--- /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 <http.h>
+#include <es_sock.h>
+
+#include <ApEngineConsts.h> // defines bearer types
+#include "httpfilterConnHandler.h"
+
+#include "HttpFilterConnHandlerObserverPS.h"
+#include <PSVariables.h> // Publish & Subscribe
+
+#include "httpfiltercommonstringsext.h"
+#include "mconnectioncallback.h"
+
+// uncomment for logging
+//#include <flogger.h>
+//_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
+