/*
* 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>
#ifndef __ENABLE_ALR__
#include <versioninfo.h> // VersionInfo
#include <extendedconnpref.h>
#endif
// 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)
#ifndef __ENABLE_ALR__
, iOCCenabled(EFalse)
#endif
{
// IsOCCImplementedSDK();
}
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;
}
#ifndef __ENABLE_ALR__
// On return, aMajor and aMinor contain the version information
TInt CSenHttpChannelImpl::GetS60PlatformVersion(TUint& aMajor, TUint& aMinor)
{
TInt ret = KErrNone;
// Connect to the file server session
RFs fsSession;
TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::GetS60PlatformVersion()")));
ret = fsSession.Connect();
if(ret == KErrNone)
{
CleanupClosePushL(fsSession); // Obtain the version numberTUint major;
VersionInfo::TPlatformVersion platformVersion;
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "--- GetS60PlatformVersion getting Version info");
ret = VersionInfo::GetVersion(platformVersion, fsSession);
CleanupStack::PopAndDestroy(); // fsSession
if (ret == KErrNone)
{
aMajor = platformVersion.iMajorVersion;
aMinor = platformVersion.iMinorVersion;
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("--- GetS60PlatformVersion Version: Major [%d], Minor[%d]"), aMajor, aMinor));
}
}
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("--- GetS60PlatformVersion returns [%d]"), ret));
return ret;
}
// On return, aMajor and aMinor contain the version information
TBool CSenHttpChannelImpl::IsOCCImplementedSDK()
{
TBool occ = EFalse;
// Obtain the version number
TUint major;
TUint minor;
TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::IsOCCImplementedSDK()")));
TInt ret = GetS60PlatformVersion(major, minor);
if (ret == KErrNone)
{
if(major == 5 && minor == 2)
{
occ = ETrue;
iOCCenabled = ETrue;
TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("---- IsOCCImplementedSDK() returns TRUE")));
}
else
{
TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("---- IsOCCImplementedSDK() returns False")));
}
}
return occ;
}
#endif
// 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;
#ifndef __ENABLE_ALR__
IsOCCImplementedSDK();
#endif
#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);
#ifndef __ENABLE_ALR__
IsOCCImplementedSDK();
#endif
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);
}
TInt CSenHttpChannelImpl::SetIapPrefsL( TUint32 aIapId, TBool aDialogPref, RConnection& aConnection, RSocketServ& aSocketServer )
{
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _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)
TInt retVal = SetID(aIapId, aDialogPref, aConnection, aSocketServer);
// 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));
return retVal;
}
TInt CSenHttpChannelImpl::SetID(TUint32 aId, TBool aDialogPref, RConnection& aConnection, RSocketServ& aSocketServer, TBool aSNAP)
{
/*
* 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
*/
TInt retVal = KErrNone;
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl called with ID [%d]"), aId));
#ifndef __ENABLE_ALR__
if (iOCCenabled == EFalse)
{
#endif
if (aSNAP == EFalse)
{
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- SetIAPID");
TCommDbConnPref pref;
pref.SetIapId( aId );
TCommDbDialogPref dialogPref;
if (aDialogPref)
{
dialogPref = ECommDbDialogPrefDoNotPrompt;
}
else
{
dialogPref = ECommDbDialogPrefPrompt;
}
pref.SetDialogPreference(dialogPref);
retVal = aConnection.Start(pref);
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("RConnection->Start retVal [%d]"), retVal));
}
else
{
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- SetSNAPID");
// Set the SNAP selection preferences (SNAP ID)
TConnSnapPref pref;
pref.SetSnap(aId);
// Start the connection with the new preferences
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel,"- SetSnapPrefsL: Calling RConnection::Start with new SNAP prefs");
TInt retVal = aConnection.Start(pref);
}
#ifndef __ENABLE_ALR__
}
else
{
if (aSNAP == EFalse)
{
/* If IAP id is zero, it is interpreted as
* client's request for not requesting any specific IAP.
* Default value is 0.
*
* If IAP id is set, SNAP id shall be zero.
* If IAP id is set, SNAP purpose shall be CMManager::ESnapPurposeUnknown.
* If IAP id is set, Connection selection dialog shall be disabled.
* If IAP id is set, bearer set shall be EExtendedConnBearerUnknown.
* If IAP id is set, forced roaming is disabled automatically.
* Either SNAP purpose, SNAP id, or IAP id shall be given, or Connection
* selection dialog shall be enabled.
*/
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- Setting up OCC with IAP Settings");
TConnPrefList prefList;
TExtendedConnPref extPrefs;
//extPrefs.SetSnapPurpose( CMManager::ESnapPurposeUnknown);
//TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- Setting up OCC Silent Connection");
//extPrefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourConnSilent);
//extPrefs.SetBearerSet(TExtendedConnBearer::EExtendedConnBearerUnknown);
extPrefs.SetIapId(aId);
extPrefs.SetSnapId(0);
prefList.AppendL(&extPrefs);
retVal = aConnection.Start(prefList);
if(retVal == KErrNone)
{
iIapId = aId;
}
else
{
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("IAP ->Start retVal [%d]"), retVal));
}
}
else
{
/**
* Sets SNAP id. If SNAP id is zero, it is interpreted as
* client's request for not requesting any specific SNAP.
* Default value is 0.
*
* If SNAP id is set, IAP id shall be zero.
* If SNAP id is set, SNAP purpose shall be CMManager::ESnapPurposeUnknown.
* If SNAP id is set, Connection selection dialog shall be disabled.
* Either SNAP purpose, SNAP id, or IAP id shall be given, or Connection
* selection dialog shall be enabled.
*/
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- Setting up OCC with SNAP Settings");
TConnPrefList prefList;
TExtendedConnPref extPrefs;
//extPrefs.SetSnapPurpose( CMManager::ESnapPurposeUnknown);
//TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- Setting up OCC Silent Connection");
//extPrefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourConnSilent);
//extPrefs.SetBearerSet(TExtendedConnBearer::EExtendedConnBearerUnknown);
if(aId == 0)
{
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel, "- Setting SnapPurpose Internet");
if(aDialogPref) //If it fails because of unavailibility of access points
{
extPrefs.SetSnapPurpose(CMManager::ESnapPurposeUnknown);
extPrefs.SetConnSelectionDialog(ETrue);
}
else
{
extPrefs.SetSnapPurpose(CMManager::ESnapPurposeInternet);
//extPrefs.SetNoteBehaviour(TExtendedConnPref::ENoteBehaviourConnSilent);
}
}
else
{
extPrefs.SetSnapId(aId);
extPrefs.SetIapId(0);
extPrefs.SetSnapPurpose(CMManager::ESnapPurposeUnknown);
extPrefs.SetConnSelectionDialog(EFalse);
}
prefList.AppendL(&extPrefs);
retVal = aConnection.Start(prefList);
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("RConnection Start retval[%d]"), retVal));
if(retVal == KErrNone)
{
aConnection.GetIntSetting( _L("IAP\\Id"), iIapId);
TName name;
retVal = aConnection.Name(name);
if(retVal == KErrNone)
{
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("IAP Name [%S]"), &name));
}
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("GetIntSetting returned IAP [%d]"), iIapId));
}
else
{
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("SNAP ->Start retVal [%d]"), retVal));
}
}
}
#endif
if (!retVal)
{
iExplicitIapDefined = ETrue;
}
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, do not prompt)
TInt retVal = SetID(aSnapId, aDialogPref, aConnection, aSocketServer, ETrue);
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 id(KErrNone);
TBool prompt(ETrue);
TInt retVal = aProps.IAPDialogL( prompt );
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
prompt = ETrue;
}
#ifndef __ENABLE_ALR__
// Independent of dialog preference (property's existance), if IAP was predefined, it must be set
if(((aProps.IapIdL(id)) == KErrNone))
{
retVal = SetIapPrefsL(id, prompt, iConnection, iSockServ);
}
else if(((aProps.SnapIdL(id)) == KErrNone))
{
retVal = SetSnapPrefsL(id, prompt, iConnection, iSockServ);
}
else//to better control RConnection, we have to call Start by ourselve
{
retVal = SetSnapPrefsL(0, EFalse, iConnection, iSockServ);
if(retVal == KErrNotFound)
{
if(iOCCenabled == EFalse)
{
retVal = SetIapPrefsL(0, EFalse, iConnection, iSockServ);
}
else
{
retVal = SetSnapPrefsL(0, prompt, 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
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("IAP/SNAP %d"), id));
#else
retVal = SetIapPrefsL(id, prompt, iConnection, iSockServ);
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("IAP/SNAP %d"), id));
iUsedIapId = id;
#endif
CSenLayeredHttpTransportProperties::TSenHttpMethod httpMethod;
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("PROMPT %d"), prompt));
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 )
{
TLSLOG(KSenHttpChannelLogChannelBase , KMinLogLevel,(_L("CSenHttpChannelImpl::AddRequestHeadersL Default Token")));
TPtrC8* pDefaultToken = new (ELeave) TPtrC8( KSenHttpChannelAcceptHeaderDefault );
TInt error = tokens.Append( pDefaultToken );
if ( error )
{
delete pDefaultToken;
pDefaultToken = NULL;
}
}
// 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)
{
TLSLOG_FORMAT((KSenHttpChannelLogChannelBase , KMinLogLevel, _L8("CSenHttpChannelImpl::EffectiveIapId(): Current RConnection's subsession handle(%d)"), handle ));
TUint connEnum(0);
TInt err = iConnection.EnumerateConnections(connEnum);
if (!err && !connEnum)
{
return EFalse;
}
}
else
{
TLSLOG_L(KSenHttpChannelLogChannelBase , KMinLogLevel," -> RConnection has not been initialized.");
}
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 && !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("---- GetIntSetting(): retuens 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