--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uidesigner/com.nokia.sdt.series60.componentlibrary/components/non-layout/webclient/WebClientEngine.cpp Fri Apr 03 23:33:03 2009 +0100
@@ -0,0 +1,450 @@
+/*
+* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 FILES
+#include <avkon.hrh>
+#include <aknnotewrappers.h>
+#include <stringloader.h>
+#include <http.h>
+//#include <WebClient.rsg>
+#include "WebClientEngine.pan"
+//#include "WebClient.hrh"
+#include "WebClientEngine.h"
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::NewL()
+// Creates instance of CWebClientEngine.
+// ----------------------------------------------------------------------------
+//
+CWebClientEngine* CWebClientEngine::NewL( MWebClientObserver& aObserver )
+ {
+ CWebClientEngine* self = CWebClientEngine::NewLC( aObserver );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::NewLC()
+// Creates instance of CWebClientEngine.
+// ----------------------------------------------------------------------------
+//
+CWebClientEngine* CWebClientEngine::NewLC( MWebClientObserver& aObserver )
+ {
+ CWebClientEngine* self = new (ELeave) CWebClientEngine( aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::CWebClientEngine()
+// First phase constructor.
+// ----------------------------------------------------------------------------
+//
+CWebClientEngine::CWebClientEngine( MWebClientObserver& aObserver )
+: iObserver( aObserver ),
+ iSessionOpened( EFalse ),
+ iRunning( EFalse )
+ {
+ // no implementation required
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::~CWebClientEngine()
+// Destructor.
+// ----------------------------------------------------------------------------
+//
+CWebClientEngine::~CWebClientEngine()
+ {
+ iSession.Close();
+ iConnection.Close();
+ iSocketServ.Close();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::ConstructL()
+// Second phase construction.
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::ConstructL()
+ {
+
+ }
+
+void CWebClientEngine::OpenSessionL()
+ {
+ if (iSessionOpened) return;
+
+ // Open RHTTPSession with default protocol ("HTTP/TCP")
+ TRAPD( err, iSession.OpenL() );
+ if( err != KErrNone ) {
+ // Most common error; no access point configured, and session creation
+ // leaves with KErrNotFound.
+ iObserver.ClientOpenSessionFailedL( *this, err );
+ User::Leave( err );
+ }
+
+ User::LeaveIfError(iSocketServ.Connect());
+ User::LeaveIfError(iConnection.Open(iSocketServ));
+ User::LeaveIfError(iConnection.Start());
+
+ RStringPool strP = iSession.StringPool();
+ RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();
+ connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable() ), THTTPHdrVal (iSocketServ.Handle()) );
+ TInt connPtr = REINTERPRET_CAST(TInt, &(iConnection));
+ connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ), THTTPHdrVal (connPtr) );
+
+
+ // Install this class as the callback for authentication requests. When
+ // page requires authentication the framework calls GetCredentialsL to get
+ // user name and password.
+ InstallAuthenticationL( iSession );
+
+ iSessionOpened = true;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::SetHeaderL()
+// Used to set header value to HTTP request
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::SetHeaderL( RHTTPHeaders aHeaders,
+ TInt aHdrField,
+ const TDesC8& aHdrValue )
+ {
+ RStringF valStr = iSession.StringPool().OpenFStringL( aHdrValue );
+ CleanupClosePushL( valStr );
+ THTTPHdrVal val( valStr );
+ aHeaders.SetFieldL( iSession.StringPool().StringF( aHdrField,
+ RHTTPSession::GetTable() ), val );
+ CleanupStack::PopAndDestroy( &valStr );
+ }
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::DumpRespHeadersL(RHTTPTransaction& aTransaction)
+// Used to display HTTP header field names and values
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::DumpRespHeadersL( RHTTPTransaction& aTransaction )
+ {
+ RHTTPResponse resp = aTransaction.Response();
+ RStringPool strP = aTransaction.Session().StringPool();
+ RHTTPHeaders hdr = resp.GetHeaderCollection();
+ THTTPHdrFieldIter it = hdr.Fields();
+
+ HBufC* headerField = HBufC::NewLC( KMaxHeaderNameLength + KMaxHeaderValueLength );
+ HBufC* fieldValBuf = HBufC::NewLC( KMaxHeaderValueLength );
+
+ while ( it.AtEnd() == EFalse )
+ {
+ RStringTokenF fieldName = it();
+ RStringF fieldNameStr = strP.StringF( fieldName );
+ THTTPHdrVal fieldVal;
+ if ( hdr.GetField( fieldNameStr, 0, fieldVal ) == KErrNone )
+ {
+ const TDesC8& fieldNameDesC = fieldNameStr.DesC();
+ headerField->Des().Copy( fieldNameDesC.Left( KMaxHeaderNameLength ));
+ fieldValBuf->Des().Zero();
+ switch ( fieldVal.Type() )
+ {
+ // the value is an integer
+ case THTTPHdrVal::KTIntVal:
+ fieldValBuf->Des().Num( fieldVal.Int() );
+ break;
+ // the value is a case-insensitive string
+ case THTTPHdrVal::KStrFVal:
+ {
+ RStringF fieldValStr = strP.StringF( fieldVal.StrF() );
+ const TDesC8& fieldValDesC = fieldValStr.DesC();
+ fieldValBuf->Des().Copy( fieldValDesC.Left(KMaxHeaderValueLength ));
+ }
+ break;
+ // the value is a case-sensitive string
+ case THTTPHdrVal::KStrVal:
+ {
+ RString fieldValStr = strP.String( fieldVal.Str() );
+ const TDesC8& fieldValDesC = fieldValStr.DesC();
+ fieldValBuf->Des().Copy( fieldValDesC.Left(KMaxHeaderValueLength) );
+ }
+ break;
+ // the value is a date/time
+ case THTTPHdrVal::KDateVal:
+ {
+ TDateTime date = fieldVal.DateTime();
+ TBuf<KMaxDateTimeStringLength> dateTimeString;
+ TTime t( date );
+ t.FormatL( dateTimeString,KDateFormat );
+ fieldValBuf->Des().Copy( dateTimeString );
+ }
+ break;
+ // the value is type is unknown
+ default:
+ break;
+ }
+
+ // Display HTTP header field name and value
+ headerField->Des().Append( KColon );
+ headerField->Des().Append( *fieldValBuf );
+ iObserver.ClientHeaderReceivedL( *this, *headerField );
+
+ // Display realm for WWW-Authenticate header
+ RStringF wwwAuth = strP.StringF( HTTP::EWWWAuthenticate,RHTTPSession::GetTable() );
+ if ( fieldNameStr == wwwAuth )
+ {
+ // check the auth scheme is 'basic'
+ RStringF basic = strP.StringF( HTTP::EBasic,RHTTPSession::GetTable() );
+ RStringF realm = strP.StringF( HTTP::ERealm,RHTTPSession::GetTable() );
+ THTTPHdrVal realmVal;
+ if (( fieldVal.StrF() == basic ) &&
+ ( !hdr.GetParam( wwwAuth, realm, realmVal )))
+ {
+ RStringF realmValStr = strP.StringF( realmVal.StrF() );
+ fieldValBuf->Des().Copy( realmValStr.DesC() );
+ headerField->Des().Copy( Krealm );
+ headerField->Des().Append( *fieldValBuf );
+ iObserver.ClientHeaderReceivedL( *this, *headerField );
+ }
+ }
+ }
+ ++it;
+ }
+ CleanupStack::PopAndDestroy( fieldValBuf );
+ CleanupStack::PopAndDestroy( headerField );
+ }
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::HandleRunErrorL()
+// Called from MHFRunError() when *leave* occurs in handling of transaction event.
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::HandleRunErrorL( TInt aError )
+ {
+ iObserver.ClientRunErrorL( *this, aError );
+ }
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::IssueHTTPGetL()
+// Start a new HTTP GET transaction.
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::IssueHTTPGetL( const TDesC8& aUri )
+ {
+ // Ensure the session is open
+ OpenSessionL();
+ // Parse string to URI (as defined in RFC2396)
+ TUriParser8 uri;
+ uri.Parse( aUri );
+
+ // Get request method string for HTTP GET
+ RStringF method = iSession.StringPool().StringF( HTTP::EGET,
+ RHTTPSession::GetTable());
+
+ // Open transaction with previous method and parsed uri. This class will
+ // receive transaction events in MHFRunL and MHFRunError.
+ iTransaction = iSession.OpenTransactionL( uri, *this, method );
+
+ // 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();
+
+ iRunning = ETrue;
+
+ iObserver.ClientConnectingL( *this );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::CancelTransactionL()
+// Cancels currently running transaction and frees resources related to it.
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::CancelTransactionL()
+ {
+ if( !iRunning )
+ return;
+
+ // Close() also cancels transaction (Cancel() can also be used but
+ // resources allocated by transaction must be still freed with Close())
+ iTransaction.Close();
+
+ // Not running anymore
+ iRunning = EFalse;
+
+ iObserver.ClientConnectionCanceledL( *this );
+ }
+
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::MHFRunL()
+// Inherited from MHTTPTransactionCallback
+// Called by framework to pass transaction events.
+// ----------------------------------------------------------------------------
+//
+void CWebClientEngine::MHFRunL( RHTTPTransaction aTransaction,
+ const THTTPEvent& aEvent )
+ {
+
+ 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.
+
+ // Get HTTP status code from header (e.g. 200)
+ RHTTPResponse resp = aTransaction.Response();
+ TInt status = resp.StatusCode();
+
+ // Get status text (e.g. "OK")
+ TBuf<KMaxStatusTextLength> statusText;
+ statusText.Copy( resp.StatusText().DesC() );
+
+ // Display header field names and value
+ DumpRespHeadersL( aTransaction );
+
+ }
+ 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.ClientBodyReceivedL( *this, dataChunk );
+
+ // 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.ClientResponseCompleteL( *this );
+ }
+ break;
+
+ case THTTPEvent::ESucceeded:
+ {
+ // Indicates that transaction succeeded.
+ iObserver.ClientTransactionSucceededL( *this );
+
+ // Transaction can be closed now. It's not needed anymore.
+ aTransaction.Close();
+ iRunning = EFalse;
+ }
+ break;
+
+ case THTTPEvent::EFailed:
+ {
+ // Transaction completed with failure.
+ iObserver.ClientTransactionFailedL( *this );
+ aTransaction.Close();
+ iRunning = 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.
+ {
+ iObserver.ClientUnknownEventL( *this, aEvent.iStatus );
+ if ( aEvent.iStatus < 0 )
+ {
+ // Just close the transaction on errors
+ aTransaction.Close();
+ iRunning = EFalse;
+ }
+ }
+ break;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::MHFRunError()
+// Inherited from MHTTPTransactionCallback
+// Called by framework when *leave* occurs in handling of transaction event.
+// These errors must be handled, or otherwise HTTP-CORE 6 panic is thrown.
+// ----------------------------------------------------------------------------
+//
+TInt CWebClientEngine::MHFRunError( TInt aError,
+ RHTTPTransaction /*aTransaction*/,
+ const THTTPEvent& /*aEvent*/)
+ {
+ // Handle error and return KErrNone.
+ TRAPD( err, HandleRunErrorL( aError ) );
+ if( err )
+ Panic( EClientEngine );
+ return KErrNone;
+ }
+
+// ----------------------------------------------------------------------------
+// CWebClientEngine::GetCredentialsL()
+//
+// Inherited from MHTTPAuthenticationCallback
+// Called by framework when we requested authenticated page and framework
+// needs to know username and password.
+// ----------------------------------------------------------------------------
+TBool CWebClientEngine::GetCredentialsL( const TUriC8& aUri,
+ RString aRealm,
+ RStringF /*aAuthenticationType*/,
+ RString& aUsername,
+ RString& aPassword)
+ {
+ TBuf<KMaxUserNameLength> userName;
+ TBuf<KMaxPasswordLength> password;
+
+ TBool haveCredentials = iObserver.ClientGetCredentialsL( *this, aUri, aRealm.DesC(), userName, password);
+ if (haveCredentials)
+ {
+ // Set aUsername and aPassword
+ TBuf8<KMaxUserNameLength> temp;
+ temp.Copy( userName );
+ TRAPD( err, aUsername = aRealm.Pool().OpenStringL( temp ));
+ if ( !err )
+ {
+ temp.Copy( password );
+ TRAP( err, aPassword = aRealm.Pool().OpenStringL( temp ));
+ if ( !err ) return ETrue;
+ }
+
+ }
+ return EFalse;
+ }
+