httpfilters/httpfilterconnhandler/Src/HttpFilterConnHandler.cpp
changeset 0 b16258d2340f
child 8 fa2fd8b2d6cc
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ConnHandler filter
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <http.h>
       
    22 #include <es_sock.h>
       
    23 
       
    24 #include <ApEngineConsts.h>  // defines bearer types
       
    25 #include "httpfilterConnHandler.h"
       
    26 
       
    27 #include "HttpFilterConnHandlerObserverPS.h"
       
    28 #include <PSVariables.h>  // Publish & Subscribe
       
    29 
       
    30 #include "httpfiltercommonstringsext.h"
       
    31 #include "mconnectioncallback.h"
       
    32 
       
    33 // uncomment for logging
       
    34 //#include <flogger.h>
       
    35 //_LIT(KDir, "connFilter");
       
    36 //_LIT(KFile, "filtererr.txt");
       
    37 
       
    38 // EXTERNAL DATA STRUCTURES
       
    39 
       
    40 // EXTERNAL FUNCTION PROTOTYPES
       
    41 void PanicHttpFiltersConnHandler(TInt aErr = 0);
       
    42 
       
    43 // CONSTANTS
       
    44 const TInt KConnHandlerOrderOffset = 10;
       
    45 
       
    46 // MACROS
       
    47 
       
    48 // LOCAL CONSTANTS AND MACROS
       
    49 
       
    50 // MODULE DATA STRUCTURES
       
    51 
       
    52 // LOCAL FUNCTION PROTOTYPES
       
    53 
       
    54 // FORWARD DECLARATIONS
       
    55 
       
    56 // ============================= LOCAL FUNCTIONS ===============================
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // LocalHostCheckL
       
    60 // If the host is a local host. Returns ETrue
       
    61 // if the transaction request URI was for a localhost.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 TBool LocalHostCheckL(RHTTPTransaction& aTransaction)
       
    65     {
       
    66     _LIT8(KLoopbackIPv4Url, "http://127.0.0.1"); 
       
    67     
       
    68     RHTTPRequest request = aTransaction.Request();
       
    69     TUriC8 uri = request.URI();
       
    70 
       
    71     TUriParser8 parserLoopBack;
       
    72     parserLoopBack.Parse(KLoopbackIPv4Url());
       
    73     TInt match = parserLoopBack.Compare(uri, EUriHost);
       
    74 
       
    75     if (KErrNone != match)
       
    76         {
       
    77         _LIT8(KLocalHostUrl, "http://localhost"); 
       
    78 
       
    79         // try another compare - compare against the "localhost".
       
    80         TUriParser8 parserLocalHost;
       
    81         parserLocalHost.Parse(KLocalHostUrl());
       
    82         match = parserLocalHost.Compare(uri, EUriHost);
       
    83 
       
    84         if (KErrNone == match) 
       
    85             {
       
    86             _LIT8(KLoopbackIPv4, "127.0.0.1"); 
       
    87 
       
    88             // "localhost" resolves to "::1", manually, replace with "127.0.0.1"
       
    89             CUri8* newUri = CUri8::NewLC(uri);
       
    90             newUri->SetComponentL(KLoopbackIPv4(), EUriHost);
       
    91             request.SetURIL(newUri->Uri());
       
    92             CleanupStack::PopAndDestroy(newUri);
       
    93             }
       
    94         }
       
    95               
       
    96     if (KErrNone == match)
       
    97         {
       
    98         return ETrue;                                                          
       
    99         }
       
   100     return EFalse;
       
   101     }
       
   102 
       
   103 // ============================ MEMBER FUNCTIONS ===============================
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // CHttpFilterConnHandler::CHttpFilterConnHandler
       
   107 // C++ default constructor can NOT contain any code, that
       
   108 // might leave.
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 CHttpFilterConnHandler::CHttpFilterConnHandler(RHTTPSession* aSession, MConnectionCallback* aConnCallback):
       
   112         iConnCallback (aConnCallback)
       
   113 {
       
   114     __ASSERT_DEBUG(aConnCallback != NULL, PanicHttpFiltersConnHandler());
       
   115     __ASSERT_DEBUG(aSession != NULL, PanicHttpFiltersConnHandler());
       
   116     iSession      = aSession;
       
   117 }
       
   118 
       
   119 
       
   120 // ------------------------------------------------------------------------------------------
       
   121 // CHttpFilterConnHandler::ConstructL
       
   122 // Symbian 2nd phase constructor can leave.
       
   123 // ------------------------------------------------------------------------------------------
       
   124 //
       
   125 void CHttpFilterConnHandler::ConstructL()
       
   126 {
       
   127     // Register the filter for THTTPSessionEvent::EConnect events,
       
   128     // Adds a filter to the session's filter queue.
       
   129     iSession->FilterCollection().AddFilterL(*this,   // The filter to add
       
   130                                             THTTPSessionEvent::EConnect,       // The event that triggers this filter
       
   131                                             RStringF(),   // The header whose presence triggers this filter, or KNullDesC to trigger on any header
       
   132                                             KAnyStatusCode,  // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
       
   133                                             ECache - KConnHandlerOrderOffset,            // The position of the filter in the queue
       
   134                                             iSession->StringPool().StringF(HttpFilterCommonStringsExt::EConnHandlerFilter,
       
   135                                                                            HttpFilterCommonStringsExt::GetTable()));    //The name of the filter to add
       
   136 
       
   137     // Register the filter for submit events,
       
   138     // Adds a filter to the session's filter queue.
       
   139     iSession->FilterCollection().AddFilterL(*this,   // The filter to add
       
   140                                             THTTPEvent::ESubmit,       // The event that triggers this filter
       
   141                                             RStringF(), // The header whose presence triggers this filter, or KNullDesC to trigger on any header
       
   142                                             KAnyStatusCode, // The status code that triggers this filter, or KAnyStatusCode to trigger on any status code
       
   143                                             ECache - KConnHandlerOrderOffset,            // The position of the filter in the queue
       
   144                                             iSession->StringPool().StringF(HttpFilterCommonStringsExt::EConnHandlerFilter,
       
   145                                                                            HttpFilterCommonStringsExt::GetTable())); //The name of the filter to add
       
   146 
       
   147 	// Create an instance of the CHttpFilterConnHandlerObserver in order to handle "No coverage" situation
       
   148     iObserver = CHttpFilterConnHandlerObserver::NewL(iConnCallback);
       
   149 }
       
   150 
       
   151 //---------------------------------------------------------------------------------------------
       
   152 // Destructor
       
   153 //----------------------------------------------------------------------------------------------
       
   154 //
       
   155 CHttpFilterConnHandler::~CHttpFilterConnHandler()
       
   156 {
       
   157     delete iObserver;
       
   158 }
       
   159 
       
   160 // ---------------------------------------------------------------------------------------------
       
   161 // CHttpFilterConnHandler::InstallFilterL
       
   162 // Two-phased constructor. This function replaces NewL.
       
   163 // ---------------------------------------------------------------------------------------------
       
   164 //
       
   165 CHttpFilterConnHandler* CHttpFilterConnHandler::InstallFilterL(TAny* aParams)
       
   166 {
       
   167     __ASSERT_DEBUG(aParams != NULL, PanicHttpFiltersConnHandler());
       
   168     TConnParams* connParams = REINTERPRET_CAST(TConnParams*, aParams);
       
   169     __ASSERT_DEBUG(connParams->iSession != NULL, PanicHttpFiltersConnHandler());
       
   170     __ASSERT_DEBUG(connParams->iConnCallback != NULL, PanicHttpFiltersConnHandler());
       
   171 
       
   172     CHttpFilterConnHandler* filter = new (ELeave) CHttpFilterConnHandler( connParams->iSession, connParams->iConnCallback );
       
   173     CleanupStack::PushL(filter);
       
   174     filter->ConstructL();
       
   175     CleanupStack::Pop(filter);
       
   176     return filter;
       
   177 }
       
   178 
       
   179 // ---------------------------------------------------------------------------------------------
       
   180 // CHttpFilterConnHandler::MHFLoad
       
   181 // Called when the filter is being added to the session's filter queue.
       
   182 // ---------------------------------------------------------------------------------------------
       
   183 //
       
   184 void CHttpFilterConnHandler::MHFLoad(RHTTPSession, THTTPFilterHandle)
       
   185 {
       
   186     ++iLoadCount;
       
   187 }
       
   188 
       
   189 // ----------------------------------------------------------------------------------------------
       
   190 // CHttpFilterConnHandler::MHFUnload
       
   191 // Called when the filter is being removed from a session's filter queue.
       
   192 // ----------------------------------------------------------------------------------------------
       
   193 //
       
   194 void CHttpFilterConnHandler::MHFUnload(RHTTPSession /*aSession*/, THTTPFilterHandle /*aFilterHandler*/)
       
   195 {
       
   196     __ASSERT_DEBUG(iLoadCount >= 0, PanicHttpFiltersConnHandler());
       
   197     if (--iLoadCount)
       
   198     {
       
   199         return;
       
   200     }
       
   201     delete this;
       
   202 }
       
   203 
       
   204 // ------------------------------------------------------------------------------------------------
       
   205 // CHttpFilterConnHandler::MHFRunL
       
   206 // Process a transaction event.
       
   207 // ------------------------------------------------------------------------------------------------
       
   208 //
       
   209 void CHttpFilterConnHandler::MHFRunL(RHTTPTransaction aTransaction,
       
   210                                      const THTTPEvent& aEvent)
       
   211 {
       
   212     TInt state = 0;
       
   213     TInt gprsState = 0;
       
   214     TInt wcdmaState = 0;
       
   215     TApBearerType bearerType;
       
   216 
       
   217     if (aEvent.iStatus == THTTPEvent::ESubmit)
       
   218     {
       
   219         THTTPHdrVal isNewConn;
       
   220         RHTTPConnectionInfo	connInfo = iSession->ConnectionInfo();
       
   221         RStringPool strPool = aTransaction.Session().StringPool();
       
   222         TBool ret = connInfo.Property (strPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag,
       
   223                                        HttpFilterCommonStringsExt::GetTable()), isNewConn);
       
   224 
       
   225         if ( LocalHostCheckL(aTransaction) && !( ret && isNewConn.Type() == THTTPHdrVal::KTIntVal ) )
       
   226             {
       
   227             return;
       
   228             }
       
   229 
       
   230         THTTPHdrVal callback;
       
   231         RHTTPTransactionPropertySet propSet = aTransaction.PropertySet();
       
   232         RStringF callbackStr = strPool.StringF( HttpFilterCommonStringsExt::EConnectionCallback, 
       
   233             HttpFilterCommonStringsExt::GetTable() );
       
   234 
       
   235         MConnectionCallback* callbackPtr = NULL;
       
   236     
       
   237         // this is a transaction, already forwarded to download manager
       
   238         if( propSet.Property( callbackStr, callback ) )
       
   239         {
       
   240             callbackPtr = REINTERPRET_CAST( MConnectionCallback*, callback.Int() );
       
   241         }        
       
   242         // make sure it is not null
       
   243         callbackPtr = callbackPtr ? callbackPtr : iConnCallback;
       
   244 
       
   245         CreateConnectionL( &bearerType, callbackPtr );
       
   246 
       
   247         iObserver->SetBearerTypeAndUid(bearerType);
       
   248         // check if "No coverage" situation exists for the GPRS bearer
       
   249         if (bearerType == EApBearerTypeGPRS)
       
   250         {
       
   251             // we sent request, so change Observer state to  EActiveReady
       
   252             iObserver->GetObserverState(state);
       
   253             if (state == EIdle)
       
   254             {
       
   255               iObserver->GetStateL(KPSUidGprsStatusValue, gprsState);
       
   256 			  iObserver->GetStateL(KPSUidWcdmaStatusValue, wcdmaState);
       
   257               if (gprsState == EPSGprsSuspend && wcdmaState == EPSWcdmaSuspend)
       
   258               {
       
   259                 // user sent request from "No coverage" area, so all outstanding transactions will 
       
   260                 // be canceled in this case and user will be notified.
       
   261                   callbackPtr->CoverageEvent(EErrNetUnreach);
       
   262               }
       
   263               else
       
   264               {
       
   265                   iObserver->SetObserverState(EActiveReady);         
       
   266               }
       
   267             }  
       
   268         }
       
   269         else if(bearerType == EApBearerTypeCDMA) 
       
   270         {
       
   271             // we sent request, so change Observer state to  EActiveReady
       
   272             iObserver->GetObserverState(state);
       
   273             if (state == EIdle)
       
   274             {
       
   275               iObserver->GetStateL(KPSUidWcdmaStatusValue, wcdmaState);
       
   276               if (wcdmaState == EPSWcdmaSuspend  && gprsState == EPSGprsSuspend) //this should not meet all the time.
       
   277               {
       
   278                 // user sent request from "No coverage" area, so all outstanding transactions will 
       
   279                 // be canceled in this case and user will be notified.  
       
   280                   callbackPtr->CoverageEvent(EErrNetUnreach);
       
   281               }
       
   282               else
       
   283               {
       
   284                   iObserver->SetObserverState(EActiveReady);
       
   285               }
       
   286             }
       
   287         }
       
   288     }
       
   289 }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CHttpFilterConnHandler::MHFRunError
       
   293 // Process an error that occured while processing the transaction.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 TInt CHttpFilterConnHandler::MHFRunError(TInt ,
       
   297         RHTTPTransaction aTransaction,
       
   298         const THTTPEvent& )
       
   299 {
       
   300     aTransaction.Cancel();
       
   301     return KErrNone;
       
   302 }
       
   303 
       
   304 // -----------------------------------------------------------------------------
       
   305 // CHttpFilterConnHandler::MHFSessionRunL
       
   306 // Process a session event.
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 void CHttpFilterConnHandler::MHFSessionRunL(const THTTPSessionEvent& aEvent)
       
   310 {
       
   311     TApBearerType bearerType;
       
   312 
       
   313     if (aEvent.iStatus == THTTPSessionEvent::EConnect)
       
   314     {
       
   315         CreateConnectionL(&bearerType, iConnCallback );
       
   316     }
       
   317 }
       
   318 
       
   319 // -----------------------------------------------------------------------------
       
   320 // CHttpFilterConnHandler::MHFSessionRunError
       
   321 // Called when MHFRunL leaves from a session event.
       
   322 // -----------------------------------------------------------------------------
       
   323 //
       
   324 TInt CHttpFilterConnHandler::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/)
       
   325 {
       
   326     return aError;
       
   327 }
       
   328 
       
   329 // -----------------------------------------------------------------------------
       
   330 // CHttpFilterConnHandler::GetObserver
       
   331 // Access method
       
   332 // -----------------------------------------------------------------------------
       
   333 //
       
   334 void CHttpFilterConnHandler::GetObserver(CHttpFilterConnHandlerObserver*& aObserver)
       
   335 {
       
   336     aObserver = iObserver;
       
   337 }
       
   338 
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // CHttpFilterConnHandler::CreateConnection
       
   342 // Function to handle Submit events.
       
   343 // Set proxy properties (EUseProxy and EProxyAddress) in order to get connected throught
       
   344 // proxy when a new HTTP session will be in effect.  The Proxy data will be taken from
       
   345 // the CommDb if a new connection has been used.
       
   346 // -----------------------------------------------------------------------------
       
   347 //
       
   348 void CHttpFilterConnHandler::CreateConnectionL(
       
   349     TApBearerType* bearerType,
       
   350     MConnectionCallback* aCallbackPtr )
       
   351 {
       
   352     RStringPool stringPool = iSession->StringPool();
       
   353     RHTTPConnectionInfo	connInfo = iSession->ConnectionInfo();
       
   354 
       
   355     // pointer to RConnection typecasted as TInt
       
   356     TInt connectionPtr = 0;
       
   357     // handle to the socket server
       
   358     TInt sockSvrHandle = 0;
       
   359     // flag of a new connection
       
   360     TBool newConn = ETrue;
       
   361 
       
   362     TInt error = aCallbackPtr->CreateConnection(&connectionPtr, &sockSvrHandle, &newConn, bearerType);
       
   363 
       
   364     // Possible causes to leave are: KErrCommsLineFail (NW_STAT_CONN_FAILED), KErrCancel (NW_STAT_CANCELLED)
       
   365     if (error != KErrNone)
       
   366     {
       
   367         User::LeaveIfError( error );
       
   368     }
       
   369 
       
   370     // Remove the properties if they were set before, before setting them again
       
   371     connInfo.RemoveProperty(stringPool.StringF(HTTP::EHttpSocketConnection,
       
   372                             RHTTPSession::GetTable()));
       
   373     connInfo.RemoveProperty(stringPool.StringF(HTTP::EHttpSocketServ,
       
   374                             RHTTPSession::GetTable()));
       
   375     connInfo.RemoveProperty(stringPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag,
       
   376                             HttpFilterCommonStringsExt::GetTable()));
       
   377 
       
   378 
       
   379     // Add the properties only if there is valid connection and socket server handler
       
   380     if (connectionPtr != NULL && sockSvrHandle != 0)
       
   381     {
       
   382         connInfo.SetPropertyL(stringPool.StringF(HTTP::EHttpSocketConnection,
       
   383                               RHTTPSession::GetTable()), THTTPHdrVal(connectionPtr));
       
   384         // Set socket server handle
       
   385         connInfo.SetPropertyL(stringPool.StringF(HTTP::EHttpSocketServ,
       
   386                               RHTTPSession::GetTable()), THTTPHdrVal((TInt)sockSvrHandle));
       
   387         // Set aNewConn flag
       
   388         connInfo.SetPropertyL(stringPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag,
       
   389                               HttpFilterCommonStringsExt::GetTable()), THTTPHdrVal((TBool)newConn));
       
   390     }
       
   391 }
       
   392 
       
   393 //  End of File
       
   394