--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/locationsystemui/locationsysui/posindicator/posreversegeocodeplugin/src/posrevgeocodehttpclientengine.cpp Tue Aug 31 15:37:04 2010 +0300
@@ -0,0 +1,491 @@
+/*
+* Copyright (c) 2010 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: Implementation of HTTP client engine class.
+*
+*/
+
+//Symbian headers
+#include "posrevgeocodehttpclientengine.h"
+#include "posrevgeocodelogger.h"
+
+#include <http.h>
+#include <CommDbConnPref.h>
+#include <connpref.h>
+#include <extendedconnpref.h>
+#include <cmgenconnsettings.h>
+
+// Used user agent for requests
+_LIT8(KUserAgent, "ReverseGeoCode 1.0");
+
+// This client accepts all content types.
+_LIT8(KAccept, "*/*");
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::NewL()
+// ----------------------------------------------------------------------------
+CPosRevGeoCodeHTTPClientEngine* CPosRevGeoCodeHTTPClientEngine::NewL(
+ MPosRevGeoCodeHTTPClientObserver& aObserver )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::NewL");
+ CPosRevGeoCodeHTTPClientEngine* self = new ( ELeave )
+ CPosRevGeoCodeHTTPClientEngine( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::CPosRevGeoCodeHTTPClientEngine()
+// ----------------------------------------------------------------------------
+CPosRevGeoCodeHTTPClientEngine::CPosRevGeoCodeHTTPClientEngine(
+ MPosRevGeoCodeHTTPClientObserver& aObserver ):
+ CActive( CActive::EPriorityStandard ),
+ iObserver( aObserver ),
+ iConnectionSetupDone( EFalse ),
+ iPrevProfileId( -1 ),
+ iMobility(NULL),
+ iTransactionOpen( EFalse ),
+ iUri(NULL)
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::CPosRevGeoCodeHTTPClientEngine");
+ CActiveScheduler::Add(this);
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::~CPosRevGeoCodeHTTPClientEngine()
+// ----------------------------------------------------------------------------
+CPosRevGeoCodeHTTPClientEngine::~CPosRevGeoCodeHTTPClientEngine()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::~CPosRevGeoCodeHTTPClientEngine");
+ Cancel();
+
+ if( iMobility )
+ {
+ iMobility->Cancel();
+ delete iMobility;
+ }
+
+ if ( iTransactionOpen )
+ {
+ iTransaction.Close();
+ }
+
+
+ iSession.Close();
+ iConnection.Close();
+ iSocketServ.Close();
+
+ delete iUri;
+
+ iCmManager.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::ConstructL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::ConstructL()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::ConstructL");
+ iCmManager.OpenL();
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::CloseConnection()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::CloseConnection()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::CloseConnection");
+ if ( iTransactionOpen )
+ {
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+ }
+
+ if ( iMobility )
+ {
+ iMobility->Cancel();
+ delete iMobility;
+ iMobility = NULL;
+ }
+
+ iSession.Close();
+ iConnection.Close();
+ iSocketServ.Close();
+ iConnectionSetupDone = EFalse;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::SetupConnectionL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::SetupConnectionL()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::SetupConnectionL");
+ if ( iConnectionSetupDone )
+ {
+ // Connection setup is done
+ User::Leave(KErrAlreadyExists);
+ }
+
+
+ // Open HTTP Session
+ iSession.OpenL();
+
+ User::LeaveIfError(iSocketServ.Connect());
+ User::LeaveIfError(iConnection.Open(iSocketServ));
+
+ TConnPrefList prefList;
+ TExtendedConnPref prefs;
+ prefs.SetSnapPurpose( CMManager::ESnapPurposeInternet );
+ prefs.SetForcedRoaming( EFalse );
+ prefs.SetBearerSet( TExtendedConnPref::EExtendedConnBearerCellular |
+ TExtendedConnPref::EExtendedConnBearerWLAN );
+ prefList.AppendL( &prefs );
+
+ iConnection.Start( prefList,iStatus );
+ SetActive();
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::SetHeaderL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::SetHeaderL( RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::SetHeaderL");
+ RStringF valStr = iSession.StringPool().OpenFStringL( aHdrValue );
+ CleanupClosePushL( valStr );
+ THTTPHdrVal val(valStr);
+ aHeaders.SetFieldL( iSession.StringPool().StringF( aHdrField, RHTTPSession::GetTable()), val);
+ CleanupStack::PopAndDestroy(); // valStr
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::IssueHTTPGetL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::IssueHTTPGetL( const TDesC8& aUri )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::IssueHTTPGetL");
+ if ( IsActive() )
+ {
+ return;
+ }
+
+ iEngineState = EGet;
+
+ delete iUri;
+ iUri = NULL;
+ iUri = aUri.AllocL();
+ // Create HTTP connection
+ TRAPD( err, SetupConnectionL() );
+ //If the Err is KErrNone, It will lead to RunL and
+ //hence jump to the DoHTTPGetL() from there.
+
+ if( err == KErrAlreadyExists )
+ {
+ DoHTTPGetL();
+ }
+ else if( err != KErrNone )
+ {
+ //If Setup Connection fails
+ iObserver.ClientEvent( EHttpConnectionFailure );
+ User::Leave(err);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::DoHTTPGetL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::DoHTTPGetL()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::DoHTTPGetL");
+ // Parse string to URI (as defined in RFC2396)
+ TUriParser8 uri;
+ uri.Parse( *iUri );
+
+ // Get request method string for HTTP GET
+ RStringF method = iSession.StringPool().StringF( HTTP::EGET,RHTTPSession::GetTable() );
+ CleanupClosePushL( method );
+ // Open transaction with previous method and parsed uri. This class will
+ // receive transaction events in MHFRunL and MHFRunError.
+ iTransaction = iSession.OpenTransactionL( uri, *this, method );
+ iTransactionOpen = ETrue;
+
+ // Set headers for request; user agent and accepted content type
+ RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
+ SetHeaderL( hdr, HTTP::EUserAgent, KUserAgent );
+ SetHeaderL( hdr, HTTP::EAccept, KAccept );
+
+ // Submit the transaction. After this the framework will give transaction
+ // events via MHFRunL and MHFRunError.
+ iTransaction.SubmitL();
+ CleanupStack::PopAndDestroy( 1 ); // method
+ iObserver.ClientEvent( EHttpConnecting );
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::CancelTransaction()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::CancelTransaction()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::CancelTransaction");
+ iEngineState = EIdle;
+ delete iUri;
+ iUri = NULL;
+
+ // Close() also cancels transaction (Cancel() can also be used but
+ // resources allocated by transaction must be still freed with Close())
+ if( iTransactionOpen )
+ {
+ iTransaction.Close();
+ iTransactionOpen = EFalse;
+
+ iObserver.ClientEvent( EHttpTxCancelled );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::MHFRunL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent& aEvent )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::MHFRunL");
+ switch ( aEvent.iStatus )
+ {
+ case THTTPEvent::EGotResponseHeaders:
+ {
+ // HTTP response headers have been received. Use
+ // aTransaction.Response() to get the response. However, it's not
+ // necessary to do anything with the response when this event occurs.
+ iObserver.ClientEvent( EHttpHdrReceived );
+ break;
+ }
+ case THTTPEvent::EGotResponseBodyData:
+ {
+ // Part (or all) of response's body data received. Use
+ // aTransaction.Response().Body()->GetNextDataPart() to get the actual
+ // body data.
+
+ // Get the body data supplier
+ MHTTPDataSupplier* body = aTransaction.Response().Body();
+ TPtrC8 dataChunk;
+
+ // GetNextDataPart() returns ETrue, if the received part is the last
+ // one.
+ TBool isLast = body->GetNextDataPart(dataChunk);
+ iObserver.ClientBodyReceived(dataChunk);
+
+ iObserver.ClientEvent( EHttpBytesReceieved );
+
+ // NOTE: isLast may not be ETrue even if last data part received.
+ // (e.g. multipart response without content length field)
+ // Use EResponseComplete to reliably determine when body is completely
+ // received.
+ if( isLast )
+ {
+ iObserver.ClientEvent( EHttpBodyReceieved );
+ }
+ // Always remember to release the body data.
+ body->ReleaseData();
+ break;
+ }
+ case THTTPEvent::EResponseComplete:
+ {
+ // Indicates that header & body of response is completely received.
+ // No further action here needed.
+
+ iObserver.ClientEvent( EHttpTxCompleted );
+ break;
+ }
+ case THTTPEvent::ESucceeded:
+ {
+ // Indicates that transaction succeeded.
+ iObserver.ClientEvent( EHttpTxSuccess );
+ // Transaction can be closed now. It's not needed anymore.
+ aTransaction.Close();
+ iTransactionOpen = EFalse;
+ break;
+ }
+ case THTTPEvent::EFailed:
+ {
+ // Transaction completed with failure.
+ iObserver.ClientEvent( EHttpTxFailed );
+ aTransaction.Close();
+ iTransactionOpen = EFalse;
+ break;
+ }
+ default:
+ // There are more events in THTTPEvent, but they are not usually
+ // needed. However, event status smaller than zero should be handled
+ // correctly since it's error.
+ {
+ if ( aEvent.iStatus < 0 )
+ {
+ iObserver.ClientEvent( EHttpConnectionFailure );
+ // Close the transaction on errors
+ aTransaction.Close();
+ iTransactionOpen = EFalse;
+ }
+ break;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::MHFRunError()
+// ----------------------------------------------------------------------------
+TInt CPosRevGeoCodeHTTPClientEngine::MHFRunError( TInt /*aError*/,
+ RHTTPTransaction /*aTransaction*/,
+ const THTTPEvent& /*aEvent*/ )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::MHFRunError");
+ // Just notify about the error and return KErrNone.
+ CloseConnection();
+ iObserver.ClientEvent(EHttpMhfRunError);
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::PreferredCarrierAvailable()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::PreferredCarrierAvailable(
+ TAccessPointInfo /*aOldAPInfo*/,
+ TAccessPointInfo /*aNewAPInfo*/,
+ TBool /*aIsUpgrade*/,
+ TBool aIsSeamless )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::PreferredCarrierAvailable");
+ if( !aIsSeamless && iMobility)
+ {
+ iMobility->MigrateToPreferredCarrier();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::NewCarrierActive()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::NewCarrierActive( TAccessPointInfo /*aNewAPInfo*/,
+ TBool aIsSeamless )
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::NewCarrierActive");
+ if( !aIsSeamless && iMobility)
+ {
+ iMobility->NewCarrierAccepted();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::Error()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::Error(TInt /*aError*/)
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::Error");
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::DoCancel()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::DoCancel()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::DoCancel");
+ iConnection.Stop();
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::DoCancel()
+// ----------------------------------------------------------------------------
+TInt CPosRevGeoCodeHTTPClientEngine::RunError(TInt /*aError*/)
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::RunError");
+ // Just notify about the error and return KErrNone.
+ CloseConnection();
+ iObserver.ClientEvent( EHttpTxFailed );
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CPosRevGeoCodeHTTPClientEngine::RunL()
+// ----------------------------------------------------------------------------
+void CPosRevGeoCodeHTTPClientEngine::RunL()
+ {
+ FUNC("CPosRevGeoCodeHTTPClientEngine::RunL");
+ TInt statusCode = iStatus.Int();
+
+ if ( statusCode == KErrNone )
+ {
+ // Connection done ok
+ iConnectionSetupDone = ETrue;
+
+ RStringPool strPool = iSession.StringPool();
+ CleanupClosePushL( strPool );
+ // Remove first session properties just in case.
+ RHTTPConnectionInfo connInfo = iSession.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
+ connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()));
+ connInfo.RemoveProperty(strPool.StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()));
+
+ // RConnection and Socket Server
+ connInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketServ,
+ RHTTPSession::GetTable()),
+ THTTPHdrVal (iSocketServ.Handle()) );
+
+ TInt connPtr1 = REINTERPRET_CAST(TInt, &iConnection);
+ connInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketConnection,
+ RHTTPSession::GetTable() ), THTTPHdrVal (connPtr1) );
+
+ // Register for mobility API
+ delete iMobility;
+ iMobility = NULL;
+ iMobility = CActiveCommsMobilityApiExt::NewL( iConnection, *this );
+ CleanupStack::Pop( &strPool ); // strPool
+
+ // Start selected HTTP action
+ switch( iEngineState )
+ {
+ case EIdle:
+ {
+ //
+ CancelTransaction();
+ break;
+ }
+ case EGet:
+ {
+ DoHTTPGetL();
+ break;
+ }
+ };
+ }
+ else
+ {
+ //handle error
+ if ( statusCode == KErrPermissionDenied )
+ {
+ iObserver.ClientEvent( EHttpAuthFailed );
+ }
+ else
+ {
+ //Throw some general Transaction falure error!
+ iObserver.ClientEvent( EHttpTxFailed );
+ }
+ CloseConnection();
+ }
+ }
+
+// End of file