httpfilters/httpfilterconnhandler/Src/HttpFilterConnHandler.cpp
changeset 0 b16258d2340f
child 8 fa2fd8b2d6cc
--- /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
+