webservices/wshttpchanneltransportplugin/src/senhttpchannelimpl.cpp
changeset 0 62f9d29f7211
child 1 272b002df977
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wshttpchanneltransportplugin/src/senhttpchannelimpl.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,1939 @@
+/*
+* Copyright (c) 2002-2005 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:           
+*
+*/
+
+
+
+
+
+
+
+
+
+
+
+#include <uri8.h>
+#include <es_sock.h>
+#include <in_sock.h>
+#include <http.h>
+
+#include "sendebug.h" // filelogging and debugging MACROS
+#include <SenServiceConnection.h> // KErrSenNoHttpResponseBody
+#include <SenElement.h>
+#include <SenXmlUtils.h>
+#include <SenHttpTransportProperties.h>
+#include "senhttpchannelimpl.h"
+#include "senhttpeventhandler.h"
+#include "sentxnstate.h"
+#include "senatomtxnstate.h"
+#include "senrfiletxnstate.h"
+#include "senhttpchannel.h"
+#include "senlayeredhttptransportproperties.h"
+#include "msenidentitymanager.h"
+#include "senlogger.h"
+
+#include "senhttpchanneltransportplugin.h"
+//For HTTPProxyFilter
+#include <HttpFilterProxyInterface.h>
+#include <HttpFilterAcceptHeaderInterface.h>
+#include <HttpFilterCommonStringsExt.h>
+#include <DeflateFilterInterface.h>
+
+// CONSTANTS
+namespace
+    {
+    _LIT(KTxnStateNullPanicText,            "TxnState is NULL");
+
+    // Minimum granularity for array initialization
+    const TInt KMinimumArrayGranularity =   1;
+
+#ifdef _SENDEBUG
+    // logging constants
+    //_LIT(KLogFileDir, "SenHttpChannel");
+   // _LIT(KLogFileName, "SenHttpChannel.log");
+    _LIT(KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
+    // Size of buffer used when submitting request bodies
+    const TInt KMaxHeaderNameLen = 16;
+    const TInt KMaxHeaderValueLen = 128;
+    const TInt KMaxFilterNameLen = 16;
+#endif
+    }
+
+//
+// Implementation of CSenHttpChannelImpl
+//
+CSenHttpChannelImpl::CSenHttpChannelImpl(MSenIdentityManager& aManager)
+:
+    iIapId(KErrNone),
+    iManager(aManager),
+    iSessionAuthentication(NULL),
+    iPasswordFromUser(EFalse),
+    iExplicitIapDefined(EFalse),
+    iProxyHostPort(NULL),
+    iXopResponse(EFalse),
+    iHasHttpContentType(ETrue)
+    {
+    }
+
+CSenHttpChannelImpl* CSenHttpChannelImpl::NewL(MSenIdentityManager& aManager)
+    {
+    CSenHttpChannelImpl* pNew = NewLC(aManager);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+CSenHttpChannelImpl* CSenHttpChannelImpl::NewLC(MSenIdentityManager& aManager)
+    {
+    CSenHttpChannelImpl* pNew = new (ELeave) CSenHttpChannelImpl(aManager);
+    CleanupStack::PushL(pNew);
+    pNew->ConstructL();
+    return pNew;
+    }
+
+CSenHttpChannelImpl* CSenHttpChannelImpl::NewL(MSenIdentityManager& aManager,
+                                               TUint32 aIapId)
+    {
+    CSenHttpChannelImpl* pNew = NewLC(aManager, aIapId);
+    CleanupStack::Pop(pNew);
+    return pNew;
+    }
+
+CSenHttpChannelImpl* CSenHttpChannelImpl::NewLC(MSenIdentityManager& aManager,
+                                                TUint32 aIapId)
+    {
+    CSenHttpChannelImpl* pNew = new (ELeave) CSenHttpChannelImpl(aManager);
+    CleanupStack::PushL(pNew);
+    pNew->ConstructL(aIapId); 
+    return pNew;
+    }
+
+// Ask IAP from user
+void CSenHttpChannelImpl::ConstructL()
+    {
+    // Open connection to the file logger server
+    TLSLOG_OPEN(KSenHttpChannelLogChannelBase, KSenHttpChannelLogLevel, KSenHttpChannelLogDir, KSenHttpChannelLogFile);
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::ConstructL - Log file opened")));
+
+    // Open the RHTTPSession
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("- Opening HTTP/TCP session.")));
+
+    iSess.OpenL();
+
+    // Store the string pool for this HTTP session
+    iStringPool = iSess.StringPool();
+
+    // Install this class as the callback for authentication requests
+    InstallAuthenticationL( iSess );
+    //Install Proxy Filter  
+    iDeflateFilter = EFalse;
+
+#ifdef EKA2
+  //#ifndef _DEBUG 
+    CHttpFilterProxyInterface::InstallFilterL( iSess );
+    iSess.StringPool().OpenL(HttpFilterCommonStringsExt::GetLanguageTable());
+    iSess.StringPool().OpenL(HttpFilterCommonStringsExt::GetTable());
+
+    CHttpFilterAcceptHeaderInterface::InstallFilterL(iSess);
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"HTTPProxyFilter installed for EKA2 build.");
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"HTTPAcceptFilter installed for EKA2 build.");
+  //#else
+  //  LOG_WRITE_L("HTTPProxyFilter is NOT in use with EKA2 debug builds.");
+  //#endif
+#else // __INSTALL_HTTP_PROXY_FILTER__ is not defined by macro in .mmp
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"HTTPProxyFilter is NOT in use with EKA1.");
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"HTTPAcceptProxyFilter is NOT in use with EKA1.");
+#endif // __INSTALL_HTTP_PROXY_FILTER__
+
+    iTransObs = CSenHttpEventHandler::NewL(this);//, &iLog);
+    iTxnStates =
+        new (ELeave) CArrayPtrFlat<CSenTxnState>(KMinimumArrayGranularity);
+
+    iBasicConnectionTries = 0;
+
+#ifdef _SENDEBUG
+    ListFilters();
+#endif // _SENDEBUG
+    }
+
+// Forces preselected IAP to be used!
+void CSenHttpChannelImpl::ConstructL( TUint32 aIapId )
+    {
+    // Initialize
+//    SetupConnectionWithIapPrefsL( aIapId, iConnection, iSockServ );
+        
+    ConstructL();
+
+//    AttachSocketServerAndConnectionWithHttpSession( aIapId, iConnection, iSockServ );
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::ConstructL - Setting IAP id");
+
+
+//    Use local variable (new RSocketServer each time; handle is given to RHTTPSession via RConnectionInfo..)
+//    RSocketServ server; // with "anon" (local) socket servers, should we keep array of open ones in case of pending txns?
+//    SetIapPrefsL(aIapId, iConnection, server);
+
+    const TInt result = SetIapPrefsL(aIapId, ETrue, iConnection, iSockServ);
+    User::LeaveIfError( result );
+    
+    }
+
+CSenHttpChannelImpl::~CSenHttpChannelImpl()
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::~CSenHttpChannelImpl()");
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"Closing http session.");
+    iSess.Close();
+    if (iTransObs) //might be NULL if constructor failed ---
+        {
+        delete iTransObs;   
+        iTransObs = NULL;
+        }
+    if (iTxnStates) //might be NULL if constructor failed--- 
+        {
+        iTxnStates->ResetAndDestroy();
+        delete iTxnStates;
+        iTxnStates = NULL;
+        }
+
+    if(iProxyHostPort)
+        {
+        delete iProxyHostPort;
+        iProxyHostPort = NULL;
+        }
+    
+    if(iMultiPartContentType.params.Count())
+        {
+        iMultiPartContentType.params.Close();
+        }
+    if(iDeflateFilter)
+        {
+        REComSession::DestroyedImplementation(KDeflateFilterUid); 	
+        }
+        
+    iConnection.Close();
+    iSockServ.Close();
+
+    // Close the log file and the connection to the server.
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("Log file closed.")));
+    TLSLOG_CLOSE(KSenHttpChannelLogChannelBase);
+    }
+
+// This function expects that RConnection has been connected
+// and that RConnection has already been opened!
+/*
+void CSenHttpChannelImpl::SetIapPrefsL(TUint32 aIapId, 
+                                       RConnection& aConnection, 
+                                       RSocketServ& aSocketServer)
+    {
+    // Check whether IAP ID is not equal with the one that is currently in effect:
+    if(iExplicitIapDefined && iIapId == aIapId )
+        {
+        return; // nothing to do
+        }
+        
+    LOG_WRITEFORMAT((_L8("- SetIapPrefsL: Re-setting IAP ID (%d)"), aIapId));
+
+    // Check if socket server (connection) is already open..
+    if( iExplicitIapDefined )
+        {
+         // Socket server opened once before for some other IAP
+        LOG_WRITE_L("- SetIapPrefsL: Re-using existing RConnection => calling RConnection::Stop");
+        aConnection.Stop();
+        }
+    else
+        {
+        aConnection.Stop(); // prompted from user
+        iSess.DisconnectL();
+        iSess.ConnectL();
+
+        // Connect to a socket server    
+        LOG_WRITE_L("- SetIapPrefsL: Connecting to new socket server");    
+        User::LeaveIfError(aSocketServer.Connect());       
+
+        // Open new connection
+        LOG_WRITE_L("- SetIapPrefsL: Opening new RConnection using the socket server.");       
+        User::LeaveIfError(aConnection.Open(aSocketServer)); 
+        }
+        
+    // Set the IAP selection preferences (IAP ID, do not prompt)
+    TCommDbConnPref pref;
+    pref.SetIapId( aIapId );    
+
+    TCommDbDialogPref dialogPref;
+    dialogPref = ECommDbDialogPrefDoNotPrompt;
+    pref.SetDialogPreference(dialogPref);
+    
+    // Start the connection with the new preferences
+    LOG_WRITE_L("- SetIapPrefsL: Calling RConnection::Start with new IAP prefs");
+    aConnection.Start(pref);
+    
+    // Get the connection "handle" from the HTTP session    
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+     
+    // Attach socket server
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketServ,
+                                                RHTTPSession::GetTable()),
+                                                THTTPHdrVal(aSocketServer.Handle()));
+    
+    // Attach connection  
+    TInt connPtr = REINTERPRET_CAST(TInt, &aConnection);
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketConnection, 
+                                                RHTTPSession::GetTable()), 
+                                                THTTPHdrVal(connPtr));
+                                                
+    // Remember the IAP id that is being set; there is
+    // no direct API to query effective IAP ID from CommsDB.
+    iExplicitIapDefined = ETrue;
+    iIapId = aIapId;
+    }
+*/
+
+
+/*
+void CSenHttpChannelImpl::SetupConnectionWithIapPrefsL( TUint32 aIapId, 
+                                                        RConnection& aConnection, 
+                                                        RSocketServ& aSocketServer )
+    {
+    // Check whether IAP ID is not equal with the one that is currently in effect:
+    if(iExplicitIapDefined && iIapId == aIapId )
+        {
+        return; // nothing to do
+        }
+        
+    LOG_WRITEFORMAT((_L8("- SetIapPrefsL, IAP ID (%d)"), aIapId));
+
+    // Check if socket server (connection) is already open..
+    if( iExplicitIapDefined )
+        {
+         // Socket server opened once before for some other IAP
+        LOG_WRITE_L("- SetIapPrefsL: Re-using existing RConnection => calling RConnection::Stop");
+        aConnection.Stop();
+        }
+    else
+        {
+        // Connect to a socket server    
+        LOG_WRITE_L("- SetIapPrefsL: Connecting to new socket server");    
+        User::LeaveIfError( aSocketServer.Connect() );       
+
+        // Open new connection
+        LOG_WRITE_L("- SetIapPrefsL: Opening new RConnection using the socket server.");       
+        User::LeaveIfError( aConnection.Open(aSocketServer) ); 
+        }
+        
+    // Set the IAP selection preferences (IAP ID, do not prompt)
+    TCommDbConnPref pref;
+    pref.SetIapId( aIapId );    
+
+    TCommDbDialogPref dialogPref;
+    dialogPref = ECommDbDialogPrefDoNotPrompt;
+    pref.SetDialogPreference(dialogPref);
+    
+    // Start the connection with the new preferences
+    LOG_WRITE_L("- SetIapPrefsL: Calling RConnection::Start with new IAP prefs");
+    aConnection.Start(pref);
+    }
+    
+
+void CSenHttpChannelImpl::AttachSocketServerAndConnectionWithHttpSession( TUint32 aIapId, 
+                                                                          RConnection& aConnection, 
+                                                                          RSocketServ& aSocketServer )
+    {
+    if(iExplicitIapDefined && iIapId == aIapId )
+        {
+        return; // nothing to do
+        }
+
+    // Get the connection "handle" from the HTTP session    
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+     
+    // Attach socket server
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketServ,
+                                                RHTTPSession::GetTable()),
+                                                THTTPHdrVal(aSocketServer.Handle()));
+    
+    // Attach connection  
+    TInt connPtr = REINTERPRET_CAST(TInt, &aConnection);
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketConnection, 
+                                                RHTTPSession::GetTable()), 
+                                                THTTPHdrVal(connPtr));
+                                                
+    // Remember the IAP id that is being set, because *at the moment*,
+    // there is NO direct API to query effective IAP ID from CommsDB.
+    iExplicitIapDefined = ETrue;
+    iIapId = aIapId;
+    }
+    
+
+void CSenHttpChannelImpl::SetIapPrefsL( TUint32 aIapId, RConnection& aConnection, RSocketServ& aSocketServer )
+    {
+    SetupConnectionWithIapPrefsL( aIapId, aConnection, aSocketServer );
+    AttachSocketServerAndConnectionWithHttpSession( aIapId, aConnection, aSocketServer );
+    }        
+*/
+
+
+TInt CSenHttpChannelImpl::SetIapPrefsL( TUint32 aIapId, TBool aDialogPref, RConnection& aConnection, RSocketServ& aSocketServer )
+   	{
+   	TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KNormalLogLevel, _L8("- SetIapPrefsL, IAP ID (%d)"), aIapId));
+   	
+    // Check whether IAP ID is not equal with the one that is currently in effect:
+    if(iExplicitIapDefined && iIapId == aIapId )
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Iap Id is same as currently in effect");
+        return KErrNone;
+        }
+		else
+				{
+				TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Iap Id different with the currently in effect");
+				}    
+    
+
+    // Check if socket server (connection) is already open..
+    if( iExplicitIapDefined )
+        {
+         // Socket server opened once before for some other IAP
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Re-using existing RConnection => calling RConnection::Stop");
+        aConnection.Stop();
+        }
+    else
+        {
+        // Connect to a socket server    
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Connecting to new socket server");    
+        User::LeaveIfError( aSocketServer.Connect() );       
+
+        // Open new connection
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Opening new RConnection using the socket server.");       
+        User::LeaveIfError( aConnection.Open(aSocketServer) ); 
+        }
+        
+    // Set the IAP selection preferences (IAP ID, do not prompt)
+    /*
+    /*Single click connectivity feature has been implemented by CSock (RConnection class).
+    /*According to this client no need to set the IAP ID. 
+    /*Automatically RConnection will use the suitable IAP
+    */
+    
+
+	    TCommDbConnPref pref;
+    #ifndef __SINGLE_CLICK_CONNECTIVITY_ENABLED__	    
+	    pref.SetIapId( aIapId );
+		#else
+			pref.SetIapId( 0 );	 //By default IAP ID is "0". IAP selection will take care by RConnection
+    #endif //__SINGLE_CLICK_CONNECTIVITY_ENABLED__	    
+	    TCommDbDialogPref dialogPref;
+	    
+	    if (aDialogPref)
+	        {
+	        dialogPref = ECommDbDialogPrefDoNotPrompt;
+	        }
+	    else
+	        {
+	        dialogPref = ECommDbDialogPrefPrompt;
+	        }     
+	    pref.SetDialogPreference(dialogPref);
+    
+  	// Start the connection with the new preferences
+	  TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetIapPrefsL: Calling RConnection::Start with new IAP prefs");
+
+    TInt retVal =aConnection.Start(pref);
+    
+		TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("RConnection->Start retVal [%d]"), retVal));
+		        
+    // Get the connection "handle" from the HTTP session    
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+     
+    // Attach socket server
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketServ,
+                                                RHTTPSession::GetTable()),
+                                                THTTPHdrVal(aSocketServer.Handle()));
+    
+    // Attach connection  
+    TInt connPtr = REINTERPRET_CAST(TInt, &aConnection);
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketConnection, 
+                                                RHTTPSession::GetTable()), 
+                                                THTTPHdrVal(connPtr));
+                                                
+    // Remember the IAP id that is being set, because *at the moment*,
+    // there is NO direct API to query effective IAP ID from CommsDB.
+    if (!retVal)
+        {
+        iExplicitIapDefined = ETrue;
+        iIapId = aIapId;
+        }
+    return retVal;
+    }
+TInt CSenHttpChannelImpl::SetSnapPrefsL( TUint32 aSnapId, TBool aDialogPref, RConnection& aConnection, RSocketServ& aSocketServer )
+    {
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- CSenHttpChannelImpl::SetSnapPrefsL, SNAP ID (%d)"), aSnapId));
+		// Check whether SNAP ID is not equal with the one that is currently in effect:
+    if(iExplicitIapDefined && iSnapId == aSnapId )
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Sanp is same as currently in effect");
+        return KErrNone;
+        }
+		else
+			{
+			TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Sanp is different with currently in effect");
+			}        
+
+    // Check if socket server (connection) is already open..
+    if( iExplicitIapDefined )
+        {
+         // Socket server opened once before for some other IAP
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Re-using existing RConnection => calling RConnection::Stop");
+        aConnection.Stop();
+        }
+    else
+        {
+        // Connect to a socket server    
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Connecting to new socket server");    
+        User::LeaveIfError( aSocketServer.Connect() );       
+
+        // Open new connection
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Opening new RConnection using the socket server.");       
+        User::LeaveIfError( aConnection.Open(aSocketServer) ); 
+        }
+        
+    // Set the SNAP selection preferences (SNAP ID)
+    TConnSnapPref pref;
+    pref.SetSnap(aSnapId);     
+    
+    // Start the connection with the new preferences
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Calling RConnection::Start with new SNAP prefs");
+    TInt retVal = aConnection.Start(pref);
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- SetSnapPrefsL, RConnection::Start returned: (%d)"), retVal));
+    
+    // Get the connection "handle" from the HTTP session    
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+     
+    // Attach socket server
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketServ,
+                                                RHTTPSession::GetTable()),
+                                                THTTPHdrVal(aSocketServer.Handle()));
+    
+    // Attach connection  
+    TInt connPtr = REINTERPRET_CAST(TInt, &aConnection);
+    connInfo.SetPropertyL(iStringPool.StringF(  HTTP::EHttpSocketConnection, 
+                                                RHTTPSession::GetTable()), 
+                                                THTTPHdrVal(connPtr));
+                                                
+    // Remember the SNAP id that is being set, because *at the moment*,
+    // there is NO direct API to query effective SNAP ID from CommsDB.
+    if (!retVal)
+        {
+        iExplicitIapDefined = ETrue;
+        iSnapId = aSnapId;
+        }
+    return retVal;
+    }
+
+TInt CSenHttpChannelImpl::SendL( MSenResponseObserver& aObserver,
+                                 const TDesC8& aUri,
+                                 const TDesC8& aContent,
+                                 CSenLayeredHttpTransportProperties& aProps )
+    {
+#ifdef _SENDEBUG
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::SendL:");
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Endpoint URI: %S"), &aUri));
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"- Content(msg):");
+    TLSLOG_ALL(KSenHttpChannelLogChannelBase , KMaxLogLevel,(aContent));
+#endif
+
+    TPtrC8 contentType;
+    TInt retVal = aProps.ContentTypeL(contentType);
+    if(retVal!=KErrNone)
+        {
+        // Use the default
+        contentType.Set(KDefaultContentType);
+        }
+
+    CSenTxnState* pTxnState = CSenTxnState::NewL(aObserver,
+                                                 //Log(),
+                                                 &aUri,
+                                                 contentType,
+                                                 &aContent);
+
+    CleanupStack::PushL(pTxnState);
+    AppendNewTxnStateL(pTxnState);
+    CleanupStack::Pop(); // pTxnState
+
+    return InvokeHttpMethodL(pTxnState, aProps);
+    }
+    
+TInt CSenHttpChannelImpl::SendL( MSenResponseObserver& aObserver,
+                                 const TDesC8& aUri,
+                                 const RFile& aFile,
+                                 CSenLayeredHttpTransportProperties& aProps )
+    {
+#ifdef _SENDEBUG
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::SendL:");
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Endpoint URI: %S"), &aUri));
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"- Content(msg):");
+#endif
+
+    TPtrC8 contentType;
+    TInt retVal = aProps.ContentTypeL(contentType);
+    if(retVal != KErrNone)
+        {
+        // Use the default
+        contentType.Set(KDefaultContentType);
+        }
+
+    CSenRfileTxnState* pTxnState = CSenRfileTxnState::NewL(aObserver,
+                                                 //Log(),
+                                                 &aUri,
+                                                 this,
+                                                 contentType,
+                                                 aFile);
+
+    CleanupStack::PushL(pTxnState);
+    AppendNewTxnStateL(pTxnState);
+    CleanupStack::Pop(); // pTxnState
+
+    return InvokeHttpMethodL(pTxnState, aProps);
+    }
+    
+    
+TInt CSenHttpChannelImpl::SendL(MSenResponseObserver& aObserver,
+                           	    const TDesC8& aUri,
+                               	CSenSoapEnvelope2& aContent, 
+                               	CSenLayeredHttpTransportProperties& aProps)
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::SendL:");
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Endpoint URI: %S"), &aUri));
+    
+    TPtrC8 soapAction;
+    TInt retVal = aProps.SoapActionL(soapAction);
+    
+    CSenMtomTxnState* pMtomTxnState = CSenMtomTxnState::NewL(aObserver,
+                                             				 //Log(),
+                                             				 &aUri,
+                                             				 soapAction,
+                                             				 aContent);
+                                             				 
+    if (aContent.SoapVersion() == ESOAP12)
+      {
+    aProps.RemovePropertyL(KSoapActionLocalName, MSenLayeredProperties::ESenMessageLayer);
+      }
+
+	CleanupStack::PushL(pMtomTxnState);
+	AppendNewTxnStateL(pMtomTxnState);
+    CleanupStack::Pop(); // pMtomTxnState
+
+	return InvokeHttpMethodL(pMtomTxnState, aProps);
+    }
+TInt CSenHttpChannelImpl::SendL(MSenResponseObserver& aObserver,
+                           	    const TDesC8& aUri,
+                               	CSenAtomEntry& aContent, 
+                               	CSenLayeredHttpTransportProperties& aProps)
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::SendL:");
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Endpoint URI: %S"), &aUri));
+    CSenAtomTxnState* pAtomTxnState = CSenAtomTxnState::NewL(aObserver,
+                                             				 &aUri,
+                                             				 aContent);
+                                             				 
+    CleanupStack::PushL(pAtomTxnState);
+	AppendNewTxnStateL(pAtomTxnState);
+    CleanupStack::Pop(); // pAtomTxnState
+
+	return InvokeHttpMethodL(pAtomTxnState, aProps);
+    }    
+/** Invoke the http method
+This actually creates the transaction,
+sets the headers and body and then starts the transaction
+*/
+TInt CSenHttpChannelImpl::InvokeHttpMethodL(CSenTxnState* aTxnState,
+                                            CSenLayeredHttpTransportProperties& aProps)
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::InvokeHttpMethodL");
+    TUriParser8 uri;
+    RStringF method;
+    TPtrC8 deflate;
+    // Set IAP preferences, if such exist in properties (and not already in effect):
+    TUint32 iapId(KErrNone);
+    TBool doNotPrompt(ETrue); 
+    
+    TInt retVal = aProps.IAPDialogL( doNotPrompt );
+    if ( retVal != KErrNone )
+        {
+        // by default, do not prompt (even if property does not exist!) 
+        // => only if property is set, and has value "FALSE", show PROMPT            
+        doNotPrompt = ETrue;
+        }
+
+    // Independent of dialog preference (property's existance), if IAP was predefined, it must be set        
+    if(((aProps.IapIdL(iapId)) == KErrNone))
+        {
+        retVal = SetIapPrefsL(iapId, doNotPrompt, iConnection, iSockServ);
+        }
+    else if(((aProps.SnapIdL(iapId)) == KErrNone))
+        {
+        retVal = SetSnapPrefsL(iapId, doNotPrompt, iConnection, iSockServ);
+        }
+    else//to better control RConnection, we have to call Start by ourselve
+        {
+        retVal = SetSnapPrefsL(0, EFalse, iConnection, iSockServ);
+        if(retVal == KErrNotFound)
+            {
+            retVal = SetIapPrefsL(0, EFalse, iConnection, iSockServ);
+            }
+        }
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Set Snap/IAP prefs retVal [%d]"), retVal));    
+    User::LeaveIfError(retVal);
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::InvokeHttpMethodL After User::Leave");
+    TInt ret=iConnection.GetIntSetting(_L("IAP\\Id"), iUsedIapId);
+    // Check transport properties
+    CSenLayeredHttpTransportProperties::TSenHttpMethod httpMethod;
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("IAP %d"), iapId));
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("DONT PROMPT %d"), doNotPrompt));
+    TInt retValHttpMethod = aProps.HttpMethodL(httpMethod);
+    
+    
+    /*Installing the deflate filter based on the property values */
+    /*Once installed, the filter will be alive for on session lifetime */   
+    if(KErrNone == aProps.PropertyL(KWsPropertyValueHttpFilterDeflate,deflate))
+       {
+        if(!iDeflateFilter)
+          {
+           TRAPD(err, CHttpDeflateFilter::InstallFilterL(iSess));
+           if(err == KErrNone) 
+           	{
+		     		iDeflateFilter = ETrue;  
+	          TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"HTTPDeflateFilter installed for EKA2 build.");	
+						}
+					else
+		     		{
+		      	TLSLOG_L(KSenHttpChannelLogChannelBase , KNormalLogLevel,"ERROR:HTTPDeflateFilter Not installed for EKA2 build.");
+		     		}
+          }
+       }
+
+
+    if(!aTxnState->HasRequestBody())
+        {
+        if (retValHttpMethod) httpMethod = CSenLayeredHttpTransportProperties::ESenHttpGet;
+        User::LeaveIfError( uri.Parse(aTxnState->RequestUri()) );
+        switch(httpMethod)
+            {
+            case CSenLayeredHttpTransportProperties::ESenHttpPost:
+                {
+                method = iStringPool.StringF(HTTP::EPOST, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EPOST");
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpPut:
+                {
+                method = iStringPool.StringF(HTTP::EPUT, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EPUT");
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpDelete:
+                {
+                method = iStringPool.StringF(HTTP::EDELETE, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EDELETE");
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpGet:
+            default:
+                {
+                // Default to HTTP GET, if no body has been provided
+                method = iStringPool.StringF(HTTP::EGET, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EGET");
+                }
+            }
+        }
+    else 
+        {   
+        // Some request "body"; or a query string for GET or DELETE was provided
+        if (retValHttpMethod) httpMethod = CSenLayeredHttpTransportProperties::ESenHttpPost;
+        switch(httpMethod)
+            {
+            case CSenLayeredHttpTransportProperties::ESenHttpGet:
+                {
+                method = iStringPool.StringF(HTTP::EGET, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EGET");
+                // The responsibility of correct query string for GET URI 
+                // is on the shoulders of the original invoker (public API
+                // caller):
+                aTxnState->TransformBodyToUriL();
+
+                // NOTE: warning from Uri16.h:
+                // @warning The descriptor that is parsed by an object of this class will be referenced 
+                // by that object. If the original descriptor is no longer in scope there will be undefined 
+                // behaviour.
+                User::LeaveIfError( uri.Parse(aTxnState->RequestUri()) );
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpPut:
+                {
+                method = iStringPool.StringF(HTTP::EPUT, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EPUT");
+                User::LeaveIfError( uri.Parse(aTxnState->RequestUri()) );
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpDelete:
+                {
+                method = iStringPool.StringF(HTTP::EDELETE, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EDELETE");
+                // The responsibility of correct query string for DELETE URI 
+                // argument is on the shoulders of the original invoker 
+                // (public API caller):
+                aTxnState->TransformBodyToUriL();
+                User::LeaveIfError( uri.Parse(aTxnState->RequestUri()) );
+                }
+                break;
+            case CSenLayeredHttpTransportProperties::ESenHttpPost:
+            default:
+                {
+                // default to HttpPost
+                method = iStringPool.StringF(HTTP::EPOST, RHTTPSession::GetTable());
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- HTTP::EPOST");
+                User::LeaveIfError( uri.Parse(aTxnState->RequestUri()) );
+                }
+            }
+        }
+
+
+    RHTTPTransaction transaction = iSess.OpenTransactionL(uri, *iTransObs, method);
+    iHttpTransaction = transaction ;
+    aTxnState->SetId(transaction.Id());
+    aTxnState->SetTransaction(transaction);
+    aTxnState->SetSession(iSess); 
+    RHTTPHeaders hdr = transaction.Request().GetHeaderCollection();
+
+    // Add request headers: Accept, User-Agent, any other user defined ones
+    AddRequestHeadersL(hdr, aProps);
+
+    // Add Content type header and request body if available
+    if(aTxnState->HasRequestBody())
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- Adding content type header and request body");
+
+        // Set the "Content-Type" HTTP header here, and *only* here(!)
+        aTxnState->SetContentTypeHeaderL(iSess, hdr);
+
+        MHTTPDataSupplier* pDataSupplier = aTxnState;
+        transaction.Request().SetBody(*pDataSupplier);
+        }
+#ifdef _SENDEBUG
+    else
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- This transaction does not carry a request body.");
+        }
+#endif
+
+    // Submit the transaction
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- Submitting the transaction.");
+    transaction.SubmitL();
+    return aTxnState->Id();
+    }
+
+void CSenHttpChannelImpl::NotifyMoreBodyL()    
+{
+	iHttpTransaction.NotifyNewRequestBodyPartL();
+}
+
+void CSenHttpChannelImpl::SetProxyL(const TDesC8& aProxyHostBaseAddr, 
+                                    TInt aProxyPort)
+    {
+    TBuf8<64> port;
+    port.AppendNum(aProxyPort);
+    HBufC8* pProxyHostPort = HBufC8::NewLC(aProxyHostBaseAddr.Length()
+                                           +KColon().Length()
+                                           +port.Length());
+
+    pProxyHostPort->Des().Append( aProxyHostBaseAddr );
+    pProxyHostPort->Des().Append( KColon );
+    pProxyHostPort->Des().AppendNum( aProxyPort );
+
+    TPtrC8 proxy = pProxyHostPort->Des();
+    SetProxyL( proxy );
+    CleanupStack::PopAndDestroy(pProxyHostPort);
+    }
+
+void CSenHttpChannelImpl::SetProxyL(const TDesC8& aProxyAddrStr)
+    {
+    if(iProxyHostPort && iProxyHostPort->Compare(aProxyAddrStr)==0)
+        {
+        // nothing to do, proxy address is already in use
+        return;
+        }
+
+    delete iProxyHostPort;
+    iProxyHostPort = NULL;
+
+    iProxyHostPort = aProxyAddrStr.AllocL();
+
+    RStringF proxyAddr = iSess.StringPool().OpenFStringL(*iProxyHostPort);
+
+    CleanupClosePushL(proxyAddr);
+
+    // Set the proxy here...
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+    THTTPHdrVal proxyUsage(
+        iSess.StringPool().StringF(HTTP::EUseProxy, RHTTPSession::GetTable()));
+    connInfo.SetPropertyL(
+        iSess.StringPool().StringF(HTTP::EProxyUsage, RHTTPSession::GetTable()),
+                                    proxyUsage);
+    connInfo.SetPropertyL(
+        iSess.StringPool().StringF(
+                    HTTP::EProxyAddress, RHTTPSession::GetTable()), proxyAddr);
+
+    CleanupStack::PopAndDestroy(); // proxyAddr
+    }
+
+void CSenHttpChannelImpl::SetHttpVersionL(TInt aVersion)
+    {
+    HTTP::TStrings httpVersion = HTTP::EHttp11;
+    if(0 == aVersion)
+        {
+        httpVersion = HTTP::EHttp10;
+        }
+
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+    RStringPool p=iSess.StringPool();
+    connInfo.SetPropertyL(p.StringF(
+                            HTTP::EHTTPVersion,RHTTPSession::GetTable()),
+                          THTTPHdrVal(
+                          p.StringF(httpVersion,RHTTPSession::GetTable())));
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KNormalLogLevel, _L8("Http version is set to HTTP 1.%d"), aVersion));
+    }
+
+void CSenHttpChannelImpl::SetProxyUsageL(TBool aProxyUsage)
+    {
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+    RStringPool strPool=iSess.StringPool();
+    if ( aProxyUsage )
+        {
+        connInfo.SetPropertyL
+            ( 
+            strPool.StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), 
+            THTTPHdrVal( strPool.StringF(HTTP::EUseProxy, RHTTPSession::GetTable() ) )
+            );    
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Http Proxy usage is set to TRUE")));
+        }
+    else
+        {
+        connInfo.SetPropertyL
+            ( 
+            strPool.StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() ), 
+            THTTPHdrVal( strPool.StringF(HTTP::EDoNotUseProxy, RHTTPSession::GetTable() ) )
+            );    
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Http Proxy usage is set to FALSE")));
+        
+        }
+    }
+
+void CSenHttpChannelImpl::SetSecureDialogL(TBool aSecureDialog)
+    {
+    RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
+    RStringPool strPool=iSess.StringPool();
+    if ( aSecureDialog )
+        {
+        connInfo.SetPropertyL
+            ( 
+            strPool.StringF( HTTP::ESecureDialog, RHTTPSession::GetTable() ), 
+            THTTPHdrVal( strPool.StringF(HTTP::EDialogPrompt, RHTTPSession::GetTable() ) )
+            );    
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Http Secure dialog prompt is set to TRUE")));
+        }
+    else
+        {
+        connInfo.SetPropertyL
+            ( 
+            strPool.StringF( HTTP::ESecureDialog, RHTTPSession::GetTable() ), 
+            THTTPHdrVal( strPool.StringF(HTTP::EDialogNoPrompt, RHTTPSession::GetTable() ) )
+            );    
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Http Secure dialog prompt is set to FALSE")));
+        
+        }
+    }
+    
+// ----------------------------------------------------------------------------
+// CSenHttpChannelImpl::AddRequestHeadersL
+// Adds headers to the request.
+// ----------------------------------------------------------------------------
+void CSenHttpChannelImpl::AddRequestHeadersL(RHTTPHeaders& aHeaders,
+                                             CSenLayeredHttpTransportProperties& aProps)
+    {
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::AddRequestHeadersL")));
+
+
+    //TPtrC8 useragent;
+    TInt retVal;// = aProps.UserAgentL(useragent);
+
+    // It is MANDATORY, that User-Agent header exists:
+ //   if ( useragent.Length()== 0 )
+ //       {
+ //       //iProperties->SetPropertyL(KUserAgentLocalName, KSenHttpChannelUserAgentHeaderDefault, KHttpHeaderType);            
+ //       useragent.Set( KSenHttpChannelUserAgentHeaderDefault );
+ //       }
+
+    // Fetch the accepted content types:
+    MSenProperty* acceptHeaders = NULL;
+    retVal = aProps.AcceptL(acceptHeaders);
+    RPointerArray<TPtrC8> tokens;
+    CleanupClosePushL(tokens);
+
+    if(retVal == KErrNone)
+        {
+        if(acceptHeaders)
+            {
+            TInt retVal = acceptHeaders->ValueTokensL(KSenHttpAcceptHeaderDelimiter, tokens);
+            // Sanity check
+            if(retVal == KErrNone && tokens.Count()==0)
+                {
+                retVal = KErrNotFound; // should not happen
+                }
+            }
+        else
+            {
+            retVal = KErrNotFound; // should not happen
+            }
+        }
+
+    // It is MANDATORY, that at least one Accept header TOKEN exists:
+  if ( tokens.Count()==0 )
+        {
+        TPtrC8* pDefaultToken = new (ELeave) TPtrC8( KSenHttpChannelAcceptHeaderDefault );
+        TInt error = tokens.Append( pDefaultToken );
+        if ( error )
+            {
+            delete pDefaultToken;
+            }
+        }
+    // Http headers
+    TInt headerCount(0);
+    RPointerArray<MSenProperty> headersArray;
+    retVal = aProps.HttpHeadersL(headersArray);
+    if ( retVal == KErrNone )
+        {
+        CleanupClosePushL(headersArray);
+        headerCount = headersArray.Count();
+        for(TInt i=0; i<headerCount; i++)
+            {
+            MSenProperty* property = headersArray[i];
+            if(property)
+                {
+                TPtrC8 name = property->Name();
+
+                // Check if header name is "Content-Type"
+                if(!name.Compare(KContentTypeLocalName) ||
+                   !name.Compare(KAcceptLocalName))
+                    {
+                    // Skip Content-Type header(s) in here:
+                    // - otherwise HTTP GET might get confused
+
+                    // NOTE(!): Content-Type header is added separately
+                    // through CSenTxnState -object:
+                    // @InvokeHttpMethodL()
+                    continue;
+                    }
+
+                TPtrC8 value = property->Value();
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Adding HTTP HEADER, name: (%S), value: (%S)"),
+                    &name, &value));
+
+                // Open stringpool strings
+                RStringF headerName = iStringPool.OpenFStringL(name);
+                CleanupClosePushL(headerName);
+                RStringF headerValue = iStringPool.OpenFStringL(value);
+                CleanupClosePushL(headerValue);
+                // Create header name field
+                THTTPHdrVal headerFieldVal;
+                headerFieldVal.SetStrF(headerValue);
+                // Check if the header field value already exists
+                TBool fieldValueExists = EFalse;
+                TInt fieldCount = aHeaders.FieldPartsL(headerName);
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Header < %S > field count: %d"), &name,
+                                        fieldCount));
+
+                for(TInt j=0; j<fieldCount; j++)
+                    {
+                    THTTPHdrVal hVal;
+                    TInt retCode = aHeaders.GetField(headerName, j, hVal);
+                    if(KErrNotFound != retCode)
+                        {
+                        if(hVal == headerFieldVal)
+                            {
+                            TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Header < %S: %S > already exists"),
+                                               &name, &value));
+
+                            fieldValueExists = ETrue;
+                            }
+                        }
+                    }
+
+                // Add header field
+                if(!fieldValueExists)
+                    {
+                    aHeaders.SetFieldL(headerName, headerFieldVal);
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Header < %S: %S > added"),
+                                       &name, &value));
+                    }
+
+                // Close stringpool strings
+                CleanupStack::PopAndDestroy(2); // headerValue, headerName
+                }
+            }
+        headersArray.Reset();
+        CleanupStack::Pop(); // headersArray
+        }
+    else
+        {
+        // No HTTP headers were found(!)
+        User::Leave( retVal );
+        }
+
+    for (TInt k = 0; k < tokens.Count(); k++)
+        {
+        TPtrC8 token = *tokens[k]; // accept header value
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("- Adding token to Accept header (%S)"), tokens[k]));
+
+        //const TDesC8& acceptHeaderValueStr
+        //        = iAcceptedContentTypes->MdcaPoint(k);
+
+        // Open stringpool string
+        RStringF acceptHeaderValue 
+            = iStringPool.OpenFStringL(token);
+
+        CleanupClosePushL(acceptHeaderValue);
+
+        // Create header name field
+        THTTPHdrVal headerFieldVal;
+        headerFieldVal.SetStrF(acceptHeaderValue);
+
+        // Check if the header field value already exists
+        TBool fieldValueExists = EFalse;
+
+        TInt fieldCount = aHeaders.FieldPartsL(
+            iStringPool.StringF(HTTP::EAccept, RHTTPSession::GetTable()));
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KNormalLogLevel, _L8("Accept header field count: %d"), fieldCount));
+
+
+        for(TInt j = 0; j < fieldCount; j++)
+            {
+            THTTPHdrVal hVal;
+            TInt retCode = aHeaders.GetField(
+                iStringPool.StringF(HTTP::EAccept, 
+                                    RHTTPSession::GetTable()),
+                                    j, 
+                                    hVal);
+
+            if(KErrNotFound != retCode)
+                {
+#ifdef _SENDEBUG
+                const TDesC8& hValStr = hVal.StrF().DesC();
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Accept: %S"),
+                                   &hValStr));
+#endif // _SENDEBUG
+                if(hVal == headerFieldVal)
+                    {
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Header < Accept: %S > already exists"), &token));
+                    fieldValueExists = ETrue;
+                    }
+                }
+            }
+
+        // Add header field
+        if(!fieldValueExists)
+            {
+            aHeaders.SetFieldL(
+                iStringPool.StringF(HTTP::EAccept, 
+                                    RHTTPSession::GetTable()),
+                                    headerFieldVal);
+            TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Header < Accept: %S > added"), &token));
+
+            }
+
+        // Close stringpool string
+        CleanupStack::PopAndDestroy(); // acceptHeaderValue
+        }
+    tokens.ResetAndDestroy(); // TPtrC8 is allocated with "new" keyword and thus owned by this array, eventhough
+                              // the actual descriptors inside TPtrC8 tokens are NOT owned, of course (NORMAL).
+    CleanupStack::PopAndDestroy(); // token array
+    }
+
+/** Called when a authenticated page is requested
+Asks the user for a username and password that would be appropriate for the
+url that was supplied.
+*/
+TBool CSenHttpChannelImpl::GetCredentialsL(const TUriC8& aURI,
+                                           RString aRealm,
+                                           RStringF /*aAuthenticationType*/,
+                                           RString& aUsername,
+                                           RString& aPassword)
+
+    {
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("GetCredentialsL(),  for URL (%S), realm (%S)"),
+                            &aURI.UriDes(), &aRealm.DesC()));
+
+    if (iBasicConnectionTries > 2)
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() max number of tries with auth-dialog reached (3)");
+        // In the next attempt start with a fresh identityprovider
+        iSessionAuthentication = NULL;
+        iPasswordFromUser = EFalse;
+        iBasicConnectionTries = 0;
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() returning EFalse");
+        return EFalse;  // Invalid login attempts have reached the defined 
+                        // maximum, abort this request
+        }
+
+    if (!iSessionAuthentication)
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() reading auth-pair from database (senidentites.xml)");
+        iSessionAuthentication = iManager.IdentityProviderL(aURI.UriDes());
+        if(!iSessionAuthentication)
+            {
+            // create and register new IDP
+            iSessionAuthentication = CSenIdentityProvider::NewL(aURI.UriDes(),
+                                                                KNullDesC8);
+            iSessionAuthentication->SetFrameworkIdL(KNullDesC8); 
+            TInt retVal = iManager.RegisterIdentityProviderL(iSessionAuthentication);
+            if(retVal!=KErrNone)
+                {
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("GetCredentials: Register IDP failed! Error code: (%d)"),
+                    retVal));
+                iSessionAuthentication = NULL;
+                TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() returning EFalse");
+                return EFalse; // decision: we could not save info into database, abort
+                }
+            TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"New IDP registeration OK. Proceeding.");
+            }
+        // we have credentials
+        TRAPD(err, aUsername = 
+            aRealm.Pool().OpenStringL(iSessionAuthentication->AuthzID()));
+        TRAP(err, aPassword = 
+            aRealm.Pool().OpenStringL(iSessionAuthentication->Password()));
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() returning ETrue");
+        return ETrue;
+        }
+    else
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() prompting auth-info from user via dialog.");
+        // Remove the old password before asking the new one.
+        CSenElement& element = iSessionAuthentication->AsElement();
+        delete element.RemoveElement(KSenIdpPasswordLocalname);
+        
+        TPckgBuf<TSenAuthentication> authInfo;
+        iManager.AuthenticationForL(*iSessionAuthentication, authInfo);
+        iPasswordFromUser = ETrue;
+
+        TRAPD(err, aUsername = 
+                aRealm.Pool().OpenStringL(authInfo().iUsername));
+        TRAP(err, aPassword = 
+                aRealm.Pool().OpenStringL(authInfo().iPassword));
+        iBasicConnectionTries++;
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"GetCredentialsL() returning ETrue");
+        return ETrue;
+        }
+    }
+
+// This is a debug logging method:
+void CSenHttpChannelImpl::ListFilters()
+    {
+#ifdef _SENDEBUG
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"List HTTP filters started.");
+    TLSLOG(KSenHttpChannelLogChannelBase , KMaxLogLevel,(_L(
+    "      Name       | Pos'n | Event  |      Header      | Status | Handle ")
+    ));
+    TLSLOG(KSenHttpChannelLogChannelBase , KMaxLogLevel,(_L(
+    "-----------------+-------+--------+------------------+--------+--------")
+    ));
+
+    RHTTPFilterCollection filtColl = iSess.FilterCollection();
+    THTTPFilterIterator iter = filtColl.Query();
+
+    THTTPFilterRegistration regInfo;
+    iter.First();
+    TBuf<KMaxFilterNameLen> earlierName;
+    while (!iter.AtEnd())
+        {
+        // Get next filter registration info
+        regInfo = iter();
+
+        TBuf<KMaxFilterNameLen> name;
+        name.Copy(iSess.StringPool().StringF(regInfo.iName).DesC().Left(
+                                                        KMaxFilterNameLen));
+        TBuf<KMaxHeaderNameLen> header;
+        header.Copy(iSess.StringPool().StringF(regInfo.iHeader).DesC().Left(
+                                                        KMaxHeaderNameLen));
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMaxLogLevel, _L8("%16S | %4d  | %4d   | %16S |   %3d  | %2d"),
+               &name, regInfo.iPosition, regInfo.iEvent.iStatus, &header,
+                regInfo.iStatus, regInfo.iHandle));
+
+        earlierName.Format(name);
+        ++iter;
+        }
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMaxLogLevel,"List HTTP filters done.");
+#endif    
+    }
+
+void CSenHttpChannelImpl::HandleResponseHeadersL(RHTTPTransaction aTransaction)
+    {
+    TInt txnId = aTransaction.Id();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::HandleResponseHeadersL( %d )"),
+                        txnId));
+
+    RHTTPResponse resp = aTransaction.Response();
+    TInt status = resp.StatusCode();
+#ifdef _SENDEBUG
+    RStringF statusStr = resp.StatusText();
+    const TDesC8& statusStrDesC = statusStr.DesC();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Response status: %d ( %S )"), status, &statusStrDesC));
+#endif // _SENDEBUG
+    CSenTxnState* pTxnState = FindTxnState(txnId);
+
+    __ASSERT_ALWAYS(pTxnState != NULL, User::Panic(KTxnStateNullPanicText, CSenHttpChannel::ETxnStateNull));
+
+    if (status == 401)  // basic authentication needed
+        {
+        CSenHttpTransportProperties* tp = CSenHttpTransportProperties::NewLC();
+        RHTTPHeaders responseHeaders = aTransaction.Response().GetHeaderCollection();
+        THTTPHdrFieldIter fields = responseHeaders.Fields();
+        while (!fields.AtEnd())
+             {
+             RStringTokenF fieldName = fields();
+             RStringF fieldNameStr = iStringPool.StringF(fieldName);
+             THTTPHdrVal fieldVal;
+             if (responseHeaders.GetField(fieldNameStr,0,fieldVal) == KErrNone)
+                 {
+                  TPtrC8 ptr(KNullDesC8);
+                  responseHeaders.GetRawField(fieldNameStr, ptr);
+                  TPtrC8 ptr2(fieldNameStr.DesC());
+                  if (fieldVal.Type() == THTTPHdrVal::KDateVal)
+                      {
+                      TDateTime date = fieldVal.DateTime();
+                      RStringF dateS = iStringPool.StringF(HTTP::EDate, RHTTPSession::GetTable());
+                      TTimeIntervalMinutes interval;
+                      TTime begin(0);
+                      TTime time(date);
+                      time.MinutesFrom(begin, interval);
+                      tp->SetIntPropertyL(dateS.DesC(), interval.Int());
+                      pTxnState->SetTP(tp);//ownership transfered
+                      pTxnState->HttpChannelPropertiesL().SetIntPropertyL(dateS.DesC(), interval.Int());
+                      }
+                  }
+              ++fields;
+             }
+        CleanupStack::Pop(tp);
+        return;
+        }
+        
+    else if (status == 200)
+        {
+        RHTTPHeaders responseHeaders = aTransaction.Response().GetHeaderCollection();
+
+        THTTPHdrVal fieldVal;
+        TPtrC8 fieldValPtr;
+        THTTPHdrVal paramVal;
+            
+        // get the Content-Type string
+        RStringF content = iStringPool.StringF(HTTP::EContentType,
+                                               RHTTPSession::GetTable());
+
+        if (responseHeaders.GetField(content,0,fieldVal) == KErrNone)
+            {
+            // get the field value
+            switch (fieldVal.Type())
+                {
+                case THTTPHdrVal::KStrFVal:
+                    {
+                    fieldValPtr.Set(iStringPool.StringF(fieldVal.StrF()).DesC());
+                    }
+                break;
+                case THTTPHdrVal::KStrVal:
+                    {
+                    fieldValPtr.Set(iStringPool.String(fieldVal.Str()).DesC());
+                    }
+                break;
+                default:
+                    {
+                    User::Panic(KUnrecognisedValueTypeOfContentTypePanicText,
+                                EContentTypeUnrecognisedValueType);
+                    }
+                }
+            _LIT8(KMultipartRelated,"Multipart/Related");	//CodeScannerWarning
+            _LIT8(KBoundry,"boundary");
+            _LIT8(KType,"type");
+            _LIT8(KStart,"start");
+            _LIT8(KStartInfo,"start-info");
+            _LIT8(KAction,"action");
+            _LIT8(KApplication,"application/xop+xml");
+            if (fieldValPtr == KMultipartRelated)
+                {
+                //SenMultiPartUtils::TMultiPartContentType MultiPartContentType;
+                iMultiPartContentType.fieldValue.Set(fieldValPtr);
+
+                // get the param values
+                TPtrC8 paramName(KBoundry);
+                if(KErrNone == ContentTypeParamValueL(responseHeaders, content, paramName,  iMultiPartContentType))     
+                    {
+                    paramName.Set(KType);
+                    if (KErrNone == ContentTypeParamValueL(responseHeaders, content, paramName,  iMultiPartContentType))     
+                        {
+                        paramName.Set(KStart);
+                        if (KErrNone == ContentTypeParamValueL(responseHeaders, content, paramName,  iMultiPartContentType))     
+                            {
+                            paramName.Set(KStartInfo);
+                            if (KErrNone == ContentTypeParamValueL(responseHeaders, content, paramName,  iMultiPartContentType))     
+                                {
+                                paramName.Set(KAction);
+                                if (KErrSenNoHttpContentType == ContentTypeParamValueL(responseHeaders, content, paramName,  iMultiPartContentType))     
+                                    {
+                                    SenMultiPartUtils::TMultiPartContentTypeParam contentTypeParam = {_L8("action"), _L8("")};
+                                    iMultiPartContentType.params.Append(contentTypeParam);
+                                    }
+                                TUint i(0);
+                                while (iMultiPartContentType.params[i].paramName != KType)
+                                    {
+                                     ++i;
+                                    }
+                                if (iMultiPartContentType.params[i].paramValue == KApplication)   
+                                    {
+                                    iXopResponse = ETrue;
+                                    content.Close();
+                                    return;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+           else 
+                {
+                iContentType.Set(fieldValPtr);
+                content.Close();
+                return;
+                }
+            }
+        iHasHttpContentType = EFalse;
+        content.Close();
+        }
+    }
+
+TInt CSenHttpChannelImpl::ContentTypeParamValueL(const RHTTPHeaders& aResponseHeaders,
+                                const RStringF& aContent, 
+                                const TPtrC8& aParamName,
+                                SenMultiPartUtils::TMultiPartContentType& aMultiPartContentType)
+    {
+    RStringF paramNameStr = iStringPool.OpenFStringL(aParamName);            
+    
+    THTTPHdrVal paramVal;
+    TPtrC8 paramValPtr;
+    if (aResponseHeaders.GetParam(aContent,paramNameStr,paramVal) == KErrNone)
+        {
+        switch (paramVal.Type())
+            {
+            case THTTPHdrVal::KStrFVal:
+                {
+                paramValPtr.Set(iStringPool.StringF(paramVal.StrF()).DesC());
+                }
+            break;
+            case THTTPHdrVal::KStrVal:
+                {
+                paramValPtr.Set(iStringPool.String(paramVal.Str()).DesC());
+                }
+            break;
+            default:
+                User::Panic(KUnrecognisedValueTypeOfContentTypePanicText,
+                            EContentTypeUnrecognisedValueType);
+            break;
+            }
+
+        SenMultiPartUtils::TMultiPartContentTypeParam contentTypeParam = {_L8(""), _L8("")};
+        contentTypeParam.paramName.Set(aParamName);
+        contentTypeParam.paramValue.Set(paramValPtr);
+        aMultiPartContentType.params.Append(contentTypeParam);
+        paramNameStr.Close();
+        return KErrNone;
+        }
+    else
+        {
+        paramNameStr.Close();
+        return KErrSenNoHttpContentType;
+        }
+    }
+
+void CSenHttpChannelImpl::HandleResponseBodyDataL(RHTTPTransaction aTransaction)
+    {
+    TInt txnId = aTransaction.Id();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::HandleResponseBodyDataL( %d )"), txnId));
+
+    CSenTxnState* pTxnState = FindTxnState(txnId);
+    __ASSERT_ALWAYS(pTxnState != NULL,
+                    User::Panic(KTxnStateNullPanicText,
+                    CSenHttpChannel::ETxnStateNull));
+
+    // Get the body data supplier
+    MHTTPDataSupplier* pRespBody = aTransaction.Response().Body();
+
+    if(pRespBody)
+        {
+        TPtrC8 dataChunk;
+#ifdef _SENDEBUG
+        TBool isLast = pRespBody->GetNextDataPart(dataChunk);
+        if (isLast)
+            TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("Got last data chunk.")));
+#else
+        pRespBody->GetNextDataPart(dataChunk);
+#endif // _SENDEBUG
+        
+        if (!iXopResponse)
+            {
+            pTxnState->CollectResponseBodyL(dataChunk);
+            }
+        else
+            {
+            ((CSenMtomTxnState*)pTxnState)->ParseMultiPartResponseL(dataChunk);
+            }
+
+
+        // Done with that bit of body data
+        pRespBody->ReleaseData();
+        }
+    else
+        {
+        //pTxnState->ResponseError(-20000);
+        pTxnState->ResponseErrorL(KErrSenNoHttpResponseBody); //SenServiceConnection.h // was -20000
+        DeleteTxnState(txnId);
+        aTransaction.Close();
+        }
+    }
+
+void CSenHttpChannelImpl::HandleResponseL(RHTTPTransaction aTransaction)
+    {
+    TInt txnId = aTransaction.Id();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::HandleResponseL( %d )"), txnId));
+    CSenTxnState* pTxnState = FindTxnState(txnId);
+    __ASSERT_ALWAYS(pTxnState != NULL,
+                    User::Panic(KTxnStateNullPanicText,
+                    CSenHttpChannel::ETxnStateNull));
+
+    // Propagate http status codes                                    
+    RHTTPResponse resp = aTransaction.Response();
+    TInt status = resp.StatusCode();
+    pTxnState->StateChanged(status);    
+                                           
+    if (iHasHttpContentType)
+        {
+         if (!iXopResponse)
+            {
+            pTxnState->ResponseReceivedL(iContentType);
+            }
+        else
+            {
+            ((CSenMtomTxnState*)pTxnState)->ResponseReceivedL(iMultiPartContentType);
+            }
+        }
+    else
+        {
+        pTxnState->ResponseErrorL(KErrSenNoHttpContentType); // was: -20001
+        }
+
+    DeleteTxnState(txnId);
+    aTransaction.Close();
+    }
+
+void CSenHttpChannelImpl::HandleRunErrorL(RHTTPTransaction aTransaction,
+                                          TInt aError)
+    {
+    TInt txnId = aTransaction.Id();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::HandleRunErrorL( %d ): %d"),txnId, aError));
+    CSenTxnState* pTxnState = FindTxnState(txnId);
+    __ASSERT_ALWAYS(pTxnState != NULL,
+                    User::Panic(KTxnStateNullPanicText,
+                    CSenHttpChannel::ETxnStateNull));
+
+    pTxnState->ResponseErrorL(aError);
+    DeleteTxnState(txnId);
+    aTransaction.Close();
+    }
+
+void CSenHttpChannelImpl::HandleRedirectRequiresConfirmationL(
+                                                RHTTPTransaction aTransaction)
+    {
+    TInt txnId = aTransaction.Id();
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::HandleRedirectRequiresConfirmationL( %d )"),
+                txnId));
+    CSenTxnState* pTxnState = FindTxnState(txnId);
+    __ASSERT_ALWAYS(pTxnState != NULL,
+                    User::Panic(KTxnStateNullPanicText,
+                    CSenHttpChannel::ETxnStateNull));
+    pTxnState->ResponseErrorL(KErrSenHttpRedirectRequiresConfirmation); // was: -20002
+    DeleteTxnState(txnId);
+    aTransaction.Close();
+    }
+/*
+RFileLogger* CSenHttpChannelImpl::Log() const
+    {
+    return (RFileLogger*) &iLog;
+    }
+*/
+// This is a debug logging method
+#ifdef _SENDEBUG
+void CSenHttpChannelImpl::DumpRespHeadersL(RHTTPTransaction& aTrans)
+    {
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::DumpRespHeadersL")));
+    RHTTPResponse resp = aTrans.Response();
+    RHTTPHeaders hdr = resp.GetHeaderCollection();
+    THTTPHdrFieldIter it = hdr.Fields();
+
+    TBuf<KMaxHeaderNameLen>  fieldName16;
+    TBuf<KMaxHeaderValueLen> fieldVal16;
+    TBuf<KMaxHeaderNameLen>  paramName16;
+    TBuf<KMaxHeaderValueLen> paramVal16;
+
+    while (!it.AtEnd())
+        {
+        RStringTokenF fieldName = it();
+        RStringF fieldNameStr = iStringPool.StringF(fieldName);
+        THTTPHdrVal fieldVal;
+        THTTPHdrVal paramVal;
+        if (hdr.GetField(fieldNameStr,0,fieldVal) == KErrNone)
+            {
+            const TDesC8& fieldNameDesC = fieldNameStr.DesC();
+            fieldName16.Copy(fieldNameDesC.Left(KMaxHeaderNameLen));
+            switch (fieldVal.Type())
+                {
+            case THTTPHdrVal::KTIntVal:
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %d"), &fieldName16, fieldVal.Int()));
+                break;
+            case THTTPHdrVal::KStrFVal:
+                {
+                RStringF fieldValStr = iStringPool.StringF(fieldVal.StrF());
+                const TDesC8& fieldValDesC = fieldValStr.DesC();
+                fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %S"), &fieldName16, &fieldVal16));
+                }
+                break;
+            case THTTPHdrVal::KStrVal:
+                {
+                RString fieldValStr = iStringPool.String(fieldVal.Str());
+                const TDesC8& fieldValDesC = fieldValStr.DesC();
+                fieldVal16.Copy(fieldValDesC.Left(KMaxHeaderValueLen));
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %S"), &fieldName16, &fieldVal16));
+                }
+                break;
+            case THTTPHdrVal::KDateVal:
+                {
+                TDateTime date = fieldVal.DateTime();
+                TBuf<40> dateTimeString;
+                TTime t(date);
+                t.FormatL(dateTimeString,KDateFormat);
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %S"), &fieldName16, &dateTimeString));
+
+                }
+                break;
+            default:
+                TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: <unrecognised value type>"), &fieldName16));
+            break;
+            }
+            
+        RStringF paramNameStr = iStringPool.OpenFStringL(_L8("type"));            
+        const TDesC8& paramNameDesC = paramNameStr.DesC();
+        paramName16.Copy(paramNameDesC.Left(KMaxHeaderNameLen));
+        if (hdr.GetParam(fieldNameStr,paramNameStr,paramVal) == KErrNone)
+            {
+            switch (paramVal.Type())
+                {
+                case THTTPHdrVal::KStrFVal:
+                    {
+                    RStringF paramValStr = iStringPool.StringF(paramVal.StrF());
+                    const TDesC8& paramValDesC = paramValStr.DesC();
+                    paramVal16.Copy(paramValDesC.Left(KMaxHeaderValueLen));
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %S"), &paramName16, &paramVal16));
+                    }
+                break;
+                case THTTPHdrVal::KStrVal:
+                    {
+                    RString paramValStr = iStringPool.String(paramVal.Str());
+                    const TDesC8& paramValDesC = paramValStr.DesC();
+                    paramVal16.Copy(paramValDesC.Left(KMaxHeaderValueLen));
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: %S"), &paramName16, &paramVal16));
+                    }
+                break;
+                default:
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: <unrecognised value type>"), &paramName16));
+                break;
+                }
+            }
+		_LIT(KMultipartRelated,"Multipart/Related");
+		_LIT(KApplication,"application/xop+xml");
+        if ((fieldVal16 == KMultipartRelated) && (paramVal16 == KApplication))
+            {
+            iXopResponse = ETrue;    
+            }
+            
+            // Display realm for WWW-Authenticate header
+            RStringF wwwAuth =
+                iStringPool.StringF(
+                    HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
+            if (fieldNameStr == wwwAuth)
+                {
+                // check the auth scheme is 'basic'
+                RStringF basic =
+                    iStringPool.StringF(HTTP::EBasic,RHTTPSession::GetTable());
+                RStringF realm =
+                    iStringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable());
+                THTTPHdrVal realmVal;
+                if ((fieldVal.StrF() == basic) &&
+                    (!hdr.GetParam(wwwAuth, realm, realmVal)))
+                    {
+                    RStringF realmValStr =
+                        iStringPool.StringF(realmVal.StrF());
+                    const TDesC8& realmValDesC = realmValStr.DesC();
+                    fieldVal16.Copy(realmValDesC.Left(KMaxHeaderValueLen));
+                    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("Realm is: %S"), &fieldVal16));
+                    }
+                }
+            paramNameStr.Close();
+            }
+        ++it;
+        }
+    }
+#else
+// do nothing
+void CSenHttpChannelImpl::DumpRespHeadersL(RHTTPTransaction& /* aTrans */) {  } 
+#endif
+
+
+// This is second debug logging method
+//Do a formatted dump of binary data
+#ifdef _SENDEBUG
+void CSenHttpChannelImpl::DumpBodyData(const TDesC8& aData)
+    {
+    // Iterate the supplied block of data in blocks of cols=80 bytes
+    const TInt cols=16;
+    TInt pos = 0;
+    TBuf<KMaxFileName - 2> logLine;
+    TBuf<KMaxFileName - 2> anEntry;
+    const TInt dataLength = aData.Length();
+    while (pos < dataLength)
+        {
+        //start-line hexadecimal( a 4 digit number)
+        anEntry.Format(TRefByValue<const TDesC>_L("%04x : "), pos);
+        logLine.Append(anEntry);
+
+        // Hex output
+        TInt offset;
+        for (offset = 0; offset < cols; ++offset)
+            {
+            if (pos + offset < aData.Length())
+                {
+                TInt nextByte = aData[pos + offset];
+                anEntry.Format(TRefByValue<const TDesC>_L("%02x "), nextByte);
+                logLine.Append(anEntry);
+                }
+            else
+                {
+                // fill the remaining spaces with
+                // blanks untill the cols-th Hex number
+                anEntry.Format(TRefByValue<const TDesC>_L("   "));
+                logLine.Append(anEntry);
+                }
+            }
+        anEntry.Format(TRefByValue<const TDesC>_L(": "));
+        logLine.Append(anEntry);
+
+        // Char output
+        for (offset = 0; offset < cols; ++offset)
+            {
+            if (pos + offset < aData.Length())
+                {
+                TInt nextByte = aData[pos + offset];
+                if ((nextByte >= ' ') && (nextByte <= '~'))
+                    {
+                    anEntry.Format(TRefByValue<const TDesC>_L("%c"), nextByte);
+                    logLine.Append(anEntry);
+                    }
+                else
+                    {
+                    anEntry.Format(TRefByValue<const TDesC>_L("."));
+                    logLine.Append(anEntry);
+                    }
+                }
+            else
+                {
+                anEntry.Format(TRefByValue<const TDesC>_L(" "));
+                logLine.Append(anEntry);
+                }
+            }
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, TRefByValue<const TDesC>_L("%S"), &logLine));
+            logLine.Zero();
+
+        // Advance to next  byte segment (1 seg= cols)
+        pos += cols;
+        }
+    }
+#else
+// do nothing
+void CSenHttpChannelImpl::DumpBodyData(const TDesC8& /* aData */) { } 
+#endif
+
+// ----------------------------------------------------------------------------
+// CSenHttpChannelImpl::AppendNewTxnStateL
+// ----------------------------------------------------------------------------
+//
+void CSenHttpChannelImpl::AppendNewTxnStateL(CSenTxnState* aTxnState)
+    {
+    TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::AppendNewTxnStateL")));
+    iTxnStates->AppendL(aTxnState);
+    }
+
+// ----------------------------------------------------------------------------
+// CSenHttpChannelImpl::DeleteTxnState
+// ----------------------------------------------------------------------------
+void CSenHttpChannelImpl::DeleteTxnState(TInt aTxnId)
+    {
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::DeleteTxnState( %d )"), aTxnId));
+    TInt index;
+    CSenTxnState* pTxnState = FindTxnState(aTxnId, &index);
+    if(pTxnState)
+        {
+        iTxnStates->Delete(index);
+        delete pTxnState;
+        pTxnState = NULL;
+        TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("TxnState ( %d ) deleted"), aTxnId));
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CSenHttpChannelImpl::FindTxnState
+// ----------------------------------------------------------------------------
+CSenTxnState* CSenHttpChannelImpl::FindTxnState(TInt aTxnId, TInt* aIndex)
+    {
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::FindTxnState( %d )"), aTxnId));
+    for(TInt i = 0; i < iTxnStates->Count(); ++i)
+        {
+        if((*iTxnStates)[i]->Id() == aTxnId)
+            {
+            if(aIndex)
+                {
+                *aIndex = i;
+                }
+            return (*iTxnStates)[i];
+            }
+        }
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("TxnState ( %d ) not found"), aTxnId));
+    return NULL;
+    }
+
+
+// @return KErrNone, if cancel was performed
+//        KErrNotFound if transaction was not found 
+TInt CSenHttpChannelImpl::CancelTransaction(const TInt aTxnId)
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KSenHttpChannelLogLevel,"");
+    TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::CancelTransaction - TxnId: %d"),
+        aTxnId));
+
+    CSenTxnState* pTxnState = FindTxnState(aTxnId);
+    if(pTxnState)
+        {
+        TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- Txn found, calling Cancel():");
+        return pTxnState->Cancel();
+        }
+    return KErrNotFound;
+    }
+
+void CSenHttpChannelImpl::CancelAllTransactions()
+    {
+    TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::CancelAllTransaction");
+    
+    for(TInt i = 0; i < iTxnStates->Count(); ++i)
+        {
+        (*iTxnStates)[i]->Cancel();
+        }
+    }
+
+void CSenHttpChannelImpl::SetExplicitIapDefined(TBool aExplicitIapDefined)
+    {
+    iExplicitIapDefined = aExplicitIapDefined;
+    }
+
+
+TBool CSenHttpChannelImpl::EffectiveIapId( TUint32 &aIapId )
+    {
+	TInt handle = iConnection.SubSessionHandle();
+		if (handle>0)
+	    {
+        TUint connEnum(0);
+        TInt err = iConnection.EnumerateConnections(connEnum);
+        if (!err && !connEnum)
+            {
+            return EFalse;
+            }
+	    }
+
+	TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::EffectiveIapId(): Current RConnection's subsession handle(%d)"), iIapId ));
+#ifdef _SENDEBUG
+	if( iExplicitIapDefined )
+		{
+		TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8(" - IAP ID is known: %d"), iIapId ));
+		}
+	else
+		{
+		TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel," - IAP ID is not known.");
+		}
+		
+	if( handle < KErrNone )
+		{
+		TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel," -> RConnection has not been initialized.");
+		}
+#endif // _SENDEBUG    
+    
+    if( handle && !iExplicitIapDefined )
+    	{
+		// Eventhough IAP was not explicitely set (through Serene API), this
+		// code can check what IAP end-user provided via IAP selection dialog:
+		TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"CSenHttpChannelImpl::EffectiveIapId: about to call RConnection::GetIntSetting()");
+		_LIT( KIapIdKey, "IAP\\Id" );
+	    iConnection.GetIntSetting( KIapIdKey, iIapId);
+	    if ( iIapId > 0 )
+	    	{
+			TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::EffectiveIapId(): end-user provided IAP(%d)"), iIapId ));
+	    	// Treat the end-user selection as "explicit" definition as well(!):
+	    	iExplicitIapDefined = ETrue; 
+	    	}
+	    }
+    if( iExplicitIapDefined )
+        {
+        aIapId = iIapId;
+        }
+    return iExplicitIapDefined;
+    }
+
+void CSenHttpChannelImpl::EnableTimeOutL(TInt aTxnId, TInt aTimeOutSec)
+    {
+    CSenTxnState* txn = FindTxnState(aTxnId);
+    if (txn)
+        txn->EnableTimeOutL(aTimeOutSec);
+    }
+void CSenHttpChannelImpl::DisableTimeOutL(TInt aTxnId)
+    {
+    CSenTxnState* txn = FindTxnState(aTxnId);
+    if (txn)
+        txn->DisableTimeOutL();
+    }
+
+TInt32 CSenHttpChannelImpl::UsedIap()
+    {
+    return iUsedIapId;
+    }
+// END OF FILE
+
+