uidesigner/com.nokia.sdt.series60.componentlibrary/components/non-layout/webclient/WebClientEngine.cpp
changeset 2 d760517a8095
equal deleted inserted replaced
-1:000000000000 2:d760517a8095
       
     1 /*
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <avkon.hrh>
       
    21 #include <aknnotewrappers.h>
       
    22 #include <stringloader.h>
       
    23 #include <http.h>
       
    24 //#include <WebClient.rsg>
       
    25 #include "WebClientEngine.pan"
       
    26 //#include "WebClient.hrh"
       
    27 #include "WebClientEngine.h"
       
    28 
       
    29 // ----------------------------------------------------------------------------
       
    30 // CWebClientEngine::NewL()
       
    31 // Creates instance of CWebClientEngine.
       
    32 // ----------------------------------------------------------------------------
       
    33 //
       
    34 CWebClientEngine* CWebClientEngine::NewL( MWebClientObserver& aObserver )
       
    35     {
       
    36     CWebClientEngine* self = CWebClientEngine::NewLC( aObserver );
       
    37     CleanupStack::Pop( self );
       
    38     return self;
       
    39     }
       
    40 
       
    41 
       
    42 // ----------------------------------------------------------------------------
       
    43 // CWebClientEngine::NewLC()
       
    44 // Creates instance of CWebClientEngine.
       
    45 // ----------------------------------------------------------------------------
       
    46 //
       
    47 CWebClientEngine* CWebClientEngine::NewLC( MWebClientObserver& aObserver )
       
    48     {
       
    49     CWebClientEngine* self = new (ELeave) CWebClientEngine( aObserver );
       
    50     CleanupStack::PushL( self );
       
    51     self->ConstructL();
       
    52     return self;
       
    53     }
       
    54 
       
    55 
       
    56 // ----------------------------------------------------------------------------
       
    57 // CWebClientEngine::CWebClientEngine()
       
    58 // First phase constructor.
       
    59 // ----------------------------------------------------------------------------
       
    60 //
       
    61 CWebClientEngine::CWebClientEngine( MWebClientObserver& aObserver )
       
    62 :    iObserver( aObserver ),
       
    63      iSessionOpened( EFalse ),
       
    64      iRunning( EFalse )
       
    65     {
       
    66     // no implementation required
       
    67     }
       
    68 
       
    69 
       
    70 // ----------------------------------------------------------------------------
       
    71 // CWebClientEngine::~CWebClientEngine()
       
    72 // Destructor.
       
    73 // ----------------------------------------------------------------------------
       
    74 //
       
    75 CWebClientEngine::~CWebClientEngine()
       
    76     {
       
    77     iSession.Close();
       
    78     iConnection.Close();
       
    79 	iSocketServ.Close();
       
    80     }
       
    81 
       
    82 
       
    83 // ----------------------------------------------------------------------------
       
    84 // CWebClientEngine::ConstructL()
       
    85 // Second phase construction.
       
    86 // ----------------------------------------------------------------------------
       
    87 //
       
    88 void CWebClientEngine::ConstructL()
       
    89 	{
       
    90 	
       
    91 	}
       
    92 	
       
    93 void CWebClientEngine::OpenSessionL()
       
    94     {
       
    95     if (iSessionOpened) return;
       
    96     
       
    97     // Open RHTTPSession with default protocol ("HTTP/TCP")
       
    98     TRAPD( err, iSession.OpenL() );
       
    99     if( err != KErrNone ) {
       
   100         // Most common error; no access point configured, and session creation
       
   101         // leaves with KErrNotFound.
       
   102     	iObserver.ClientOpenSessionFailedL( *this, err );
       
   103         User::Leave( err );
       
   104     }
       
   105     
       
   106  	User::LeaveIfError(iSocketServ.Connect());
       
   107 	User::LeaveIfError(iConnection.Open(iSocketServ));
       
   108 	User::LeaveIfError(iConnection.Start());
       
   109 	
       
   110 	RStringPool strP = iSession.StringPool();
       
   111 	RHTTPConnectionInfo connInfo = iSession.ConnectionInfo();
       
   112 	connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable() ), THTTPHdrVal (iSocketServ.Handle()) );
       
   113 	TInt connPtr = REINTERPRET_CAST(TInt, &(iConnection));
       
   114 	connInfo.SetPropertyL ( strP.StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable() ), THTTPHdrVal (connPtr) );
       
   115 
       
   116 
       
   117     // Install this class as the callback for authentication requests. When 
       
   118     // page requires authentication the framework calls GetCredentialsL to get 
       
   119     // user name and password.
       
   120     InstallAuthenticationL( iSession );
       
   121     
       
   122     iSessionOpened = true;
       
   123     }
       
   124 
       
   125 
       
   126 // ----------------------------------------------------------------------------
       
   127 // CWebClientEngine::SetHeaderL()
       
   128 // Used to set header value to HTTP request
       
   129 // ----------------------------------------------------------------------------
       
   130 //
       
   131 void CWebClientEngine::SetHeaderL( RHTTPHeaders aHeaders, 
       
   132                                    TInt aHdrField, 
       
   133                                    const TDesC8& aHdrValue )
       
   134     {
       
   135     RStringF valStr = iSession.StringPool().OpenFStringL( aHdrValue );
       
   136     CleanupClosePushL( valStr );
       
   137     THTTPHdrVal val( valStr );
       
   138     aHeaders.SetFieldL( iSession.StringPool().StringF( aHdrField,
       
   139         RHTTPSession::GetTable() ), val );
       
   140     CleanupStack::PopAndDestroy( &valStr );
       
   141     }
       
   142 
       
   143 // ----------------------------------------------------------------------------
       
   144 // CWebClientEngine::DumpRespHeadersL(RHTTPTransaction& aTransaction)
       
   145 // Used to display HTTP header field names and values
       
   146 // ----------------------------------------------------------------------------
       
   147 //
       
   148 void CWebClientEngine::DumpRespHeadersL( RHTTPTransaction& aTransaction )
       
   149     {
       
   150     RHTTPResponse resp = aTransaction.Response();
       
   151     RStringPool strP = aTransaction.Session().StringPool();
       
   152     RHTTPHeaders hdr = resp.GetHeaderCollection();
       
   153     THTTPHdrFieldIter it = hdr.Fields();
       
   154 
       
   155     HBufC* headerField = HBufC::NewLC( KMaxHeaderNameLength + KMaxHeaderValueLength );
       
   156     HBufC* fieldValBuf = HBufC::NewLC( KMaxHeaderValueLength );
       
   157 
       
   158     while ( it.AtEnd() == EFalse )
       
   159         {
       
   160         RStringTokenF fieldName = it();
       
   161         RStringF fieldNameStr = strP.StringF( fieldName );
       
   162         THTTPHdrVal fieldVal;
       
   163         if ( hdr.GetField( fieldNameStr, 0, fieldVal ) == KErrNone )
       
   164             {
       
   165             const TDesC8& fieldNameDesC = fieldNameStr.DesC();
       
   166             headerField->Des().Copy( fieldNameDesC.Left( KMaxHeaderNameLength ));
       
   167             fieldValBuf->Des().Zero();
       
   168             switch ( fieldVal.Type() )
       
   169                 {
       
   170             // the value is an integer
       
   171             case THTTPHdrVal::KTIntVal:
       
   172                 fieldValBuf->Des().Num( fieldVal.Int() );
       
   173                 break;
       
   174             // the value is a case-insensitive string
       
   175             case THTTPHdrVal::KStrFVal:
       
   176                 {
       
   177                 RStringF fieldValStr = strP.StringF( fieldVal.StrF() );
       
   178                 const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   179                 fieldValBuf->Des().Copy( fieldValDesC.Left(KMaxHeaderValueLength ));
       
   180                 }
       
   181                 break;
       
   182             // the value is a case-sensitive string
       
   183             case THTTPHdrVal::KStrVal:
       
   184                 {
       
   185                 RString fieldValStr = strP.String( fieldVal.Str() );
       
   186                 const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   187                 fieldValBuf->Des().Copy( fieldValDesC.Left(KMaxHeaderValueLength) );
       
   188                 }
       
   189                 break;
       
   190             // the value is a date/time
       
   191             case THTTPHdrVal::KDateVal:
       
   192                 {
       
   193                 TDateTime date = fieldVal.DateTime();
       
   194                 TBuf<KMaxDateTimeStringLength> dateTimeString;
       
   195                 TTime t( date );
       
   196                 t.FormatL( dateTimeString,KDateFormat );
       
   197                 fieldValBuf->Des().Copy( dateTimeString );
       
   198                 } 
       
   199                 break;
       
   200             // the value is type is unknown
       
   201             default:
       
   202                 break;
       
   203                 }
       
   204 
       
   205             // Display HTTP header field name and value
       
   206             headerField->Des().Append( KColon );
       
   207             headerField->Des().Append( *fieldValBuf );
       
   208             iObserver.ClientHeaderReceivedL( *this, *headerField );
       
   209             
       
   210             // Display realm for WWW-Authenticate header
       
   211             RStringF wwwAuth = strP.StringF( HTTP::EWWWAuthenticate,RHTTPSession::GetTable() );
       
   212             if ( fieldNameStr == wwwAuth )
       
   213                 {
       
   214                 // check the auth scheme is 'basic'
       
   215                 RStringF basic = strP.StringF( HTTP::EBasic,RHTTPSession::GetTable() );
       
   216                 RStringF realm = strP.StringF( HTTP::ERealm,RHTTPSession::GetTable() );
       
   217                 THTTPHdrVal realmVal;
       
   218                 if (( fieldVal.StrF() == basic ) && 
       
   219                     ( !hdr.GetParam( wwwAuth, realm, realmVal )))
       
   220                     {
       
   221                     RStringF realmValStr = strP.StringF( realmVal.StrF() );
       
   222                     fieldValBuf->Des().Copy( realmValStr.DesC() );
       
   223                     headerField->Des().Copy( Krealm );
       
   224                     headerField->Des().Append( *fieldValBuf );
       
   225                     iObserver.ClientHeaderReceivedL( *this, *headerField );
       
   226                     }
       
   227                 }
       
   228             }
       
   229         ++it;
       
   230         }
       
   231         CleanupStack::PopAndDestroy( fieldValBuf );
       
   232         CleanupStack::PopAndDestroy( headerField );
       
   233     }
       
   234 
       
   235 // ----------------------------------------------------------------------------
       
   236 // CWebClientEngine::HandleRunErrorL()
       
   237 // Called from MHFRunError() when *leave* occurs in handling of transaction event.
       
   238 // ----------------------------------------------------------------------------
       
   239 //
       
   240 void CWebClientEngine::HandleRunErrorL( TInt aError )
       
   241     {
       
   242     iObserver.ClientRunErrorL( *this, aError );
       
   243     }
       
   244 
       
   245 // ----------------------------------------------------------------------------
       
   246 // CWebClientEngine::IssueHTTPGetL()
       
   247 // Start a new HTTP GET transaction.
       
   248 // ----------------------------------------------------------------------------
       
   249 //
       
   250 void CWebClientEngine::IssueHTTPGetL( const TDesC8& aUri )
       
   251     {
       
   252     // Ensure the session is open
       
   253     OpenSessionL();
       
   254     // Parse string to URI (as defined in RFC2396)
       
   255     TUriParser8 uri;
       
   256     uri.Parse( aUri );
       
   257 
       
   258     // Get request method string for HTTP GET
       
   259     RStringF method = iSession.StringPool().StringF( HTTP::EGET,
       
   260         RHTTPSession::GetTable());
       
   261 
       
   262     // Open transaction with previous method and parsed uri. This class will
       
   263     // receive transaction events in MHFRunL and MHFRunError.
       
   264     iTransaction = iSession.OpenTransactionL( uri, *this, method );
       
   265 
       
   266     // Set headers for request; user agent and accepted content type
       
   267     RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
       
   268     SetHeaderL( hdr, HTTP::EUserAgent, KUserAgent );
       
   269     SetHeaderL( hdr, HTTP::EAccept, KAccept );
       
   270 
       
   271     // Submit the transaction. After this the framework will give transaction
       
   272     // events via MHFRunL and MHFRunError.
       
   273     iTransaction.SubmitL();
       
   274 
       
   275     iRunning = ETrue;
       
   276 
       
   277     iObserver.ClientConnectingL( *this );
       
   278     }
       
   279 
       
   280 
       
   281 // ----------------------------------------------------------------------------
       
   282 // CWebClientEngine::CancelTransactionL()
       
   283 // Cancels currently running transaction and frees resources related to it.
       
   284 // ----------------------------------------------------------------------------
       
   285 //
       
   286 void CWebClientEngine::CancelTransactionL()
       
   287     {
       
   288     if( !iRunning ) 
       
   289         return;
       
   290 
       
   291     // Close() also cancels transaction (Cancel() can also be used but 
       
   292     // resources allocated by transaction must be still freed with Close())
       
   293     iTransaction.Close();
       
   294 
       
   295     // Not running anymore
       
   296     iRunning = EFalse;
       
   297 
       
   298     iObserver.ClientConnectionCanceledL( *this );
       
   299     }
       
   300 
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // CWebClientEngine::MHFRunL()
       
   304 // Inherited from MHTTPTransactionCallback
       
   305 // Called by framework to pass transaction events.
       
   306 // ----------------------------------------------------------------------------
       
   307 //
       
   308 void CWebClientEngine::MHFRunL( RHTTPTransaction aTransaction, 
       
   309                                 const THTTPEvent& aEvent )
       
   310     {
       
   311 
       
   312     switch ( aEvent.iStatus ) 
       
   313         {
       
   314         case THTTPEvent::EGotResponseHeaders:
       
   315             {
       
   316             // HTTP response headers have been received. Use
       
   317             // aTransaction.Response() to get the response. However, it's not
       
   318             // necessary to do anything with the response when this event occurs.
       
   319 
       
   320             // Get HTTP status code from header (e.g. 200)
       
   321             RHTTPResponse resp = aTransaction.Response();
       
   322             TInt status = resp.StatusCode();
       
   323 
       
   324             // Get status text (e.g. "OK")
       
   325             TBuf<KMaxStatusTextLength> statusText;
       
   326             statusText.Copy( resp.StatusText().DesC() );
       
   327 
       
   328             // Display header field names and value
       
   329             DumpRespHeadersL( aTransaction );
       
   330 
       
   331             }
       
   332             break;
       
   333 
       
   334         case THTTPEvent::EGotResponseBodyData:
       
   335             {
       
   336             // Part (or all) of response's body data received. Use 
       
   337             // aTransaction.Response().Body()->GetNextDataPart() to get the actual
       
   338             // body data.
       
   339 
       
   340             // Get the body data supplier
       
   341             MHTTPDataSupplier* body = aTransaction.Response().Body();
       
   342             TPtrC8 dataChunk;
       
   343 
       
   344             // GetNextDataPart() returns ETrue, if the received part is the last 
       
   345             // one.
       
   346             TBool isLast = body->GetNextDataPart( dataChunk );
       
   347             iObserver.ClientBodyReceivedL( *this, dataChunk );
       
   348 
       
   349             // Always remember to release the body data.
       
   350             body->ReleaseData();
       
   351             }
       
   352             break;
       
   353 
       
   354         case THTTPEvent::EResponseComplete:
       
   355             {
       
   356             // Indicates that header & body of response is completely received.
       
   357             // No further action here needed.
       
   358             iObserver.ClientResponseCompleteL( *this );
       
   359             }
       
   360             break;
       
   361 
       
   362         case THTTPEvent::ESucceeded:
       
   363             {
       
   364             // Indicates that transaction succeeded. 
       
   365             iObserver.ClientTransactionSucceededL( *this );
       
   366 
       
   367             // Transaction can be closed now. It's not needed anymore.
       
   368             aTransaction.Close();
       
   369             iRunning = EFalse;
       
   370             }
       
   371             break;
       
   372 
       
   373         case THTTPEvent::EFailed:
       
   374             {
       
   375             // Transaction completed with failure. 
       
   376             iObserver.ClientTransactionFailedL( *this );
       
   377             aTransaction.Close();
       
   378             iRunning = EFalse;
       
   379             }
       
   380             break;
       
   381 
       
   382         default:
       
   383             // There are more events in THTTPEvent, but they are not usually 
       
   384             // needed. However, event status smaller than zero should be handled 
       
   385             // correctly since it's error.
       
   386             {
       
   387             iObserver.ClientUnknownEventL( *this, aEvent.iStatus );
       
   388             if ( aEvent.iStatus < 0 )
       
   389                 {
       
   390                 // Just close the transaction on errors
       
   391                 aTransaction.Close();
       
   392                 iRunning = EFalse;
       
   393                 }
       
   394             }
       
   395             break;
       
   396         }
       
   397     }
       
   398 
       
   399 // ----------------------------------------------------------------------------
       
   400 // CWebClientEngine::MHFRunError()
       
   401 // Inherited from MHTTPTransactionCallback
       
   402 // Called by framework when *leave* occurs in handling of transaction event.
       
   403 // These errors must be handled, or otherwise HTTP-CORE 6 panic is thrown.
       
   404 // ----------------------------------------------------------------------------
       
   405 //
       
   406 TInt CWebClientEngine::MHFRunError( TInt aError, 
       
   407                                     RHTTPTransaction /*aTransaction*/, 
       
   408                                     const THTTPEvent& /*aEvent*/)
       
   409     {
       
   410     // Handle error and return KErrNone.
       
   411     TRAPD( err, HandleRunErrorL( aError ) );
       
   412     if( err )
       
   413         Panic( EClientEngine );
       
   414     return KErrNone;
       
   415     }
       
   416 
       
   417 // ----------------------------------------------------------------------------
       
   418 // CWebClientEngine::GetCredentialsL()
       
   419 //
       
   420 // Inherited from MHTTPAuthenticationCallback
       
   421 // Called by framework when we requested authenticated page and framework 
       
   422 // needs to know username and password.
       
   423 // ----------------------------------------------------------------------------
       
   424 TBool CWebClientEngine::GetCredentialsL( const TUriC8& aUri,
       
   425                                                RString aRealm, 
       
   426                                                RStringF /*aAuthenticationType*/,
       
   427                                                RString& aUsername, 
       
   428                                                RString& aPassword) 
       
   429     {
       
   430     TBuf<KMaxUserNameLength> userName;
       
   431     TBuf<KMaxPasswordLength> password;
       
   432  
       
   433     TBool haveCredentials = iObserver.ClientGetCredentialsL( *this, aUri, aRealm.DesC(), userName, password);
       
   434     if (haveCredentials)
       
   435     	{
       
   436 	    // Set aUsername and aPassword
       
   437 	    TBuf8<KMaxUserNameLength> temp;
       
   438 	    temp.Copy( userName );
       
   439 	    TRAPD( err, aUsername = aRealm.Pool().OpenStringL( temp ));
       
   440 	    if ( !err ) 
       
   441 	        {
       
   442 	        temp.Copy( password );
       
   443 	        TRAP( err, aPassword = aRealm.Pool().OpenStringL( temp ));
       
   444 	        if ( !err ) return ETrue;
       
   445 	        }
       
   446     	
       
   447     	}
       
   448     return EFalse;
       
   449     }
       
   450