author | cawthron |
Tue, 24 Mar 2009 22:20:21 -0500 | |
changeset 2 | d760517a8095 |
permissions | -rw-r--r-- |
/* * 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; }