diff -r 000000000000 -r b497e44ab2fc syncmlfw/common/http/src/nsmlhttp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/syncmlfw/common/http/src/nsmlhttp.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,1184 @@ +/* +* 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: SyncML HTTP client +* +*/ + + +#include "nsmlhttp.h" +#include "nsmlhttpclient.h" +#include +#include +#include +#include "nsmlprivatepskeys.h" + + +#include "nsmlerror.h" +#ifdef __NSML_DEBUG__ +#include "wbxml2xmlconverter.h" +#endif // __NSML_DEBUG__ + +#include +#include +#include "PMUtilInternalCRKeys.h" +#include "nsmlhttpPrivateCRKeys.h" +#include +#include +#include + +#ifndef __WINS__ +// This lowers the unnecessary compiler warning (armv5) to remark. +// "Warning: #174-D: expression has no effect..." is caused by +// DBG_ARGS8 macro in no-debug builds. +#pragma diag_remark 174 +#endif +#include + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CNSmlHTTP* CNSmlHTTP::NewL() + { + CNSmlHTTP* self = new (ELeave) CNSmlHTTP(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::CNSmlHTTP() +// constructor +// ----------------------------------------------------------------------------- +// +CNSmlHTTP::CNSmlHTTP() +: CActive( EPriorityStandard ), iReqBodySubmitBufferPtr( 0,0 ) + { + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::ConstructL() +// 2-phase constructor +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::ConstructL() + { + // construct shutdown timer + DBG_FILE(_S8("CNSmlHTTP::ConstructL BEGIN")); + FeatureManager::InitializeLibL(); + iShutdown = new (ELeave) CNSmlXptShutdownTimer( this ); + iShutdown->ConstructL(); + iNetworkStatusEngine = NULL; + // do this only if session is DM + TInt session=0; + TInt r=RProperty::Get( KPSUidNSmlSOSServerKey, KNSmlSyncJobOngoing, session); + DBG_FILE_CODE(session, _S8("CNSmlHTTP::ConstructL Current Session is (DM = 2, DS = 1) ")); + if( session == ESyncMLDMSession )//for dm session + { + TInt dmsessionTimeout = -1; + CRepository *rep = NULL; + TRAPD( err1, rep = CRepository::NewL( KCRUidDeviceManagementInternalKeys )) + DBG_FILE_CODE(err1, _S8("CNSmlHTTP::ConstructL cenrep read error code ")); + if(err1 == KErrNone) + { + rep->Get( KDevManDMSessionTimeout, dmsessionTimeout ); + delete rep; + DBG_FILE_CODE(dmsessionTimeout, _S8("CNSmlHTTP::ContructL, DMSessiontimeout feature value from cenrep")); + if( dmsessionTimeout > KNSmlDMMaxSessionTimeout || dmsessionTimeout < KNSmlDMMinSessionTimeout) + { + dmsessionTimeout = -1; + } + DBG_FILE_CODE(dmsessionTimeout, _S8("CNSmlHTTP::ContructL, DMSessiontimeout feature value ")); + } + if(dmsessionTimeout != -1) + { + iNetworkStatusEngine = new (ELeave) CNsmlNetworkStatusEngine( this ); + iNetworkStatusEngine->ConstructL(); + iNetworkStatusEngine->NotifyL(); + } + } + + iPreemptRequest = 0; + + iServerContentEncoding = ExptNone; + iServerAcceptEncoding = ExptNone; + iSession = ESyncMLSessionUnknown; + RProperty::Get( KPSUidNSmlSOSServerKey, KNSmlSyncJobOngoing, iSession); + // construct dialup agent + iDialUpAgent = new (ELeave) CNSmlDialUpAgent(); + iDialUpAgent->ConstructL(); + + iEngineState = ExptIdle; + iTimeOut = EFalse; + iLastPart = EFalse; + iAuthRetryCount=0; + iAuthUsed=0; + + iTransObs = CHttpEventHandler::NewL(); + iTransObs->ConstructL( this ); + iMaxMsgSize = KNSmlDefaultWorkspaceSize; + + if( iSession == ESyncMLDSSession ) + { + TInt value(0); + TRAPD( err, ReadRepositoryL( KNSmlMaxMsgSizeKey, value) ); + if ( err == KErrNone ) + { + iMaxMsgSize = value; + } + } + } + +// --------------------------------------------------------- +// CNSmlHTTP::ReadRepositoryL(TInt aKey, TInt& aValue) +// +// --------------------------------------------------------- +TInt CNSmlHTTP::ReadRepositoryL(TInt aKey, TInt& aValue) + { + const TUid KRepositoryId = KCRUidNSmlDSEngine; + + CRepository* rep = CRepository::NewLC(KRepositoryId); + TInt err = rep->Get(aKey, aValue); + CleanupStack::PopAndDestroy(rep); + + return err; + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::~CNSmlHTTP() +// desctructor +// ----------------------------------------------------------------------------- +// +CNSmlHTTP::~CNSmlHTTP() + { +DBG_FILE(_S8("CNSmlHTTP::~CNSmlHTTP() BEGIN")); +if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement)) +{ + DeleteCertificate(); +} + + Cancel(); + delete iData; + delete iReqBodySubmitBuffer; + delete iURI; + delete iMimeType; + delete iHTTPusername; + delete iHTTPpassword; + delete iShutdown; + iShutdown = NULL; + if(iNetworkStatusEngine) + { + delete iNetworkStatusEngine; + iNetworkStatusEngine = NULL; + } + iSess.Close(); + delete iTransObs; + delete iDialUpAgent; + delete iIAPidArray; + FeatureManager::UnInitializeLib(); + DBG_FILE(_S8("CNSmlHTTP::~CNSmlHTTP() END")); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::DoCancel() +// DoCancel() from CActive +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::DoCancel() + {DBG_FILE(_S8("CNSmlHTTP::DoCancel() BEGIN")); + iEngineState = ExptIdle; + TInt cancelReason; + + iShutdown->Cancel(); + iDialUpAgent->Cancel(); + iSess.Close(); + + if( iTimeOut ) + {DBG_FILE(_S8("CNSmlHTTP::DoCancel() timing out")); + cancelReason = TNSmlHTTPErrCode::ENSmlHTTPErr_RequestTimeout; + } + else + { + cancelReason = KErrCancel; + } + // signal current (engine) thread request semaphore that this AO's + // request has completed + TRequestStatus* status = &iStatus; + User::RequestComplete( status, cancelReason ); + // signal agent + TRequestStatus* agentStatus = iAgentStatus; + User::RequestComplete( agentStatus, cancelReason ); + DBG_FILE(_S8("CNSmlHTTP::DoCancel() END")); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::CompleteRequest() +// called when asynchronous request should be completed with a purpose +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::CompleteRequest() +{ + DBG_FILE(_S8("CNSmlHTTP::CompleteRequest BEGIN")); + + if(IsActive()) + { + DBG_FILE(_S8("CNSmlHTTP::CompleteRequest iTrans.Cancel();")); + iTrans.Cancel(); + DBG_FILE(_S8("CNSmlHTTP::CompleteRequest iTrans.Close();")); + iTrans.Close(); + DBG_FILE(_S8("CNSmlHTTP::CompleteRequest isActive returned TRUE ")); + iPreemptRequest++; + DBG_FILE_CODE( iPreemptRequest, _S8("Increasing value of iPreemptRequest ") ); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrTimedOut ); + } + + DBG_FILE(_S8("CNSmlHTTP::CompleteRequest ENDS ")); +} +// CNSmlHTTP::RunL() +// Runl() from CActive +// called when asynchronous request completed +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::RunL() + { + DBG_FILE(_S8("CNSmlHTTP::RunL begins")); + + DBG_FILE_CODE( iEngineState, _S8("RunL iEgnineStatus is : ") ); + DBG_FILE_CODE( iStatus.Int(), _S8("RunL httpClient status is : ") ); + if(iEngineState == ExptOpenCommunication) + { + DBG_FILE(_S8("CNSmlHTTP::RunL before SetHttpConnectionInfoL")); + DBG_FILE_CODE( iStatus.Int(), _S8("RunL HTTP client iStatus: ") ); + if( iStatus == KErrNone) + { + DBG_FILE(_S8("CNSmlHTTP::RunL Status was NO ERROR")); + TRAPD( ret, SetHttpConnectionInfoL( EFalse ) ); + if ( ret != KErrNone ) + { + DBG_FILE_CODE( ret, _S8("CNSmlHTTP::RunL SetHttpConnectionInfoL\ + error:") ); + iShutdown->Cancel(); + TRequestStatus* status = iAgentStatus; + User::RequestComplete( status, ret ); + iTimeOut = EFalse; + return; + } + } + DBG_FILE(_S8("CNSmlHTTP::RunL after SetHttpConnectionInfoL")); + } + + iShutdown->Cancel(); + TRequestStatus* status = iAgentStatus; + User::RequestComplete( status, iStatus.Int() ); + iTimeOut = EFalse; + DBG_FILE(_S8("CNSmlHTTP::RunL ends")); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::OpenCommunicationL +// Establishes a communication using the protocol service with the given ID. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::OpenCommunicationL( + CArrayFixFlat* aIAPidArray, + TDesC8& aURI, + TDesC8& aMimeType, + TRequestStatus &aStatus, + TDesC8& aHTTPusername, + TDesC8& aHTTPpassword, + TInt aHTTPauthused ) + { + __ASSERT_ALWAYS( !IsActive(), User::Panic( _L("CNSmlHTTP"), 1 ) ); + if ( !iShutdown->IsActive() ) + { + iShutdown->Start(); + } + iAgentStatus = &aStatus; + iEngineState = ExptOpenCommunication; + + iIAPidArray = new ( ELeave ) CArrayFixFlat(KSmlArrayGranularity); + + for ( TInt i = 0 ; i < aIAPidArray->Count() ; i++ ) + { + iIAPidArray->AppendL( aIAPidArray->At( i ) ); + } + + iAuthUsed = aHTTPauthused; + + // Open the RHTTPSession + iSess.OpenL(); + + // Install this class as the callback for authentication requests + if( iAuthUsed ) + { + InstallAuthenticationL(iSess); + } + + delete iURI; + iURI = NULL; + iURI = HBufC8::NewL( aURI.Length() ); + TPtr8 iURIptr( iURI->Des() ); + iURIptr.Copy( aURI ); + + delete iMimeType; + iMimeType = NULL; + iMimeType = HBufC8::NewL( aMimeType.Length() ); + TPtr8 iMIMEptr( iMimeType->Des() ); + iMIMEptr.Copy( aMimeType ); + + delete iHTTPusername; + iHTTPusername = NULL; + if(aHTTPusername.Length()!=0) + { + iHTTPusername = HBufC8::NewL( aHTTPusername.Length() ); + TPtr8 iHTTPusernameptr( iHTTPusername->Des() ); + iHTTPusernameptr.Copy( aHTTPusername ); + } + else + { + iHTTPusername = KNullDesC8().AllocL(); + } + + delete iHTTPpassword; + iHTTPpassword = NULL; + if(aHTTPpassword.Length()!=0) + { + iHTTPpassword = HBufC8::NewL( aHTTPpassword.Length() ); + TPtr8 iHTTPpasswordptr( iHTTPpassword->Des() ); + iHTTPpasswordptr.Copy( aHTTPpassword ); + } + else + { + iHTTPpassword = KNullDesC8().AllocL(); + } + + TRAPD( err, ProcessRequestL() ); + User::LeaveIfError( err ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::CloseCommunicationL( TRequestStatus &aStatus ) +// Closes a previously opened communication. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::CloseCommunicationL( TRequestStatus &aStatus ) + { + __ASSERT_ALWAYS( !IsActive(), User::Panic( _L("CNSmlHTTP"), 1 ) ); + iAgentStatus = &aStatus; + iEngineState = ExptCloseCommunication; + TRAPD( err, ProcessRequestL() ); + User::LeaveIfError( err ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::ReceiveDataL +// Read data across a connection. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::ReceiveDataL( TDes8& aStartPtr, TRequestStatus &aStatus ) + { + __ASSERT_ALWAYS( !IsActive(), User::Panic( _L("CNSmlHTTP"), 1 ) ); + iAgentStatus = &aStatus; + if ( !iShutdown->IsActive() ) + { + iShutdown->Start(); + } + iEngineState = ExptReceiveData; + GetResponseBodyL( aStartPtr ); + + DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(), + _S8("ReceiveDataL (WBXML)")); +#ifdef __NSML_DEBUG__ + _DBG_FILE("CNSmlHTTP::ReceiveDataL(): CWbxml2XmlConverter::ConvertL()\ + begin"); + CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC(); + c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length()); + DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), + _S8("ReceiveDataL (XML)") ); + CleanupStack::PopAndDestroy(); // c + _DBG_FILE("CNSmlHTTP::ReceiveDataL(): CWbxml2XmlConverter::ConvertL() end"); +#endif // __NSML_DEBUG__ + + TRAPD( err, ProcessRequestL() ); + User::LeaveIfError( err ); + } + + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::DeleteCertificate() +// Delete HTTP connection certificate. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::DeleteCertificate( ) + { + if(!FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement)) + { + + } + else + { + CRepository *re = NULL; + TRAPD( erx, re = CRepository::NewL ( + KCRUidPolicyManagementUtilInternalKeys ) ); + if (erx == KErrNone ) + { + re->Reset( KSyncMLSessionCertificate ); + delete re; + re = NULL; + } + else + { + DBG_ARGS8(_S8("ERROR Failed to delete reposiritry key %d"), erx ); + } + } +} + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::SaveCertificateL( RHTTPTransaction &aTransaction ) +// save HTTP connection certificate. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::SaveCertificateL( RHTTPTransaction &aTransaction ) + { + if(!FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement)) + { + User::Leave(KErrNotSupported); + } + TCertInfo info ; + TInt errx( aTransaction.ServerCert( info ) ); + if ( errx == KErrNone ) + { + CRepository *re = NULL; + TRAPD( erx, re = CRepository::NewL ( + KCRUidPolicyManagementUtilInternalKeys ) ); + if (erx == KErrNone ) + { + TPckg pcert( info ); + errx = re->Create( KSyncMLSessionCertificate, pcert ) ; + if ( errx == KErrNone ) + { + DBG_ARGS8(_S8("Wrote reposotry key %S"), &pcert ); + } + else + { + if ( errx == KErrAlreadyExists ) + { + errx = re->Set( KSyncMLSessionCertificate, pcert ) ; + if ( errx != KErrNone ) + { + DBG_ARGS8( _S8("ERROR Failed to add reposiritry \ + key %d"), errx ); + } + } + else + { + DBG_ARGS8( _S8("ERROR Failed to create reposiritry \ + key %d"), errx ); + } + } + delete re ; + re = NULL; + } + else + { + DBG_ARGS8(_S8("ERROR Failed to open reposiritry %d"), erx ); + } + } + else + { + DBG_ARGS8(_S8("ERROR Failed to get certificate %d"), errx ); + } + + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::CompressL +// Compress the data. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::CompressL(TDesC8& aStartPtr) + { + HBufC8* tempBufferPtr = HBufC8::NewLC(iMaxMsgSize); + TPtr8 unCompressed( tempBufferPtr->Des()); + unCompressed.Copy( aStartPtr ); + + iReqBodySubmitBuffer = NULL; + iReqBodySubmitBuffer = HBufC8::NewMaxL( iMaxMsgSize ); + + iReqBodySubmitBufferPtr.Set( iReqBodySubmitBuffer->Des() ); + TRAPD(err, CEZCompressor::CompressL(iReqBodySubmitBufferPtr, unCompressed, Z_BEST_COMPRESSION)); + CleanupStack::PopAndDestroy(); + if(err == KErrNone) + { + iDocumentLength = iReqBodySubmitBufferPtr.Length(); + } + } + + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::SendDataL +// Send data across a connection. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::SendDataL( + TDesC8& aStartPtr, + TBool /*aFinalPacket*/, + TRequestStatus &aStatus ) + { + __ASSERT_ALWAYS( !IsActive(), User::Panic( _L("CNSmlHTTP"), 1 ) ); + iAgentStatus = &aStatus; + if ( !iShutdown->IsActive() ) + { + iShutdown->Start(); + } + iEngineState = ExptSendData; + + DBG_DUMP((void*)aStartPtr.Ptr(), aStartPtr.Length(), + _S8("SendDataL (WBXML)") ); +#ifdef __NSML_DEBUG__ + _DBG_FILE("CNSmlHTTP::SendDataL(): CWbxml2XmlConverter::ConvertL() begin"); + CWbxml2XmlConverter* c = CWbxml2XmlConverter::NewLC(); + c->ConvertL(aStartPtr.Ptr(), aStartPtr.Length()); + DBG_DUMP((void*)c->Document().Ptr(), c->Document().Length(), + _S8("SendDataL (XML)") ); + CleanupStack::PopAndDestroy(); // c + _DBG_FILE("CNSmlHTTP::SendDataL(): CWbxml2XmlConverter::ConvertL() end"); +#endif // __NSML_DEBUG__ + + delete iReqBodySubmitBuffer; + iReqBodySubmitBuffer = NULL; + + if( (iSession == ESyncMLDSSession) && (iServerAcceptEncoding == ExptDeflate) ) + { + TRAPD( err, CompressL(aStartPtr) ); + User::LeaveIfError( err ); + } + else + { + iReqBodySubmitBuffer = HBufC8::NewMaxL( iMaxMsgSize ); + iReqBodySubmitBufferPtr.Set( iReqBodySubmitBuffer->Des() ); + iReqBodySubmitBufferPtr.Copy( aStartPtr ); + iDocumentLength = aStartPtr.Length(); + } + TRAPD( err, ProcessRequestL() ); + User::LeaveIfError( err ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::DecompressL +// Decompress the data. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::DecompressL(TDes8& aStartPtr) + { + TPtr8 ptrCompressed( iData->Des() ); + HBufC8* ideCompressed = HBufC8::NewLC(iMaxMsgSize); + TPtr8 ptrdeCompressed( ideCompressed->Des() ); + + TRAPD(err, CEZDecompressor::DecompressL(ptrdeCompressed,ptrCompressed)); + + if(err == KErrNone) + { + aStartPtr.Copy( ideCompressed->Des()); + } + CleanupStack::PopAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::ProcessRequestL() +// wake up thread (or create one) to handle requested service +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::ProcessRequestL() + { + TRequestStatus* statusOwn = &this->iStatus; + // set AO (CNSmlHTTP) active + this->iStatus = KRequestPending; + this->SetActive(); + // agent + *iAgentStatus = KRequestPending; + + if ( iEngineState == ExptOpenCommunication ) + { + this->iDialUpAgent->ConnectL( iIAPidArray, iStatus ); + } + else if ( iEngineState == ExptCloseCommunication ) + { + this->Cancel(); + } + else if ( iEngineState == ExptReceiveData ) + { + User::RequestComplete( statusOwn, KErrNone ); + } + else if ( iEngineState == ExptSendData ) + { + RStringPool strP = iSess.StringPool(); + RStringF method; + method = strP.StringF( HTTP::EPOST, RHTTPSession::GetTable() ); + + RHTTPConnectionInfo connInfo = iSess.ConnectionInfo(); + connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketServ, + RHTTPSession::GetTable() ), + THTTPHdrVal ( + this->iDialUpAgent->iSocketServer.Handle() ) ); + TInt connPtr = REINTERPRET_CAST(TInt, &this->iDialUpAgent->iConnection); + connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable() ), + THTTPHdrVal (connPtr) ); + TInt session=0; + TInt r1=RProperty::Get( KPSUidNSmlSOSServerKey, KNSmlSyncJobOngoing, session); + if( session == ESyncMLDMSession )//for dm session + { + TInt dmsessionTimeout = -1; + CRepository *rep = NULL; + TRAPD( err1, rep = CRepository::NewL( KCRUidDeviceManagementInternalKeys )); + DBG_FILE_CODE(err1, _S8("CNSmlHTTP::ConstructL cenrep read error code ")); + if(err1 == KErrNone) + { + rep->Get( KDevManDMSessionTimeout, dmsessionTimeout ); + delete rep; + DBG_FILE_CODE(dmsessionTimeout, _S8("DMSessiontimeout feature value from cenrep")); + if( dmsessionTimeout < KNSmlDMMaxSessionTimeout && dmsessionTimeout > KNSmlDMMinSessionTimeout) + { + THTTPHdrVal immediateShutdown = strP.StringF(HTTP::ESocketShutdownImmediate, RHTTPSession::GetTable() ); + connInfo.SetPropertyL ( + strP.StringF(HTTP::ESocketShutdownMode, RHTTPSession::GetTable()), + immediateShutdown ); + } + } + } +if(FeatureManager::FeatureSupported(KFeatureIdSapPolicyManagement)) +{ + TInt Session=0; + TInt r=RProperty::Get( KPSUidNSmlSOSServerKey, KNSmlSyncJobOngoing, Session); + if( Session == ESyncMLDMSession )//for dm session + { + THTTPHdrVal secDlgNo( strP.StringF(HTTP::EDialogNoPrompt, + RHTTPSession::GetTable() ) ); + connInfo.SetPropertyL ( strP.StringF(HTTP::ESecureDialog, + RHTTPSession::GetTable() ), secDlgNo ); + DBG_FILE_CODE( Session, _S8("In HTTP No prompt set ") ); + } +} + + + InvokeHttpMethodL( iURI->Des(), method ); + } + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::ChangeTargetURIL( TDesC8& aURI ) +// Changes target URI +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::ChangeTargetURIL( TDesC8& aURI ) + { + delete iURI; + iURI = NULL; + iURI = HBufC8::NewL( aURI.Length() ); + TPtr8 iURIptr( iURI->Des() ); + iURIptr.Copy( aURI ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::SetErrorStatus( Tint aError ) +// Returns the internal http error status code for 4xx-5xx statuses +// ----------------------------------------------------------------------------- +// +TInt CNSmlHTTP::SetErrorStatus( TInt aError ) + { + TInt error = aError; + DBG_FILE_CODE( aError, _S8("http Error code in SetError CNSmlHTTP ") ); + if( aError == 400 ) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_BadRequest; + } + else if ( aError == 401) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_Unauthorized; + } + else if ( aError == 402) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_PaymentRequired; + } + else if ( aError == 403) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_Forbidden; + } + else if ( aError == 404) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_NotFound; + } + else if ( aError == 405) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_MethodNotAllowed; + } + else if ( aError == 406) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_NotAcceptable; + } + else if ( aError == 407) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_ProxyAuthenticationRequired; + } + else if ( aError == 408) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_RequestTimeout; + } + else if ( aError == 409) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_Conflict; + } + else if ( aError == 410) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_Gone; + } + else if ( aError == 411) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_LengthRequired; + } + else if ( aError == 412) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_PreconditionFailed; + } + else if ( aError == 413) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_RequestEntityTooLarge; + } + else if ( aError == 414) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_RequestURITooLong; + } + else if ( aError == 415) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_UnsupportedMediaType; + } + else if ( aError == 416) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_RequestedRangeNotSatisfiable; + } + else if ( aError == 417) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_ExpectationFailed; + } + else if ( aError == 500) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_InternalServerError; + } + else if ( aError == 501) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_NotImplemented; + } + else if ( aError == 502) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_BadGateway; + } + else if ( aError == 503) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_ServiceUnavailable; + } + else if ( aError == 504) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_GatewayTimeout; + } + else if ( aError == 505) + { + return TNSmlHTTPErrCode::ENSmlHTTPErr_HTTPVersionNotSupported; + } + else + { + return error; + } + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::GetCredentialsL (const TUriC8 &aURI,RString aRealm, +// RStringF aAuthenticationType,RString &aUsername,RString &aPassword) +// Gets some credentials +// ----------------------------------------------------------------------------- +// +TBool CNSmlHTTP::GetCredentialsL ( + const TUriC8 &/*aURI*/, + RString aRealm, + RStringF /*aAuthenticationType*/, + RString &aUsername, + RString &aPassword) + { + + if(iAuthRetryCount > 1) + { + return EFalse; + } + + TRAPD(err, aUsername = aRealm.Pool().OpenStringL(*iHTTPusername)); + if (!err) + { + TRAP(err, aPassword = aRealm.Pool().OpenStringL(*iHTTPpassword)); + } + + if (!err) + { + iAuthRetryCount++; + return ETrue; + } + else + { + return EFalse; + } + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::SetHttpConnectionInfoL( TBool aUseOwnConnection ) +// Sets proxy for the connection, if it is configured for the IAP.. +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::SetHttpConnectionInfoL( TBool aUseOwnConnection ) + { + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo begins")); + TInt result; + TBuf<100> serviceType; + TUint32 serviceId; + TBuf<100> query; + TBuf<100> proxyAddr; + TBuf8<100> proxyAddr2; + TUint32 proxyPort; + TUint connCount; + TBool useProxy; + CCommsDatabase* TheDb; + RStringF proxyName; + + // Trick to get new values into use + iSess.Close(); + iSess.OpenL(); + + RStringPool strPool = iSess.StringPool(); + + + // Remove first session properties just in case. + RHTTPConnectionInfo connInfo = iSess.ConnectionInfo(); + + // Clear RConnection and Socket Server instances + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketServ, + RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable())); + + // Clear the proxy settings + THTTPHdrVal proxyUsage(strPool.StringF(HTTP::EUseProxy, + RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyUsage, + RHTTPSession::GetTable())); + connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyAddress, + RHTTPSession::GetTable())); + + if(!aUseOwnConnection) + { + // RConnection has been started, set proxy (if defined) and RConnection and + // Socket Server session properties. + + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo !aUseOwnConnection")); + // Proxy + result = this->iDialUpAgent->iConnection. + EnumerateConnections(connCount); + User::LeaveIfError(result); + + // + // Get service and service type for this connection + // + query.Format(_L("%s\\%s"), IAP, IAP_SERVICE); + result = this->iDialUpAgent->iConnection.GetIntSetting(query, + serviceId); + + query.Format(_L("%s\\%s"), IAP, IAP_SERVICE_TYPE); + result = this->iDialUpAgent->iConnection.GetDesSetting(query, + serviceType); + User::LeaveIfError(result); + + TheDb = CCommsDatabase::NewL(); + CleanupStack::PushL(TheDb); + + CCommsDbTableView* view = TheDb->OpenViewOnProxyRecordLC(serviceId, + serviceType); + result = view->GotoFirstRecord(); + + if(result == KErrNone) + { + // This IAP uses proxy, set it to http session + view->ReadBoolL(TPtrC(PROXY_USE_PROXY_SERVER), useProxy); + if(useProxy) + { + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo WE are using PROXY!")); + + TRAPD(err ,view->ReadUintL(TPtrC(PROXY_PORT_NUMBER), proxyPort)); + + if (err == KErrNone) + { + DBG_FILE(_S8("Proxy Port Number Found")); + HBufC* k = view->ReadLongTextLC(TPtrC(PROXY_SERVER_NAME)); + proxyAddr.Copy(k->Des()); + proxyAddr.AppendFormat(_L(":%d"), proxyPort); + + proxyAddr2.Copy(proxyAddr); + + CleanupClosePushL(proxyName); + proxyName = iSess.StringPool().OpenFStringL(proxyAddr2); + connInfo.SetPropertyL(strPool.StringF(HTTP::EProxyUsage, + RHTTPSession::GetTable()), proxyUsage); + connInfo.SetPropertyL(strPool.StringF(HTTP::EProxyAddress, + RHTTPSession::GetTable()), proxyName); + CleanupStack::PopAndDestroy(); // proxyName + CleanupStack::PopAndDestroy(); //k + } + } + + } + CleanupStack::PopAndDestroy(2); // view, TheDb + + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo before SetPropertys")); + // RConnection and Socket Server + connInfo.SetPropertyL ( + strPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), + THTTPHdrVal (this->iDialUpAgent->iSocketServer.Handle()) ); + + TInt connPtr1 = REINTERPRET_CAST(TInt, &this->iDialUpAgent->iConnection); + connInfo.SetPropertyL ( + strPool.StringF(HTTP::EHttpSocketConnection, + RHTTPSession::GetTable() ), THTTPHdrVal (connPtr1) ); + + if( iAuthUsed ) + { + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo \ + before installing auth filter")); + InstallAuthenticationL( iSess ); + } + + } + + DBG_FILE(_S8("CNSmlHTTP::SetHttpConnectionInfo ends")); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::GetNextDataPart( TPtrC8& aDataPart ) +// +// ----------------------------------------------------------------------------- +// +TBool CNSmlHTTP::GetNextDataPart( TPtrC8& aDataPart ) + { + aDataPart.Set( iReqBodySubmitBufferPtr ); + iLastPart = ETrue; + return iLastPart; + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::ReleaseData() +// +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::ReleaseData() + { + + // Fix for BPSS-7H7H5S + + // Clear out the submit buffer + //TPtr8 buff = iReqBodySubmitBuffer->Des(); + //buff.Zero(); + + if (iLastPart) + return; + // Notify HTTP of more data available immediately, since it's being read + //from file + TRAPD( err, iTrans.NotifyNewRequestBodyPartL() ); + if ( err != KErrNone ) + User::Panic( KSmlHttpClientPanic, KCouldNotNotifyBodyDataPart ); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::OverallDataSize() +// +// ----------------------------------------------------------------------------- +// +TInt CNSmlHTTP::OverallDataSize() + { + return iDocumentLength; + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::Reset() +// +// ----------------------------------------------------------------------------- +// +TInt CNSmlHTTP::Reset() + { + // Reset is called when the posted data needs to be resend + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::InvokeHttpMethodL( const TDesC8& aUri, RStringF aMethod ) +// Invoke the http method +// This actually creates the transaction, sets the headers and +// body and then starts the transaction +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::InvokeHttpMethodL( const TDesC8& aUri, RStringF aMethod ) + { + TUriParser8 uri; + uri.Parse( aUri ); + iTrans = iSess.OpenTransactionL( uri, *iTransObs, aMethod ); + RHTTPHeaders hdr = iTrans.Request().GetHeaderCollection(); + + // Add headers appropriate to all methods + TInt error; + HBufC* useragent = HBufC::NewLC( NCentralRepositoryConstants::KMaxUnicodeStringLength ); + TPtr ptr (useragent->Des() ); + CRepository* rep = CRepository::NewLC( KCRUidNsmlHttp ); + error = rep->Get( KNsmlHttpUAHeader, ptr ); + if( error == KErrNone ) + { + HBufC8* uaheader; + NSmlUnicodeConverter::HBufC8InUTF8LC( *useragent, uaheader ); + TPtr8 ptr8( uaheader->Des() ); + SetHeaderL( hdr, HTTP::EUserAgent, uaheader->Des() ); + DBG_ARGS8(_S8("CNSmlHTTP::InvokeHttpMethodL KNsmlHttpUAHeader key value %S"), &ptr8); + CleanupStack::PopAndDestroy( uaheader ); + } + else + { + DBG_FILE(_S8("CNSmlHTTP::InvokeHttpMethodL KNsmlHttpUAHeader key error ")); + } + CleanupStack::PopAndDestroy( rep ); + CleanupStack::PopAndDestroy( useragent ); + SetHeaderL( hdr, HTTP::ECacheControl, KSmlCacheControl ); + SetHeaderL( hdr, HTTP::EAcceptCharset, KSmlAcceptCharSet ); + SetHeaderL( hdr, HTTP::EAcceptLanguage , KSmlAcceptLanguage ); + + if( iSession == ESyncMLDSSession )//for ds session + { + if(iServerAcceptEncoding == ExptDeflate) + { + SetHeaderL( hdr, HTTP::EContentEncoding , KSmlContentDeflate ); + } + SetHeaderL( hdr, HTTP::EAcceptEncoding , KSmlContentDeflate ); + } + + // Add headers and body data for methods that use request bodies + // Content type header + TBuf8 contTypeBuf; + contTypeBuf.Copy( iMimeType->Des() ); + RStringF contTypeStr; + CleanupClosePushL( contTypeStr ); + contTypeStr = iSess.StringPool().OpenFStringL( contTypeBuf ); + THTTPHdrVal contType( contTypeStr ); + hdr.SetFieldL( iSess.StringPool().StringF( HTTP::EContentType, + RHTTPSession::GetTable()), contType ); + CleanupStack::PopAndDestroy(); // contTypeStr + + + // Accept header + TBuf8 acceptTypeBuf; + acceptTypeBuf.Copy( iMimeType->Des() ); + RStringF acceptTypeStr; + CleanupClosePushL( acceptTypeStr ); + acceptTypeStr = iSess.StringPool().OpenFStringL( acceptTypeBuf ); + THTTPHdrVal acceptType( acceptTypeStr ); + hdr.SetFieldL( iSess.StringPool().StringF( HTTP::EAccept, + RHTTPSession::GetTable()), acceptType ); + CleanupStack::PopAndDestroy(); // acceptTypeStr + + // Expect: 100-continue + THTTPHdrVal expectVal( iSess.StringPool().StringF( HTTP::E100Continue, + RHTTPSession::GetTable() ) ); + hdr.SetFieldL( iSess.StringPool().StringF( HTTP::EExpect, + RHTTPSession::GetTable() ), expectVal ); + + RStringF expectStr( iSess.StringPool().StringF( HTTP::EExpect, + RHTTPSession::GetTable() ) ); + hdr.RemoveField( expectStr ); + + MHTTPDataSupplier* dataSupplier = this; + iTrans.Request().SetBody( *dataSupplier ); + + // submit the transaction + iTrans.SubmitL(); + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::GetResponseBodyL( TDes8& aStartPtr ) +// +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::GetResponseBodyL( TDes8& aStartPtr ) + { + if( iData != NULL ) + { + if (aStartPtr.MaxLength() < (iData->Des()).Length()) + { + User::LeaveIfError( TNSmlError::ESmlStatusSizeMismatch ); + } + else + { + if ( (iSession == ESyncMLDSSession) && (iServerContentEncoding == ExptDeflate) ) + { + TRAPD( err, DecompressL( aStartPtr ) ); + User::LeaveIfError( err ); + } + else + { + aStartPtr.Copy( iData->Des() ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CNSmlHTTP::SetHeaderL( RHTTPHeaders aHeaders, TInt aHdrField, +// const TDesC8& aHdrValue ) +// +// ----------------------------------------------------------------------------- +// +void CNSmlHTTP::SetHeaderL( + RHTTPHeaders aHeaders, + TInt aHdrField, + const TDesC8& aHdrValue ) + { + RStringF valStr; + CleanupClosePushL( valStr ); + valStr = iSess.StringPool().OpenFStringL( aHdrValue ); + THTTPHdrVal val( valStr ); + aHeaders.SetFieldL( iSess.StringPool().StringF( aHdrField, + RHTTPSession::GetTable() ), val ); + CleanupStack::PopAndDestroy(); // valStr + } + + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// ----------------------------------------------------------------------------- +// CreateCNSmlHTTPL() +// ----------------------------------------------------------------------------- +// +EXPORT_C CNSmlHTTP* CreateCNSmlHTTPL() + { + return CNSmlHTTP::NewL(); + } + +//End of File +