diff -r 000000000000 -r 62f9d29f7211 webservices/wshttpchanneltransportplugin/src/senhttpchannelimpl.cpp --- /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 +#include +#include +#include + +#include "sendebug.h" // filelogging and debugging MACROS +#include // KErrSenNoHttpResponseBody +#include +#include +#include +#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 +#include +#include +#include + +// 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(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 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 headersArray; + retVal = aProps.HttpHeadersL(headersArray); + if ( retVal == KErrNone ) + { + CleanupClosePushL(headersArray); + headerCount = headersArray.Count(); + for(TInt i=0; iName(); + + // 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 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 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 earlierName; + while (!iter.AtEnd()) + { + // Get next filter registration info + regInfo = iter(); + + TBuf name; + name.Copy(iSess.StringPool().StringF(regInfo.iName).DesC().Left( + KMaxFilterNameLen)); + TBuf 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 fieldName16; + TBuf fieldVal16; + TBuf paramName16; + TBuf 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: "), &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: "), ¶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 logLine; + TBuf anEntry; + const TInt dataLength = aData.Length(); + while (pos < dataLength) + { + //start-line hexadecimal( a 4 digit number) + anEntry.Format(TRefByValue_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_L("%02x "), nextByte); + logLine.Append(anEntry); + } + else + { + // fill the remaining spaces with + // blanks untill the cols-th Hex number + anEntry.Format(TRefByValue_L(" ")); + logLine.Append(anEntry); + } + } + anEntry.Format(TRefByValue_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_L("%c"), nextByte); + logLine.Append(anEntry); + } + else + { + anEntry.Format(TRefByValue_L(".")); + logLine.Append(anEntry); + } + } + else + { + anEntry.Format(TRefByValue_L(" ")); + logLine.Append(anEntry); + } + } + TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, TRefByValue_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 + +