# HG changeset patch # User Dremov Kirill (Nokia-D-MSW/Tampere) # Date 1266616257 -7200 # Node ID 5ee1d9ce5878a3e8f601d84e132158a80ade7ae9 # Parent b16258d2340fcf81508750dfc25ab52fffdae3bd Revision: 201003 Kit: 201007 diff -r b16258d2340f -r 5ee1d9ce5878 applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.cpp --- 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. + } + diff -r b16258d2340f -r 5ee1d9ce5878 applayerpluginsandutils/httpprotocolplugins/httpclient/chttpconnectionmanager.h --- 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 diff -r b16258d2340f -r 5ee1d9ce5878 applayerpluginsandutils/httpprotocolplugins/httpclient/chttpresponseparser.cpp --- 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 ) { diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/Group/t_httppipeliningtest.mmp --- 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 diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/Group/testfilter.mmp --- /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 + diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CDEF143497.cpp --- /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 +#include +#include + + +#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__ diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/T_HttpPipeliningTest/CTestServerStreamManager.cpp --- 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)) && (currentBatchGetRawRequest(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)) && (currentBatchConstructL(); + 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); + +} + diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/testfilter/Timer.h --- /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 + + +#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 diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/testfilter/testhttpfilter.cpp --- /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 +#include +#include +#include +#include +#include //for base64 en/decoding +#include +#include +#include +#include +#include +#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 keyBase64(_L8("Aladdin")); + TBuf8 keyBase64Username(_L8("open sesame"));; + RString username = iStringPool.OpenStringL( keyBase64 ); + CleanupClosePushL( username ); + RString password = iStringPool.OpenStringL( keyBase64Username ); + CleanupClosePushL( 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 keyBase64(_L8("Aladdin")); + TBuf8 keyBase64Username(_L8("open sesame"));; + RString username = iStringPool.OpenStringL( keyBase64 ); + CleanupClosePushL( username ); + RString password = iStringPool.OpenStringL( keyBase64Username ); + CleanupClosePushL( 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); + + } diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/testfilter/testhttpfilter.h --- /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 +#include +#include +#include +#include + +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 diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/Test/testfilter/testhttpfiltermain.cpp --- /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 +#include +#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; + } + + + diff -r b16258d2340f -r 5ee1d9ce5878 applayerprotocols/httptransportfw/group/bld.inf --- 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"