uidesigner/com.nokia.sdt.series60.componentlibrary/components/non-layout/webclient/WebClientEngine.cpp
changeset 0 fb279309251b
--- /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;
+    }
+