diff -r 000000000000 -r b16258d2340f httpfilters/httpfilterconnhandler/Src/HttpFilterConnHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/httpfilters/httpfilterconnhandler/Src/HttpFilterConnHandler.cpp Tue Feb 02 01:09:52 2010 +0200 @@ -0,0 +1,394 @@ +/* +* Copyright (c) 2003 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: ConnHandler filter +* +*/ + + + +// INCLUDE FILES +#include +#include + +#include // defines bearer types +#include "httpfilterConnHandler.h" + +#include "HttpFilterConnHandlerObserverPS.h" +#include // Publish & Subscribe + +#include "httpfiltercommonstringsext.h" +#include "mconnectioncallback.h" + +// uncomment for logging +//#include +//_LIT(KDir, "connFilter"); +//_LIT(KFile, "filtererr.txt"); + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES +void PanicHttpFiltersConnHandler(TInt aErr = 0); + +// CONSTANTS +const TInt KConnHandlerOrderOffset = 10; + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// LocalHostCheckL +// If the host is a local host. Returns ETrue +// if the transaction request URI was for a localhost. +// ----------------------------------------------------------------------------- +// +TBool LocalHostCheckL(RHTTPTransaction& aTransaction) + { + _LIT8(KLoopbackIPv4Url, "http://127.0.0.1"); + + RHTTPRequest request = aTransaction.Request(); + TUriC8 uri = request.URI(); + + TUriParser8 parserLoopBack; + parserLoopBack.Parse(KLoopbackIPv4Url()); + TInt match = parserLoopBack.Compare(uri, EUriHost); + + if (KErrNone != match) + { + _LIT8(KLocalHostUrl, "http://localhost"); + + // try another compare - compare against the "localhost". + TUriParser8 parserLocalHost; + parserLocalHost.Parse(KLocalHostUrl()); + match = parserLocalHost.Compare(uri, EUriHost); + + if (KErrNone == match) + { + _LIT8(KLoopbackIPv4, "127.0.0.1"); + + // "localhost" resolves to "::1", manually, replace with "127.0.0.1" + CUri8* newUri = CUri8::NewLC(uri); + newUri->SetComponentL(KLoopbackIPv4(), EUriHost); + request.SetURIL(newUri->Uri()); + CleanupStack::PopAndDestroy(newUri); + } + } + + if (KErrNone == match) + { + return ETrue; + } + return EFalse; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::CHttpFilterConnHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CHttpFilterConnHandler::CHttpFilterConnHandler(RHTTPSession* aSession, MConnectionCallback* aConnCallback): + iConnCallback (aConnCallback) +{ + __ASSERT_DEBUG(aConnCallback != NULL, PanicHttpFiltersConnHandler()); + __ASSERT_DEBUG(aSession != NULL, PanicHttpFiltersConnHandler()); + iSession = aSession; +} + + +// ------------------------------------------------------------------------------------------ +// CHttpFilterConnHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ------------------------------------------------------------------------------------------ +// +void CHttpFilterConnHandler::ConstructL() +{ + // Register the filter for THTTPSessionEvent::EConnect events, + // Adds a filter to the session's filter queue. + iSession->FilterCollection().AddFilterL(*this, // The filter to add + THTTPSessionEvent::EConnect, // The event that triggers this filter + RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header + KAnyStatusCode, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code + ECache - KConnHandlerOrderOffset, // The position of the filter in the queue + iSession->StringPool().StringF(HttpFilterCommonStringsExt::EConnHandlerFilter, + HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add + + // Register the filter for submit events, + // Adds a filter to the session's filter queue. + iSession->FilterCollection().AddFilterL(*this, // The filter to add + THTTPEvent::ESubmit, // The event that triggers this filter + RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header + KAnyStatusCode, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code + ECache - KConnHandlerOrderOffset, // The position of the filter in the queue + iSession->StringPool().StringF(HttpFilterCommonStringsExt::EConnHandlerFilter, + HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add + + // Create an instance of the CHttpFilterConnHandlerObserver in order to handle "No coverage" situation + iObserver = CHttpFilterConnHandlerObserver::NewL(iConnCallback); +} + +//--------------------------------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------------------------------- +// +CHttpFilterConnHandler::~CHttpFilterConnHandler() +{ + delete iObserver; +} + +// --------------------------------------------------------------------------------------------- +// CHttpFilterConnHandler::InstallFilterL +// Two-phased constructor. This function replaces NewL. +// --------------------------------------------------------------------------------------------- +// +CHttpFilterConnHandler* CHttpFilterConnHandler::InstallFilterL(TAny* aParams) +{ + __ASSERT_DEBUG(aParams != NULL, PanicHttpFiltersConnHandler()); + TConnParams* connParams = REINTERPRET_CAST(TConnParams*, aParams); + __ASSERT_DEBUG(connParams->iSession != NULL, PanicHttpFiltersConnHandler()); + __ASSERT_DEBUG(connParams->iConnCallback != NULL, PanicHttpFiltersConnHandler()); + + CHttpFilterConnHandler* filter = new (ELeave) CHttpFilterConnHandler( connParams->iSession, connParams->iConnCallback ); + CleanupStack::PushL(filter); + filter->ConstructL(); + CleanupStack::Pop(filter); + return filter; +} + +// --------------------------------------------------------------------------------------------- +// CHttpFilterConnHandler::MHFLoad +// Called when the filter is being added to the session's filter queue. +// --------------------------------------------------------------------------------------------- +// +void CHttpFilterConnHandler::MHFLoad(RHTTPSession, THTTPFilterHandle) +{ + ++iLoadCount; +} + +// ---------------------------------------------------------------------------------------------- +// CHttpFilterConnHandler::MHFUnload +// Called when the filter is being removed from a session's filter queue. +// ---------------------------------------------------------------------------------------------- +// +void CHttpFilterConnHandler::MHFUnload(RHTTPSession /*aSession*/, THTTPFilterHandle /*aFilterHandler*/) +{ + __ASSERT_DEBUG(iLoadCount >= 0, PanicHttpFiltersConnHandler()); + if (--iLoadCount) + { + return; + } + delete this; +} + +// ------------------------------------------------------------------------------------------------ +// CHttpFilterConnHandler::MHFRunL +// Process a transaction event. +// ------------------------------------------------------------------------------------------------ +// +void CHttpFilterConnHandler::MHFRunL(RHTTPTransaction aTransaction, + const THTTPEvent& aEvent) +{ + TInt state = 0; + TInt gprsState = 0; + TInt wcdmaState = 0; + TApBearerType bearerType; + + if (aEvent.iStatus == THTTPEvent::ESubmit) + { + THTTPHdrVal isNewConn; + RHTTPConnectionInfo connInfo = iSession->ConnectionInfo(); + RStringPool strPool = aTransaction.Session().StringPool(); + TBool ret = connInfo.Property (strPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag, + HttpFilterCommonStringsExt::GetTable()), isNewConn); + + if ( LocalHostCheckL(aTransaction) && !( ret && isNewConn.Type() == THTTPHdrVal::KTIntVal ) ) + { + return; + } + + THTTPHdrVal callback; + RHTTPTransactionPropertySet propSet = aTransaction.PropertySet(); + RStringF callbackStr = strPool.StringF( HttpFilterCommonStringsExt::EConnectionCallback, + HttpFilterCommonStringsExt::GetTable() ); + + MConnectionCallback* callbackPtr = NULL; + + // this is a transaction, already forwarded to download manager + if( propSet.Property( callbackStr, callback ) ) + { + callbackPtr = REINTERPRET_CAST( MConnectionCallback*, callback.Int() ); + } + // make sure it is not null + callbackPtr = callbackPtr ? callbackPtr : iConnCallback; + + CreateConnectionL( &bearerType, callbackPtr ); + + iObserver->SetBearerTypeAndUid(bearerType); + // check if "No coverage" situation exists for the GPRS bearer + if (bearerType == EApBearerTypeGPRS) + { + // we sent request, so change Observer state to EActiveReady + iObserver->GetObserverState(state); + if (state == EIdle) + { + iObserver->GetStateL(KPSUidGprsStatusValue, gprsState); + iObserver->GetStateL(KPSUidWcdmaStatusValue, wcdmaState); + if (gprsState == EPSGprsSuspend && wcdmaState == EPSWcdmaSuspend) + { + // user sent request from "No coverage" area, so all outstanding transactions will + // be canceled in this case and user will be notified. + callbackPtr->CoverageEvent(EErrNetUnreach); + } + else + { + iObserver->SetObserverState(EActiveReady); + } + } + } + else if(bearerType == EApBearerTypeCDMA) + { + // we sent request, so change Observer state to EActiveReady + iObserver->GetObserverState(state); + if (state == EIdle) + { + iObserver->GetStateL(KPSUidWcdmaStatusValue, wcdmaState); + if (wcdmaState == EPSWcdmaSuspend && gprsState == EPSGprsSuspend) //this should not meet all the time. + { + // user sent request from "No coverage" area, so all outstanding transactions will + // be canceled in this case and user will be notified. + callbackPtr->CoverageEvent(EErrNetUnreach); + } + else + { + iObserver->SetObserverState(EActiveReady); + } + } + } + } +} + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::MHFRunError +// Process an error that occured while processing the transaction. +// ----------------------------------------------------------------------------- +// +TInt CHttpFilterConnHandler::MHFRunError(TInt , + RHTTPTransaction aTransaction, + const THTTPEvent& ) +{ + aTransaction.Cancel(); + return KErrNone; +} + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::MHFSessionRunL +// Process a session event. +// ----------------------------------------------------------------------------- +// +void CHttpFilterConnHandler::MHFSessionRunL(const THTTPSessionEvent& aEvent) +{ + TApBearerType bearerType; + + if (aEvent.iStatus == THTTPSessionEvent::EConnect) + { + CreateConnectionL(&bearerType, iConnCallback ); + } +} + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::MHFSessionRunError +// Called when MHFRunL leaves from a session event. +// ----------------------------------------------------------------------------- +// +TInt CHttpFilterConnHandler::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/) +{ + return aError; +} + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::GetObserver +// Access method +// ----------------------------------------------------------------------------- +// +void CHttpFilterConnHandler::GetObserver(CHttpFilterConnHandlerObserver*& aObserver) +{ + aObserver = iObserver; +} + + +// ----------------------------------------------------------------------------- +// CHttpFilterConnHandler::CreateConnection +// Function to handle Submit events. +// Set proxy properties (EUseProxy and EProxyAddress) in order to get connected throught +// proxy when a new HTTP session will be in effect. The Proxy data will be taken from +// the CommDb if a new connection has been used. +// ----------------------------------------------------------------------------- +// +void CHttpFilterConnHandler::CreateConnectionL( + TApBearerType* bearerType, + MConnectionCallback* aCallbackPtr ) +{ + RStringPool stringPool = iSession->StringPool(); + RHTTPConnectionInfo connInfo = iSession->ConnectionInfo(); + + // pointer to RConnection typecasted as TInt + TInt connectionPtr = 0; + // handle to the socket server + TInt sockSvrHandle = 0; + // flag of a new connection + TBool newConn = ETrue; + + TInt error = aCallbackPtr->CreateConnection(&connectionPtr, &sockSvrHandle, &newConn, bearerType); + + // Possible causes to leave are: KErrCommsLineFail (NW_STAT_CONN_FAILED), KErrCancel (NW_STAT_CANCELLED) + if (error != KErrNone) + { + User::LeaveIfError( error ); + } + + // Remove the properties if they were set before, before setting them again + connInfo.RemoveProperty(stringPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable())); + connInfo.RemoveProperty(stringPool.StringF(HTTP::EHttpSocketServ, + RHTTPSession::GetTable())); + connInfo.RemoveProperty(stringPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag, + HttpFilterCommonStringsExt::GetTable())); + + + // Add the properties only if there is valid connection and socket server handler + if (connectionPtr != NULL && sockSvrHandle != 0) + { + connInfo.SetPropertyL(stringPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable()), THTTPHdrVal(connectionPtr)); + // Set socket server handle + connInfo.SetPropertyL(stringPool.StringF(HTTP::EHttpSocketServ, + RHTTPSession::GetTable()), THTTPHdrVal((TInt)sockSvrHandle)); + // Set aNewConn flag + connInfo.SetPropertyL(stringPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag, + HttpFilterCommonStringsExt::GetTable()), THTTPHdrVal((TBool)newConn)); + } +} + +// End of File +