--- /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"), ¶mName16, ¶mVal16));
+ }
+ 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"), ¶mName16, ¶mVal16));
+ }
+ break;
+ default:
+ TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("%S: <unrecognised value type>"), ¶mName16));
+ 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
+
+