diff -r 000000000000 -r fb279309251b uidesigner/com.nokia.sdt.series60.componentlibrary/components/non-layout/webclient/WebClientEngine.cpp --- /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 +#include +#include +#include +//#include +#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 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 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 userName; + TBuf password; + + TBool haveCredentials = iObserver.ClientGetCredentialsL( *this, aUri, aRealm.DesC(), userName, password); + if (haveCredentials) + { + // Set aUsername and aPassword + TBuf8 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; + } +