--- a/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.cpp Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -1348,10 +1348,10 @@
}
}
-void CHttpConnectionManager::InsertPipelineFailedHost(const TDesC8& aHost)
- {
- iPipelineFallback.InsertPipelineFailedHost(aHost);
- }
+void CHttpConnectionManager::AppendPipelineFailedHost(const TDesC8& aHost)
+ {
+ iPipelineFallback.AppendPipelineFailedHost(aHost);
+ }
CHttpHostElement* CHttpHostElement::New(const TDesC8& aHost)
@@ -1441,6 +1441,26 @@
}
}
+
+ void CHttpPipelineFallback::AppendPipelineFailedHost(const TDesC8& aHost)
+ {
+ // Already failed. no need to check further.
+ if(NeedPipelineFallback(aHost))
+ {
+ return;
+ }
+
+ // Failure doesn't matter here.
+ HBufC8* host = aHost.Alloc();
+ if(host == NULL)
+ {
+ return;
+ }
+
+ iPipelineFailedHosts.Append(host); // no error checking as failure does not matter
+ // we will keep going.
+ }
+
--- a/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.h Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.h Fri Feb 19 23:50:57 2010 +0200
@@ -70,7 +70,19 @@
~CHttpPipelineFallback();
TBool NeedPipelineFallback(const TDesC8& aHost);
- void InsertPipelineFailedHost(const TDesC8& aHost);
+
+/**
+ If the pipeline has failed atleast 2 times due to network problems
+ the host is inserted into the failed host array. The function checks
+ for the no. of failures for the given host. Only on time failed hosts
+ are pushed into the probable pipeline failed host array
+ */
+ void InsertPipelineFailedHost(const TDesC8& aHost);
+
+/**
+ Add to the pipeline failed host array if not already added.
+ */
+ void AppendPipelineFailedHost(const TDesC8& aHost);
private:
CHttpPipelineFallback();
@@ -115,7 +127,8 @@
void MakeConnectionNonPersistent();
void CheckRequestComplete(MHttpRequest& aRequest);
void DisablePipelining();
- void InsertPipelineFailedHost(const TDesC8& aHost);
+ void AppendPipelineFailedHost(const TDesC8& aHost);
+
private: // methods from MHttpRequestObserver
--- a/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpresponseparser.cpp Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerpluginsandutils/httpprotocolplugins/httpclient/chttpresponseparser.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -226,7 +226,8 @@
iCancellingResponse = ETrue;
RHTTPTransaction trans = iProtTrans->Transaction();
RHTTPResponse response = trans.Response();
-
+ if(iBodyParts.Count() > 0)
+ iBodyParts.Remove(0);
iMessageParser.Flush ();
iMessageParser.Reset();
iCancellingResponse = EFalse;
@@ -484,7 +485,7 @@
if( headReq.GetField(hostStr, 0, hostVal) == KErrNotFound )
{
- // No Host header - do not know which host to connect to.
+ // No Host header
User::Leave(KErrHttpGeneralHeaderMissingHost);
}
@@ -495,7 +496,7 @@
#if defined (_DEBUG) && defined (_LOGGING)
__FLOG_0(_T8("Pipelining is disabled for WebLogic Server- \n"));
#endif
- manager->InsertPipelineFailedHost(hostVal.StrF().DesC());
+ manager->AppendPipelineFailedHost(hostVal.StrF().DesC());
}
}
@@ -659,7 +660,8 @@
if( !ConsumingResponse() )
{
- iResponseObserver.ResponseComplete(aExcessData);
+ if( iBodyParts.Count() == 0 )
+ iResponseObserver.ResponseComplete(aExcessData);
if ( iCancellingResponse )
{
--- a/applayerprotocols/httptransportfw/Test/Group/t_httppipeliningtest.mmp Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerprotocols/httptransportfw/Test/Group/t_httppipeliningtest.mmp Fri Feb 19 23:50:57 2010 +0200
@@ -17,7 +17,7 @@
TARGETTYPE exe
CAPABILITY TrustedUI ProtServ NetworkServices
-SYSTEMINCLUDE ../../../../applayerpluginsandutils/httptransportplugins/httptransporthandler
+SYSTEMINCLUDE ../../../../applayerpluginsandutils/httptransportplugins/httptransporthandler
#ifdef SYMBIAN_OLD_EXPORT_LOCATION
SYSTEMINCLUDE /epoc32/include /epoc32/include/ecom
#else
@@ -30,7 +30,7 @@
#endif
-USERINCLUDE ../T_HttpPipeliningTest ../t_utils ../../inc/framework
+USERINCLUDE ../T_HttpPipeliningTest ../t_utils ../../inc/framework ../testfilter
SOURCEPATH ../T_HttpPipeliningTest
SOURCE t_httppipeliningtest.cpp
@@ -81,6 +81,7 @@
SOURCE ctestcase25.cpp
SOURCE ctestcase26.cpp
SOURCE CTestCasePipelineFallback.cpp
+SOURCE CDEF143497.cpp
LIBRARY euser.lib httptestutils.lib http.lib ecom.lib inetprotutil.lib bafl.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/Group/testfilter.mmp Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,56 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+TARGET testfilter.dll
+TARGETTYPE PLUGIN
+
+CAPABILITY ALL -TCB
+
+// ECom Recogniction UID followed by Unique 3rd UID
+UID 0x10009D8D 0x2002CE94
+VENDORID 0x70000001
+
+SOURCEPATH ../testfilter
+SOURCE testhttpfiltermain.cpp testhttpfilter.cpp CTimer.cpp
+USERINCLUDE ../testfilter
+
+
+#ifdef SYMBIAN_OLD_EXPORT_LOCATION
+SYSTEMINCLUDE /epoc32/include /epoc32/include/ecom
+#else
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+SYSTEMINCLUDE /epoc32/include/ecom
+SYSTEMINCLUDE /epoc32/include/platform/ecom
+SYSTEMINCLUDE /epoc32/include/platform
+SYSTEMINCLUDE /epoc32/include/platform/mw
+SYSTEMINCLUDE /epoc32/include/mw
+#endif
+
+SOURCEPATH ../testfilter
+START RESOURCE 20029F09.rss
+TARGET testfilter.rsc
+END
+
+LIBRARY euser.lib
+LIBRARY ecom.lib
+LIBRARY http.lib
+LIBRARY bafl.lib
+LIBRARY hash.lib
+LIBRARY inetprotutil.lib
+LIBRARY imut.lib
+DEBUGLIBRARY flogger.lib charconv.lib
+
+SMPSAFE
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CDEF143497.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,123 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "CDEF143497.h"
+#include "httptestutils.h"
+#include "testhttpfilter.h"
+
+const TInt KTransactionCount = 1;
+const TInt KConnectionCount = 1;
+_LIT8(KTxtRawRequest1, "GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nUser-Agent: 3gpp-gba\r\n\r\n");
+_LIT8(KTxtRawResponse1, "HTTP/1.1 401 Authorization Required\r\nWWW-Authenticate: Basic realm=\"Secure Area\"\r\nContent-Length: 6\r\n\r\nhello!");
+_LIT8(KTxtRawRequest2,"GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nAuthorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\r\nUser-Agent: 3gpp-gba\r\n\r\n");
+_LIT8(KTxtRawResponse2, "HTTP/1.0 200 Ok\r\nContent-Length: 6\r\n\r\nhello!");
+_LIT8(KNullResponse, " ");
+
+CDEF143497 * CDEF143497 ::NewL(CHTTPTestUtils& aTestUtils)
+ {
+ CDEF143497 * self = new (ELeave) CDEF143497 (aTestUtils);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CDEF143497 ::CDEF143497 (CHTTPTestUtils& aTestUtils)
+: CPipeliningTestCase(), iTestUtils(aTestUtils)
+ {
+ }
+
+void CDEF143497 ::ConstructL()
+ {
+ }
+
+CDEF143497 ::~CDEF143497 ()
+ {
+ }
+
+const TDesC& CDEF143497 ::TestCaseName() const
+ {
+ _LIT(KTxtTitle, "Defect Fix CDEF143497");
+ return KTxtTitle();
+ }
+
+TInt CDEF143497 ::TotalTransactionCount() const
+ {
+ return KTransactionCount;
+ }
+
+TInt CDEF143497 ::ConnectionCount() const
+ {
+ return KConnectionCount;
+ }
+
+
+RHTTPTransaction CDEF143497 ::GetTransactionL(TInt aIndex, RHTTPSession aSession, MHTTPTransactionCallback& aClient)
+ {
+ __ASSERT_ALWAYS(aIndex<KTransactionCount, User::Invariant());
+ CTestFilterInterface::InstallFilterL(aSession);
+ RStringF method = aSession.StringPool().StringF(HTTP::EGET,RHTTPSession::GetTable());
+ _LIT8(KTxtUri, "http://127.0.0.1");
+ TUriParser8 uri;
+ uri.Parse(KTxtUri());
+ return aSession.OpenTransactionL(uri, aClient, method);
+ }
+
+const TDesC8& CDEF143497 ::GetRawRequest(TInt /*aConnectionIndex*/, TInt /*aTransIndex*/)
+ {
+ static TInt RequestCounter =0;
+ if(RequestCounter==0)
+ {
+ RequestCounter++;
+ return KTxtRawRequest1();
+ }
+ if(RequestCounter==1)
+ {
+ return KTxtRawRequest2();
+ }
+ else
+ return KNullResponse();
+ }
+
+const TDesC8& CDEF143497 ::GetRawResponse(TInt /*aConnectionIndex*/, TInt /*aTransIndex*/)
+ {
+ static TInt ResponseCounter =0;
+ if(ResponseCounter==0)
+ {
+ ResponseCounter++;
+ return KTxtRawResponse1();
+ }
+ if(ResponseCounter==1)
+ return KTxtRawResponse2();
+ else
+ return KNullResponse();
+
+ }
+
+ TInt CDEF143497::ExpectedError(RHTTPTransaction /*aTrans*/)
+ {
+ return KErrNone;
+ }
+
+TBool CDEF143497::GetCredentialsL(const TUriC8& /*aURI*/, RString aRealm, RStringF /*aAuthenticationType*/, RString& aUsername, RString& aPassword)
+ {
+ _LIT8(KUsername, "Aladdin");
+ _LIT8(KPassword, "open sesame");
+ RStringPool p = aRealm.Pool();
+ aUsername = p.OpenStringL(KUsername);
+ aPassword = p.OpenStringL(KPassword);
+ return ETrue;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CDEF143497.h Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,58 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef __CDEF143497_H__
+#define __CDEF143497_H__
+
+#include <e32base.h>
+#include <http.h>
+#include <http/mhttpauthenticationcallback.h>
+
+
+#include "CPipeliningTestCase.h"
+
+class CHTTPTestUtils;
+
+//Test case for defect fix DEF143497
+class CDEF143497 : public CPipeliningTestCase, MHTTPAuthenticationCallback
+ {
+public:
+ static CDEF143497 * NewL(CHTTPTestUtils& aTestUtils);
+ ~CDEF143497 ();
+public :
+ virtual TBool GetCredentialsL(const TUriC8& aURI, RString aRealm,
+ RStringF aAuthenticationType,
+ RString& aUsername,
+ RString& aPassword);
+
+
+private:
+ CDEF143497 (CHTTPTestUtils& aTestUtils);
+ void ConstructL();
+
+ // From MPipeliningTestCase
+ const TDesC& TestCaseName() const;
+ TInt TotalTransactionCount() const;
+ RHTTPTransaction GetTransactionL(TInt aIndex, RHTTPSession aSession, MHTTPTransactionCallback& aClient);
+ const TDesC8& GetRawRequest(TInt aConnectionIndex, TInt aTransIndex);
+ const TDesC8& GetRawResponse(TInt aConnectionIndex, TInt aTransIndex);
+ TInt ConnectionCount() const;
+ virtual TInt ExpectedError(RHTTPTransaction aTrans);
+
+private:
+ CHTTPTestUtils& iTestUtils;
+ };
+
+#endif // __CDEF143497_H__
--- a/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CTestServerStreamManager.cpp Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CTestServerStreamManager.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -183,6 +183,41 @@
{
TBool processingRequest = ETrue;
TInt currentBatch = 0;
+ _LIT(KDefectTitle, "Defect Fix CDEF143497");
+ while((iTestCase->TestCaseName().Match(KDefectTitle) == 0) && (processingRequest && (iCurrentTrans <= iTransCount)) && (currentBatch<KResponseBatchSize))
+ {
+ // Do we have enough data to respond to the current transaction?
+ TPtrC8 rawRequest = iTestCase->GetRawRequest(iConnectionIndex, iCurrentTrans);
+ TInt requestLength = rawRequest.Length();
+ TPtrC8 dataWindow = iDataStore->Mid(iDataPos);
+ // Prepare the response data to send
+ iDataPos += requestLength;
+ processingRequest = ETrue;
+ TPtrC8 rawResponse = iTestCase->GetRawResponse(iConnectionIndex, iCurrentTrans);
+ if(iDataToSend==NULL)
+ iDataToSend = rawResponse.AllocL();
+ else
+ {
+ TInt responseLength = rawResponse.Length();
+ iDataToSend = iDataToSend->ReAllocL( (iDataToSend->Length()) + responseLength );
+ TPtr8 buffer = iDataToSend->Des();
+ buffer.Append(rawResponse);
+ }
+ // Check for a Connection: Close in the request
+ iCloseConnection = IsConnectionCloseInData(rawRequest, rawResponse);
+ if(iCloseConnection)
+ processingRequest = EFalse;
+ ++iCurrentTrans;
+ ++currentBatch;
+ if( processingRequest && currentBatch==KResponseBatchSize)
+ iMoreResponseBatches = ETrue;
+ else
+ iMoreResponseBatches = EFalse;
+ if(iDataToSend!=NULL)
+ return ETrue;
+
+ return EFalse;
+ }
while( (processingRequest && (iCurrentTrans < iTransCount)) && (currentBatch<KResponseBatchSize) )
{
// Do we have enough data to respond to the current transaction?
--- a/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/cpipeliningtestengine.cpp Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/cpipeliningtestengine.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -59,6 +59,7 @@
#include "ctestcase25.h"
#include "ctestcase26.h"
#include "ctestcasepipelinefallback.h"
+#include "CDEF143497.h"
_LIT(KTestHttpPipeliningTestTitle, "HTTP Pipelining Unit Test Harness");
@@ -340,11 +341,16 @@
CleanupStack::PushL(testCase26);
RunTestL(*testCase26);
CleanupStack::PopAndDestroy(testCase26);
-
+
CTestCasePipelineFallback* pipelineFallback = CTestCasePipelineFallback::NewL(*iTestUtils);
CleanupStack::PushL(pipelineFallback);
RunTestL(*pipelineFallback);
CleanupStack::PopAndDestroy(pipelineFallback);
+
+ CDEF143497* def143497 = CDEF143497::NewL(*iTestUtils);
+ CleanupStack::PushL(def143497);
+ RunTestL(*def143497);
+ CleanupStack::PopAndDestroy(def143497);
DoPipeliningConfigTestsL();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/20029F09.rss Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,56 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "ecom/registryinfov2.rh"
+
+RESOURCE REGISTRY_INFO theInfo
+ {
+ // resource format version for ROM-only filter
+ resource_format_version = RESOURCE_FORMAT_VERSION_2;
+
+ dll_uid = 0x2002CE94;
+ interfaces=
+ {
+ INTERFACE_INFO
+ {
+ interface_uid = 0x101F446D;
+ implementations =
+ {
+ IMPLEMENTATION_INFO
+ {
+ implementation_uid = 0x2002CE96;
+ version_no = 1;
+ display_name = "testfilter";
+
+ // For HTTP-TF the default_data must be defined as follows
+ // 1.Protocol identifier
+ // HTTP-TF uses first part (separated with /-character) to identify
+ // what protocol this filter will support. It could also be WSP but
+ // then HTTP-TF does not load it with any sessions that based on HTTP.
+ // 2.Separator
+ // /-separator must be always there
+ // 3.Filter category
+ // + = mandatory (HTTP-TF will panic if installation of this filter fails)
+ // - = Explicit (Does not install filter)
+ // = Implicit (Installs filter but traps possible errors and continues)
+
+ default_data = "HTTP/-AUTHENTICATION||WSP/-AUTHENTICATION";
+ opaque_data = "";
+ }
+ };
+ }
+ };
+ }
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/CTimer.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,85 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+#include "Timer.h"
+
+
+CTimerOut* CTimerOut::NewL(MTimerObserver& aObserver)
+{
+
+ CTimerOut* iSelf = new (ELeave) CTimerOut(aObserver);
+ CleanupStack::PushL(iSelf);
+ iSelf->ConstructL();
+ CleanupStack::Pop();
+
+ return iSelf;
+}
+
+
+CTimerOut::CTimerOut(MTimerObserver& aObserver) : CActive(EPriorityStandard), iObserver(aObserver)
+{
+
+}
+
+
+void CTimerOut::ConstructL()
+{
+ User::LeaveIfError(iTimer.CreateLocal());
+ CActiveScheduler::Add(this);
+
+}
+
+
+CTimerOut::~CTimerOut()
+{
+ Deque();
+ iTimer.Close();
+
+}
+
+
+void CTimerOut::Start(TTimeIntervalMicroSeconds32 aInterval)
+{
+
+ iTimer.After(iStatus,aInterval);
+ SetActive();
+
+}
+
+
+void CTimerOut::Stop()
+{
+
+ Cancel();
+
+}
+
+
+void CTimerOut::DoCancel()
+{
+
+ iTimer.Cancel();
+
+}
+
+
+void CTimerOut::RunL()
+{
+ if(iStatus == KErrNone)
+ iObserver.HandleTimerEventL(ETimerExpired);
+ else
+ iObserver.HandleTimerEventL(ETimerCancled);
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/Timer.h Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,57 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32base.h>
+
+
+#ifndef CTIMER_H
+#define CTIMER_H
+
+
+enum TTimerEventType
+ {
+ ETimerExpired,
+ ETimerCancled
+ };
+
+class MTimerObserver
+ {
+
+ public :
+ virtual TBool HandleTimerEventL(TTimerEventType aEventType)=0;
+
+ };
+
+
+class CTimerOut : public CActive
+ {
+ public:
+ static CTimerOut* NewL(MTimerObserver& aObserver);
+ ~CTimerOut();
+ void Start(TTimeIntervalMicroSeconds32 aInterval);
+ void Stop();
+
+ protected:
+ CTimerOut(MTimerObserver& aObserver);
+ void ConstructL();
+ void DoCancel();
+ void RunL();
+ private:
+ RTimer iTimer;
+ MTimerObserver& iObserver;
+
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/testhttpfilter.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,401 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <http/rhttptransaction.h>
+#include <http/rhttpheaders.h>
+#include <http/rhttpresponse.h>
+#include <httperr.h>
+#include <httpstringconstants.h>
+#include <imcvcodc.h> //for base64 en/decoding
+#include <bautils.h>
+#include <e32math.h>
+#include <hash.h>
+#include <e32const.h>
+#include <tconvbase64.h>
+#include "testhttpfilter.h"
+_LIT8( KTESTHTTPFilterName, "TestHttp");
+_LIT8( KAuthenticationInfoStr, "Authentication-Info" );
+_LIT8( KUserAgentProductToken,"3gpp-gba");
+_LIT8( KColon, ":" );
+const TInt KB64KeySize = 64;
+_LIT(KTestHttpFilter, "TEST HTTP FILTER ");
+
+void PanicTestHttpFilters(TInt aErr = 0)
+{
+ User::Panic(KTestHttpFilter, aErr);
+}
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CTestFilter::CTestFilter
+// Constructor
+// -----------------------------------------------------------------------------
+//
+CTestFilter::CTestFilter()
+ : iBootstrapCount(0),iHaveCredentials(EFalse)
+{
+
+}
+
+// -----------------------------------------------------------------------------
+// CTestFilter::InstallFilterL
+// Initialize the filter and register it to sesssion's filter collection
+// -----------------------------------------------------------------------------
+//
+CTestFilterInterface* CTestFilter::InstallFilterL(TAny* aParams)
+{
+ __ASSERT_DEBUG(aParams != NULL, PanicTestHttpFilters());
+ RHTTPSession* session = REINTERPRET_CAST(RHTTPSession*, aParams);
+ CTestFilter* filter = new (ELeave) CTestFilter();
+ CleanupStack::PushL(filter);
+ filter->ConstructL(*session);
+ CleanupStack::Pop(filter);
+ return filter;
+}
+
+// -----------------------------------------------------------------------------
+// CTestFilter::ConstructL
+// Memory and resource allocation, leaves
+// -----------------------------------------------------------------------------
+//
+void CTestFilter::ConstructL(RHTTPSession aSession)
+{
+ iStringPool = aSession.StringPool();
+ // register the filter
+ RStringF filterName = iStringPool.OpenFStringL( KTESTHTTPFilterName );
+ CleanupClosePushL( filterName );
+ iStringPool = aSession.StringPool();
+
+ iUsernameStr = iStringPool.StringF( HTTP::EUsername, RHTTPSession::GetTable() );
+ iPasswordStr = iStringPool.StringF( HTTP::EPassword, RHTTPSession::GetTable() );
+ iUserAgent = iStringPool.OpenFStringL( KUserAgentProductToken );
+ iAuthInfo = iStringPool.OpenFStringL( KAuthenticationInfoStr );
+
+ //Regsiter for THTTPEvent::ESubmit http event
+ aSession.FilterCollection().AddFilterL( *this,
+ THTTPEvent::ESubmit,
+ RStringF(),
+ KAnyStatusCode,
+ EStatusCodeHandler,
+ filterName);
+
+ //Regsiter for THTTPEvent::EGotResponseHeaders http event with "Authentication-Info" header
+ //and HTTPStatus::EOk http status code,just to know if the credentials established are valid.
+ aSession.FilterCollection().AddFilterL( *this,
+ THTTPEvent::EGotResponseHeaders,
+ iAuthInfo,
+ HTTPStatus::EOk,
+ EStatusCodeHandler,
+ filterName );
+
+ //Regsiter for THTTPEvent::EGotResponseHeaders http event with "WWW-Authenticate" header
+ //and HTTPStatus::EUnauthorized http status code
+ //The priority for this is set to MHTTPFilter::EStatusCodeHandler - 1,
+ //so the filter intercepts the transaction before the default
+ //http digest authentication filter(which has priority MHTTPFilter::EStatusCodeHandler).
+
+ aSession.FilterCollection().AddFilterL( *this,
+ THTTPEvent::EGotResponseHeaders, // Any transaction event
+ iStringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()),
+ HTTPStatus::EUnauthorized,
+ MHTTPFilter::EStatusCodeHandler - 1, // Priority of filter
+ filterName ); // Name of filter
+
+ CleanupStack::PopAndDestroy( &filterName );
+
+ iTimeOut = CTimerOut::NewL(*this);
+
+ }
+
+
+//------------------------------------------------------------------------
+// CTestFilter::~CTestFilter
+// Destructor
+//------------------------------------------------------------------------
+//
+CTestFilter::~CTestFilter()
+{
+ CleanupAll();
+ delete iTimeOut;
+}
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFLoad
+//------------------------------------------------------------------------
+//
+void CTestFilter::MHFLoad(RHTTPSession, THTTPFilterHandle)
+{
+ ++iLoadCount;
+}
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFUnload
+//------------------------------------------------------------------------
+//
+void CTestFilter::MHFUnload(RHTTPSession , THTTPFilterHandle)
+{
+ __ASSERT_DEBUG( iLoadCount >= 0, PanicTestHttpFilters() );
+
+ if (--iLoadCount)
+ {
+ return;
+ }
+ delete this;
+}
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFRunL
+// See MHTTPFilterBase::MHFRunL
+//------------------------------------------------------------------------
+//
+void CTestFilter::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
+{
+ if (aEvent.iUID != KHTTPUid)
+ return;
+
+ switch(aEvent.iStatus)
+ {
+ case THTTPEvent::ESubmit:
+ {
+ DoSubmitL(aTransaction);
+ }
+ break;
+
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ // Get HTTP status code from header (e.g. 200)
+ RHTTPResponse resp = aTransaction.Response();
+ CheckHeadersL( aTransaction );
+ }
+ break;
+ default:
+ {
+ }
+ break;
+ }
+
+}
+
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFRunError
+// See MHTTPFilterBase::MHFRunError
+//------------------------------------------------------------------------
+//
+TInt CTestFilter::MHFRunError(TInt /*aError*/, RHTTPTransaction aTransaction, const THTTPEvent& )
+{
+ TInt error = 0;
+ // map aError to global error message
+ // pass the errorcode forward
+ THTTPEvent httpEvent(error);
+ TRAP_IGNORE(aTransaction.SendEventL(httpEvent, THTTPEvent::EIncoming, THTTPFilterHandle::ECurrentFilter ));
+ return KErrNone;
+}
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFSessionRunL
+// See MHTTPFilterBase::MHFSessionRunL
+//------------------------------------------------------------------------
+//
+void CTestFilter::MHFSessionRunL(const THTTPSessionEvent& )
+{
+ // do nothing
+}
+
+//------------------------------------------------------------------------
+// CTestFilter::MHFSessionRunL
+// See MHTTPFilterBase::MHFSessionRunL
+//------------------------------------------------------------------------
+//
+TInt CTestFilter::MHFSessionRunError(TInt aError, const THTTPSessionEvent& )
+{
+ // session problem
+ return aError;
+}
+//------------------------------------------------------------------------
+// CTestFilter::CheckHeadersL
+// Check HTTP headers and extract MIME type
+//------------------------------------------------------------------------
+//
+void CTestFilter::CheckHeadersL( RHTTPTransaction& aTrans )
+{
+ // read the header data and check the MIME type here
+ // check the status and body
+ RHTTPResponse response = aTrans.Response();
+ TInt status = response.StatusCode();
+ THTTPHdrVal fieldVal;
+ // check if status == 401 and realm is 3GPP then we need to bootstrap, if we are already bootstrappign this is the second call
+ if( status == HTTPStatus::EUnauthorized )
+ {
+
+ TInt headerPart=0;
+ THTTPHdrVal headerVal;
+ TInt cred = KErrNotFound;
+ RStringF wwwAuthHeader = iStringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
+ RHTTPHeaders headers(aTrans.Response().GetHeaderCollection());
+
+ RString realm;
+ THTTPHdrVal hdrVal;
+ if (!headers.GetParam(wwwAuthHeader, iStringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()),
+ hdrVal, headerPart))
+ {
+ realm = hdrVal;
+ const TDesC8& val = realm.DesC();
+ if (headerPart == KErrNotFound)
+ return;
+ THTTPHdrVal authTypeParam;
+
+
+ RHTTPTransactionPropertySet propSet = aTrans.PropertySet();
+ // if we are already bootstrapping results will be retrieved when request is resubmitted
+ iBootstrapPending = ETrue;
+
+
+ TTimeIntervalMicroSeconds32 aInterval(20000000);
+
+ iTimeOut->Start(aInterval); //Start the http post request timer, aInterval - timeout in micro-seconds
+
+ if(!iBootstrapWait.IsStarted())
+ {
+ iBootstrapWait.Start();
+ }
+
+ if( iHaveCredentials )
+ {
+ RHTTPTransactionPropertySet propSet = aTrans.PropertySet();
+
+ //user name/pass word for accessing http://replab.nrln.net/digest/
+ //username: dummy, password: dummy
+ TBuf8<KB64KeySize> keyBase64(_L8("Aladdin"));
+ TBuf8<KB64KeySize> keyBase64Username(_L8("open sesame"));;
+ RString username = iStringPool.OpenStringL( keyBase64 );
+ CleanupClosePushL<RString>( username );
+ RString password = iStringPool.OpenStringL( keyBase64Username );
+ CleanupClosePushL<RString>( password );
+ propSet.SetPropertyL( iUsernameStr, username );
+ propSet.SetPropertyL( iPasswordStr, password );
+ CleanupStack::PopAndDestroy(&password);
+ CleanupStack::PopAndDestroy(&username);
+ //Cancel the transaction
+ aTrans.Cancel();
+ // Re-submit the http request with much needed credentials
+ aTrans.SubmitL();
+ }
+ else
+ {
+ //Since bootstrapping failed,Do not have to resubmit the http request ?
+ return;
+ }
+
+ }
+ }
+}
+
+void CTestFilter::DoSubmitL( RHTTPTransaction aTransaction )
+{
+ RHTTPHeaders hdr = aTransaction.Request().GetHeaderCollection();
+
+ RStringF fieldname = aTransaction.Session().StringPool().StringF(HTTP::EUserAgent,RHTTPSession::GetTable());
+
+ TBool found = EFalse;
+ TPtrC8 rawFieldData;
+
+ hdr.GetRawField(fieldname, rawFieldData);
+
+ found = rawFieldData.Find(iUserAgent.DesC()) != KErrNotFound;
+
+ if(!found)
+ hdr.SetFieldL(fieldname, iUserAgent);
+
+ TInt cred = KErrNotFound;
+
+ if( iHaveCredentials )
+ {
+ TBuf8<KB64KeySize> keyBase64(_L8("Aladdin"));
+ TBuf8<KB64KeySize> keyBase64Username(_L8("open sesame"));;
+ RString username = iStringPool.OpenStringL( keyBase64 );
+ CleanupClosePushL<RString>( username );
+ RString password = iStringPool.OpenStringL( keyBase64Username );
+ CleanupClosePushL<RString>( password );
+ EncodeBasicAuthL(username, password, aTransaction);
+ CleanupStack::PopAndDestroy(&password);
+ CleanupStack::PopAndDestroy(&username);
+
+ }
+}
+
+//-----------------------------------------------------------------------------
+// CTestFilter::CleanupAll
+// Cleanup all the transactions, in case a session error happens or a session
+// is closed.
+//-----------------------------------------------------------------------------
+//
+void CTestFilter::CleanupAll()
+{
+
+ iUserAgent.Close();
+ iAuthInfo.Close();
+}
+
+TBool CTestFilter::HandleTimerEventL(TTimerEventType /*aEventType*/)
+{
+ iBootstrapPending = EFalse;
+
+ iHaveCredentials = ETrue;
+
+ if (iBootstrapWait.IsStarted())
+ iBootstrapWait.AsyncStop();
+
+ return ETrue;
+}
+
+
+void CTestFilter::EncodeBasicAuthL(RString& aUsername,
+ RString& aPW,
+ RHTTPTransaction& aTransaction)
+ {
+ // Standard, plain-text HTTP - Base 64 the name and password
+ TBase64 codec;
+ HBufC8* nameAndPW = HBufC8::NewMaxLC(aUsername.DesC().Length() + aPW.DesC().Length() + 1);
+ _LIT8(KBasicAuthFormatString, "%S:%S");
+ nameAndPW->Des().Format(KBasicAuthFormatString, &aUsername.DesC(), &aPW.DesC());
+
+ // Conservatively allocate a buffer twice as big as the unencoded
+ // buffer for the encoded string.
+ HBufC8* encoded = HBufC8::NewMaxLC(nameAndPW->Des().Length() * 2);
+ TPtr8 encodedPtr(encoded->Des());
+ codec.Encode(*nameAndPW, encodedPtr);
+
+ RString encodedString = iStringPool.OpenStringL(*encoded);
+ CleanupStack::PopAndDestroy(2, nameAndPW);
+
+ CleanupClosePushL(encodedString);
+
+ RHTTPHeaders requestHeaders(aTransaction.Request().GetHeaderCollection());
+
+ requestHeaders.RemoveField(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()));
+ requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()),
+ THTTPHdrVal(iStringPool.StringF(HTTP::EBasic,RHTTPSession::GetTable())));
+
+ requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()),
+ THTTPHdrVal(encodedString));
+
+ aTransaction.PropertySet().SetPropertyL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()),
+ THTTPHdrVal(encodedString));
+
+ CleanupStack::PopAndDestroy(&encodedString);
+
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/testhttpfilter.h Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,173 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#ifndef __TESTFILTER_H_
+#define __TESTFILTER_H_
+#include "Timer.h"
+#include <http/mhttpfilter.h>
+#include <http/rhttpsession.h>
+#include <http/cecomfilter.h>
+#include <http/framework/httplogger.h>
+#include <ecom/ecom.h>
+
+class RHTTPResponse;
+class RHTTPTransaction;
+class CMD5;
+
+const TInt KMaxTypeLength = 255;
+const TInt KBsfAddressSize = 128;
+
+class CShutdown : public CTimer
+ {
+ enum { EShutdownDelay = 0x4000000 }; // approx 2s
+ public:
+ CShutdown();
+ void ConstructL();
+ void Start();
+ void Stop();
+ private:
+ void RunL();
+ };
+
+class CTestFilterInterface : public CBase
+/**
+The ECOM interface definition for an HTTP authentication filter. Implementations
+of an authentication filter must inherit this class.
+@publishedAll
+@released
+*/
+ {
+public: // Methods
+ /**
+ @fn InstallFilterL(RHTTPSession& aSession, MHTTPAuthenticationCallback* aCallback)
+ Intended Usage: This method is used to install the authentication filter to the filter queue.
+ The returned pointer is not owned as the filters must be self-destroying when
+ they are unloaded.
+ @param aSession A handle to the transport session
+ @param aCallback A pointer to the object implementing the callback function
+ @return Pointer to the newly installed plugin
+ @pre The session had already been setup
+ @post The filter(s) have been installed
+ */
+ inline static void InstallFilterL(RHTTPSession& aSession);
+
+ /**
+ @fn ~CTestFilterInterface()
+ Intended Usage: Virtual destructor
+ @pre The object identified by the destructor key in iEcomDtorID exists
+ @post The object is destroyed
+ */
+ inline ~CTestFilterInterface();
+
+private:
+ // Attributes
+ /// The ECom destructor key identifier
+ TUid iEcomDtorID;
+ };
+
+//----------------------------------------------------------------------------------------
+
+inline void CTestFilterInterface::InstallFilterL(RHTTPSession& aSession)
+ {
+ const TUid KUidAuthenticationFilter = {0x2002CE96};
+
+ REComSession::CreateImplementationL(KUidAuthenticationFilter, _FOFF(CTestFilterInterface,iEcomDtorID), &aSession);
+ }
+
+inline CTestFilterInterface::~CTestFilterInterface()
+ {
+ REComSession::DestroyedImplementation(iEcomDtorID);
+ }
+
+
+class CTestFilter : public CTestFilterInterface, public MHTTPFilter, public MTimerObserver
+{
+ enum
+ {
+ EAlgUnknown,
+ EAlgMd5,
+ EAlgMd5Sess
+ };
+
+public:
+
+ static CTestFilterInterface* InstallFilterL(TAny* aSession);
+
+ virtual ~CTestFilter();
+
+public: // Methods from MHTTPFilterBase
+
+ /// @see MHTTPFilterBase::MHFRunL
+ virtual void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
+
+ /// @see MHTTPFilterBase::MHFSessionRunL
+ virtual void MHFSessionRunL(const THTTPSessionEvent& aEvent);
+
+ /// @see MHTTPFilterBase::MHFRunError
+ virtual TInt MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
+
+ /// @see MHTTPFilterBase::MHFSessionRunError
+ virtual TInt MHFSessionRunError(TInt aError, const THTTPSessionEvent& aEvent);
+
+public: // Methods from MHTTPFilter
+
+ /// @see MHTTPFilter::MHFUnload
+ virtual void MHFUnload(RHTTPSession aSession, THTTPFilterHandle aHandle);
+
+ /// @see MHTTPFilter::MHFLoad
+ virtual void MHFLoad(RHTTPSession aSession, THTTPFilterHandle aHandle);
+
+ private:
+
+ CTestFilter();
+
+ ///ContructL also Installs the filter.
+ void ConstructL( RHTTPSession aSession );
+
+ void CheckHeadersL( RHTTPTransaction& aTrans );
+
+ void CleanupAll();
+
+ TBool FindAuth(const TDesC8& aQop) const;
+
+ void DoSubmitL( RHTTPTransaction aTransaction );
+
+ void EncodeBasicAuthL(RString& aUsername,RString& aPW, RHTTPTransaction& aTransaction);
+
+ TBool HandleTimerEventL(TTimerEventType aEventType);
+
+ /// A count to make sure we delete at the right time.
+ TInt iLoadCount;
+ RStringPool iStringPool;
+ RStringF iUsernameStr;
+ RStringF iPasswordStr;
+ RStringF iUserAgent;
+ RStringF iAuthInfo;
+ TInt64 iSeed;
+ TInt iOffset;
+ TUint8 iFlags;
+ TBuf8<5> iProtocolIdentifier;
+ TInt iBootstrapCount;
+ TBool iBootstrapPending;
+ TBool iHaveCredentials;
+ CActiveSchedulerWait iBootstrapWait;
+ CTimerOut* iTimeOut;
+
+};
+
+#endif //__TESTFILTER_H_
+
+//EOF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/httptransportfw/Test/testfilter/testhttpfiltermain.cpp Fri Feb 19 23:50:57 2010 +0200
@@ -0,0 +1,33 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32std.h>
+#include <ecom/implementationproxy.h>
+#include "testhttpfilter.h"
+
+const TImplementationProxy KImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY(0x2002CE96,CTestFilter::InstallFilterL)
+ };
+
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+ {
+ aTableCount = sizeof(KImplementationTable) / sizeof(TImplementationProxy);
+ return KImplementationTable;
+ }
+
+
+
--- a/applayerprotocols/httptransportfw/group/bld.inf Tue Feb 02 01:09:52 2010 +0200
+++ b/applayerprotocols/httptransportfw/group/bld.inf Fri Feb 19 23:50:57 2010 +0200
@@ -262,6 +262,9 @@
../Test/Group/HTTPPipeliningTest.mmp
../Test/Group/HTTPIOPTest.mmp
+// HTTP Test Filter
+../Test/Group/testfilter.mmp
+
// Test HTTP Suite
#include "../Test/Integration/group/bld.inf"