httpfilters/httpfilterproxy/Src/HttpFilterProxy.cpp
changeset 0 b16258d2340f
child 8 fa2fd8b2d6cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/httpfilters/httpfilterproxy/Src/HttpFilterProxy.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,651 @@
+/*
+* 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:  Proxy filter
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <http.h>
+#include <es_sock.h>
+#include <cdbstore.h>
+#include <commdbconnpref.h>
+
+// User Includes
+#include "httpfilterproxy.h"
+#include "httpfiltercommonstringsext.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+void PanicHttpFiltersProxy(TInt aErr = 0);
+
+// CONSTANTS
+const TInt KProxyOrderOffset = 20;
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// LocalHostCheckL
+// If the host is a local host, then remove the proxy property. Returns ETrue
+// if the transaction request URI was for a localhost.
+// -----------------------------------------------------------------------------
+//
+TBool LocalHostCheckL(RHTTPTransaction& aTransaction, RStringPool& aStringPool)
+    {
+    _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)
+        {
+        // request is for localhost, explicitly state that this transaction
+        // must not be sent to proxy.
+    	RStringF proxyUsageStrF = aStringPool.StringF(HTTP::EProxyUsage, 
+                                                      RHTTPSession::GetTable());
+        
+    	RStringF dontUseProxyStrF = aStringPool.StringF(HTTP::EDoNotUseProxy, 
+                                                        RHTTPSession::GetTable());	
+
+        aTransaction.PropertySet().RemoveProperty(proxyUsageStrF);
+        aTransaction.PropertySet().SetPropertyL(proxyUsageStrF, dontUseProxyStrF);
+
+    	//RStringF proxyAddrStrF = aStringPool.StringF(HTTP::EProxyAddress, 
+        //                                             RHTTPSession::GetTable());
+
+        //aTransaction.PropertySet().RemoveProperty(proxyAddrStrF);
+        return ETrue;                                                          
+        }
+    return EFalse;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::CHttpFilterProxy
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CHttpFilterProxy::CHttpFilterProxy(RHTTPSession* aSession)
+{
+    __ASSERT_DEBUG(aSession != NULL, PanicHttpFiltersProxy());
+    iSession      = aSession;
+}
+
+
+// ------------------------------------------------------------------------------------------
+// CHttpFilterProxy::ConstructL
+// Symbian 2nd phase constructor can leave.
+// ------------------------------------------------------------------------------------------
+//
+void CHttpFilterProxy::ConstructL()
+{
+	iStringPool = iSession->StringPool();
+	iConnInfo = iSession->ConnectionInfo();
+	
+	// Added to fix panic when Proxy filter is used outside the browser initiated HTTP Framework.
+	iSession->StringPool().OpenL(HttpFilterCommonStringsExt::GetTable());
+
+    // 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 - KProxyOrderOffset,// The position of the filter in the queue
+                                            iStringPool.StringF(HttpFilterCommonStringsExt::EProxyFilter,RHTTPSession::GetTable()));  //The name of the filter to add
+
+	// register for notification of KErrNotReady error codes
+	// this allows us to re-start the connection if it fails
+	iSession->FilterCollection().AddFilterL(*this, KErrNotReady, MHTTPFilter::ETidyUp -1, iStringPool.StringF(HttpFilterCommonStringsExt::EProxyFilter,RHTTPSession::GetTable()));
+}
+
+//---------------------------------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------------------------------
+//
+CHttpFilterProxy::~CHttpFilterProxy()
+{
+    // Cleanup strings.
+    iProxyAddress.Close();
+    iExceptions.Close();
+
+/*
+//  Closing RSocketServ is causing crash in SDK Applications. SDK Apps will have to close RSocketServ and RConnection after closing CHTTPSession.
+//  It is not needed to close connection as soon as the CHttpConnectionManager close connection by
+//  calling   CHttpConnectionManager::CloseConnection()
+	if(iFilterOwnsConnection)
+		{
+		// Close ESOCK handles
+		iConnection.Close();
+		iSocketServ.Close();
+		}
+*/
+}
+
+// ---------------------------------------------------------------------------------------------
+// CHttpFilterProxy::InstallFilterL
+// Two-phased constructor. This function replaces NewL.
+// ---------------------------------------------------------------------------------------------
+//
+CHttpFilterProxy* CHttpFilterProxy::InstallFilterL(TAny* aSession)
+{
+    __ASSERT_DEBUG(aSession != NULL, PanicHttpFiltersProxy());
+    RHTTPSession* session = REINTERPRET_CAST(RHTTPSession*, aSession);
+    CHttpFilterProxy* filter = new (ELeave) CHttpFilterProxy( session );
+    CleanupStack::PushL(filter);
+    filter->ConstructL();
+    CleanupStack::Pop(filter);
+    return filter;
+}
+
+// ---------------------------------------------------------------------------------------------
+// CHttpFilterProxy::MHFLoad
+// Called when the filter is being added to the session's filter queue.
+// ---------------------------------------------------------------------------------------------
+//
+void CHttpFilterProxy::MHFLoad(RHTTPSession, THTTPFilterHandle)
+{
+    ++iLoadCount;
+}
+
+// ----------------------------------------------------------------------------------------------
+// CHttpFilterProxy::MHFUnload
+// Called when the filter is being removed from a session's filter queue.
+// ----------------------------------------------------------------------------------------------
+//
+void CHttpFilterProxy::MHFUnload(RHTTPSession /*aSession*/, THTTPFilterHandle /*aFilterHandler*/)
+{
+    __ASSERT_DEBUG(iLoadCount >= 0, PanicHttpFiltersProxy());
+    if (--iLoadCount)
+    {
+        return;
+    }
+    delete this;
+}
+
+// ------------------------------------------------------------------------------------------------
+// CHttpFilterProxy::MHFRunL
+// Process a transaction event.
+// ------------------------------------------------------------------------------------------------
+//
+void CHttpFilterProxy::MHFRunL(RHTTPTransaction aTransaction,
+                               const THTTPEvent& aEvent)
+    {
+    switch(aEvent.iStatus)
+	    {
+		case THTTPEvent::ESubmit:
+		    {
+            if (LocalHostCheckL(aTransaction, iStringPool))
+                {
+                return;
+                }
+			SetProxyL(aTransaction);
+		    } 
+            break;
+
+		case KErrNotReady:
+		    {
+            if (LocalHostCheckL(aTransaction, iStringPool))
+                {
+                return;
+                }
+			if(iFilterOwnsConnection)
+			    {
+				// we must re-start the RConnection
+		 		TInt err = iConnection.Start();
+				if (err == KErrAlreadyExists)
+				    {
+					// the KErrNotReady must have come from elsewhere
+					return;
+				    }
+
+				User::LeaveIfError(err);
+
+				// re-submit the transaction
+				aTransaction.Cancel();
+				aTransaction.SubmitL();				
+			    }
+			break;
+		    }
+
+		default:
+			break;
+	    }
+
+    }
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::MHFRunError
+// Process an error that occured while processing the transaction.
+// -----------------------------------------------------------------------------
+//
+TInt CHttpFilterProxy::MHFRunError(TInt /*aError*/,
+                                   RHTTPTransaction aTransaction,
+                                   const THTTPEvent& /*aEvent*/)
+{
+    // Cleanup strings.
+    iProxyAddress.Close();
+    iExceptions.Close();
+    aTransaction.Fail();
+    return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::MHFSessionRunL
+// Process a session event.
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterProxy::MHFSessionRunL(const THTTPSessionEvent& /*aEvent*/)
+{
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::MHFSessionRunError
+// Called when MHFRunL leaves from a session event.
+// -----------------------------------------------------------------------------
+//
+TInt CHttpFilterProxy::MHFSessionRunError(TInt aError, const THTTPSessionEvent& /*aEvent*/)
+{
+    return aError;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::SetProxyL
+// 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. If a proxy property has already been 
+// set by a higher filter or by the client, then those settings are preferred over 
+// CommsDB.
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterProxy::SetProxyL(const RHTTPTransaction aTransaction)
+{
+    THTTPHdrVal isNewConn, proxyAddress;
+
+    // If connection has been disconnected the user could change Access Point, so let's
+    // check if a new connection has been used.
+    TBool ret = iConnInfo.Property (iStringPool.StringF(HttpFilterCommonStringsExt::EHttpNewConnFlag,
+                                   HttpFilterCommonStringsExt::GetTable()), isNewConn);
+
+    if (ret && isNewConn.Type() == THTTPHdrVal::KTIntVal && (isNewConn.Int() == 1))
+    {
+        iUsage = EFalse;
+        // Read proxy info from the CommDB
+        ReadProxyInfoL(iStringPool,
+                       iUsage,
+                       iProxyAddress,
+                       iExceptions);
+    }
+    else
+    {
+        TBool useProxy( ETrue );
+        THTTPHdrVal proxyUsageVal;
+
+	    // Is the property for proxy usage set?
+        TBool hasUsageValue = iConnInfo.Property(iStringPool.StringF(HTTP::EProxyUsage,
+                            RHTTPSession::GetTable()), proxyUsageVal);
+                            
+        // If the property is set, is it EUseProxy
+        if (hasUsageValue)
+        {
+        useProxy = ( proxyUsageVal.StrF().Index(RHTTPSession::GetTable()) == HTTP::EUseProxy);
+        }
+
+        // Use proxy if the property value is EUseProxy or no property is set.
+        if (useProxy || !hasUsageValue)
+        {
+            THTTPHdrVal proxyAddressVal;
+            TBool hasValue = iConnInfo.Property(iStringPool.StringF(HTTP::EProxyAddress,
+                                               RHTTPSession::GetTable()), proxyAddressVal);
+            if (!hasValue)
+            {
+                // The proxyAddress has not been set, so Read proxy info from the CommDB
+                ReadProxyInfoL(iStringPool,
+                               iUsage,
+                               iProxyAddress,
+                               iExceptions);
+
+            }
+            else
+            {
+                // Now get the proxy address...
+                iProxyAddress = proxyAddressVal.StrF().Copy();
+                iUsage = ETrue;
+            }
+        }
+//      }
+    }
+
+    // We should not use proxy if the uri matches to one of exceptions from the exception list
+    // In this case the Origing server will be used
+
+    ExcptionsCompare(aTransaction);
+    
+    // Respect proxy settings already defined by client or higher HTTP filter
+    THTTPHdrVal proxyUsage;  // Check if property present or not present, not the value.
+    if ( !iConnInfo.Property(iStringPool.StringF(HTTP::EProxyUsage,
+                            RHTTPSession::GetTable()), proxyUsage)) 
+   	{ 
+
+		// Set the proxy address and proxy Usage
+		proxyAddress = THTTPHdrVal(iProxyAddress);
+
+		iConnInfo.RemoveProperty(iStringPool.StringF(HTTP::EProxyAddress,
+		                        RHTTPSession::GetTable()));
+		iConnInfo.SetPropertyL(iStringPool.StringF(HTTP::EProxyAddress,
+		                      RHTTPSession::GetTable()), proxyAddress);
+
+		iConnInfo.RemoveProperty(iStringPool.StringF(HTTP::EProxyUsage,
+		                        RHTTPSession::GetTable()));
+		if (iUsage)
+		{
+		    iConnInfo.SetPropertyL(iStringPool.StringF(HTTP::EProxyUsage,
+		                          RHTTPSession::GetTable()), iStringPool.StringF(HTTP::EUseProxy,
+		                                  RHTTPSession::GetTable()));
+		}
+		else
+		{
+		    iConnInfo.SetPropertyL(iStringPool.StringF(HTTP::EProxyUsage,
+		                          RHTTPSession::GetTable()), iStringPool.StringF(HTTP::EDoNotUseProxy,
+		                                  RHTTPSession::GetTable()));
+		}
+    	
+   	}  
+    
+
+    // Cleanup strings.
+    iProxyAddress.Close();
+    iExceptions.Close();
+}
+
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::ReadProxyInfoL
+// Purpose:	Reads the Proxy information from the comms database.
+// Gives the Proxy usage, a proxy address (<proxy name>:<proxy port>),
+// and proxy exceptions through the output arguments.
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterProxy::ReadProxyInfoL(const RStringPool aStringPool,
+                                      TBool&      aUsage,
+                                      RStringF&   aProxyAddress,
+                                      RStringF&   aExceptions)
+
+{
+    // Let's find Internet Access point ID (ServiceId) in use from the RConnection associated with the HTTP framework
+    THTTPHdrVal connValue;
+    TUint32     serviceId;
+    TUint pushCount = 0;
+    RConnection* connPtr = NULL;
+	THTTPHdrVal		iapId;
+	TCommDbConnPref pref;
+    TBool hasValue = iConnInfo.Property (aStringPool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()),
+                     connValue);
+
+    if (hasValue && connValue.Type() == THTTPHdrVal::KTIntVal)
+    {
+        connPtr = REINTERPRET_CAST(RConnection*, connValue.Int());
+	}
+	else
+	{
+		// Connect to ESOCK and open connection handle
+		User::LeaveIfError(iSocketServ.Connect());
+		User::LeaveIfError(iConnection.Open(iSocketServ));
+
+		TBool ret = iConnInfo.Property (aStringPool.StringF(HttpFilterCommonStringsExt::EAccessPointID, HttpFilterCommonStringsExt::GetTable()),
+                     iapId);
+		if (ret && (iapId.Type() == THTTPHdrVal::KTIntVal) && (iapId.Int() != 0) )
+			{
+			 pref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+			 pref.SetIapId( iapId.Int() );
+			 //pref.SetBearerSet( ECommDbBearerGPRS );
+			 pref.SetDirection(ECommDbConnectionDirectionOutgoing);
+			 TInt err = iConnection.Start(pref);
+			 if ( err != KErrNone )
+				User::LeaveIfError(iConnection.Start());
+			}
+		else
+			{
+			// start the connection - note that this thread will be blocked until the connection is established.
+			User::LeaveIfError(iConnection.Start());
+			}
+
+		connPtr = &iConnection;
+
+		// set the ESOCK handles as session properties after successful connection
+		iConnInfo.SetPropertyL(aStringPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), iSocketServ.Handle());
+		iConnInfo.SetPropertyL(aStringPool.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()), reinterpret_cast<TInt>(&iConnection));
+
+		iFilterOwnsConnection = ETrue;
+	}
+
+    // Retrieve the service Id  from the RConnection ; "<table name>/<field name>
+    User::LeaveIfError(connPtr->GetIntSetting(_L("IAP\\IAPService"), serviceId));
+
+    // Retrieve the service Type  from the RConnection
+    HBufC* serviceType16 = HBufC::NewL(KCommsDbSvrMaxFieldLength);
+    CleanupStack::PushL(serviceType16);
+    pushCount++;
+    TPtr serviceTypePtr16 = serviceType16->Des();
+    User::LeaveIfError(connPtr->GetDesSetting(_L("IAP\\IAPServiceType"), serviceTypePtr16));
+
+    // Open the Comms DB with the IAP style
+    CCommsDatabase* db=CCommsDatabase::NewL(EDatabaseTypeUnspecified);
+    CleanupStack::PushL(db);
+    pushCount++;
+
+    // Opens a view on records in the Proxies table with a specified range of service types and service IDs.
+    // Proxies records are included that have matching service types and IDs.
+    // When the use of the view object is complete, it should be popped from the cleanup stack, and deleted.
+    CCommsDbTableView* pView = db->OpenViewOnProxyRecordLC(serviceId, serviceTypePtr16);
+
+    pushCount++;
+    TInt err = pView->GotoFirstRecord();
+	aUsage = ETrue;
+	// if there is some other DB error.
+	if ( err != KErrNotFound && err != KErrNone )
+		{
+        User::LeaveIfError( err );
+		}
+    if ( err == KErrNotFound )
+		{// setting to EFalse because proxy table view does not exisit, was not created during Access point creation?
+		aUsage = EFalse;
+		}
+	else
+		// no need to keep going as not Proxy will be used. 
+		{
+		// Read the proxy usage flag from the selected Proxy record.
+		pView->ReadBoolL(TPtrC(PROXY_USE_PROXY_SERVER), aUsage);
+
+		// COntinue only if the proxy usage flag is set
+		if (aUsage)
+			{
+			// Read the server name specified in the selected Proxy record.
+			// The proxyAddress will be build based on the serverName and the port number
+			// separated with ':'
+			HBufC* serverName = pView->ReadLongTextLC(TPtrC(PROXY_SERVER_NAME));
+			pushCount++;
+			TPtr serverNamePtr16 = serverName->Des();
+			serverNamePtr16.Trim();
+
+			// Continue only if we have a proxy name
+			if (serverNamePtr16.Length() > 0 && serverNamePtr16.Ptr() != NULL)
+				{
+				// Read the port number specified in the selected Proxy record
+				TUint32 portNumber = 8080;      // default port number
+				TInt length = 1;                // add 1 for the separator ':'            
+				pView->ReadUintL(TPtrC(PROXY_PORT_NUMBER), portNumber);
+				// calculate the length of portNumber
+
+				if (portNumber == 0)
+				   {
+				   portNumber = 8080;
+				   }
+
+				TUint32 portNumSave = portNumber;
+				while (portNumSave > 0)
+					{
+				   portNumSave = portNumSave/10;
+				   length++;
+					}
+				// convert number to string & add to the server name. We should get <serverName1>:<port number>
+				HBufC8* proxyAddress8 = HBufC8::NewL(serverNamePtr16.Length() + length);
+				CleanupStack::PushL(proxyAddress8);
+				pushCount++;
+				TPtr8 proxyAddressPtr8 = proxyAddress8->Des();
+				proxyAddressPtr8.Copy(serverNamePtr16);
+				_LIT(KSeparator, ":");
+				proxyAddressPtr8.Append(KSeparator);
+				proxyAddressPtr8.AppendNum((TInt)portNumber);
+
+				// Set gateway as a service number - this is the proxy address
+				aProxyAddress = aStringPool.OpenFStringL(proxyAddressPtr8);
+
+				// Read the server name specified in the selected Proxy record.
+				HBufC* exceptions16 = pView->ReadLongTextLC(TPtrC(PROXY_EXCEPTIONS));
+				pushCount++;
+				TPtr exceptionsPtr16 = exceptions16->Des();
+				// Copy to 8-bits...
+				HBufC8* exceptions8 = HBufC8::NewL(exceptionsPtr16.Length());
+				CleanupStack::PushL(exceptions8);
+				pushCount++;
+				TPtr8 exceptionsPtr8 = exceptions8->Des();
+				exceptionsPtr8.Copy(exceptionsPtr16);
+
+				// Set gateway as a service number - this is the proxy address
+				aExceptions = aStringPool.OpenFStringL(exceptionsPtr8);
+				}
+			else
+				{
+				aUsage = EFalse;
+				}
+			}
+		}
+    // All done - clean up
+    CleanupStack::PopAndDestroy(pushCount); //pView, serverType16, db, serverName, proxyAddress8, exceptions8  exceptions16
+}
+
+//---------------------------------------------------------------------------------
+//
+//   Get exception from the list of exceptions
+//   Returns ETrue if there is at least one exception in the list.
+//   Returns EFalse if list of exceptions is empty or there is no exceptions in the list any more.
+//---------------------------------------------------------------------------------
+TBool CHttpFilterProxy::GetException(TPtr8& aException,TInt& aStartIndex)
+{
+    TBool done;
+    TPtrC8 exceptionsDesC = iExceptions.DesC();
+    TPtr8 exceptionsDes((TUint8*)exceptionsDesC.Ptr(), exceptionsDesC.Length(),exceptionsDesC.Length());
+
+    exceptionsDes.TrimAll();
+    // get part of string starting from aStartIndex. aStartIndex =0 when it is called the first time.
+    TPtrC8 desPtr = exceptionsDes.Mid(aStartIndex);
+
+    //The offset of the exception position from the beginning of the exception list
+    const TChar separator(';');
+    TInt position = desPtr.Locate(separator);
+    if (position != KErrNotFound)
+    {
+        // Extracts a portion of the data starting from the beggining
+        // Get the rest of the descriptor without the separator that we have found
+        aException.Set((unsigned char*)desPtr.Ptr(), position, position);
+        aStartIndex = position + 1;
+        done = ETrue;
+    }
+    else
+    {
+        aException.Set((unsigned char*)desPtr.Ptr(), desPtr.Length(), desPtr.Length());
+        done = EFalse;
+    }
+    return done;
+}
+
+// -----------------------------------------------------------------------------
+// CHttpFilterProxy::ExcptionsCompare
+// Compare each exception from the exception list against the current uri.
+// -----------------------------------------------------------------------------
+//
+void CHttpFilterProxy::ExcptionsCompare(const RHTTPTransaction aTransaction)
+{
+    if (iUsage)
+    {
+        TBool isFound  = ETrue;
+        TInt   index = 0;
+        TInt   loopCount = 0;
+        TPtr8 exception (NULL, 0,0);
+        // Let's get uri for this transaction to comapre the current uri with an exception.
+        // If the current uri has an exception for proxy set proxy usage to EDoNotUseProxy.
+        RHTTPRequest req = aTransaction.Request();
+        TUriC8 originalUri = req.URI();
+        const TDesC8& uriHost = originalUri.UriDes();
+
+        TPtrC8 exceptionsDes = iExceptions.DesC();
+        if (exceptionsDes.Length() != 0)
+        {
+            // at least one exception has been found in the list of exceptions
+            while (isFound)
+            {
+                loopCount++;                
+                isFound = GetException(exception, index);
+                if (exception.Compare(uriHost) == NULL)
+                {
+                    iUsage = EFalse;
+                    isFound = EFalse;
+                }
+            } //while
+        }
+    }
+}
+
+//  End of File