xdmprotocols/XcapProtocol/XcapHttpTransport/src/XcapHttpResponse.cpp
branchRCL_3
changeset 18 fbd2e7cec7ef
parent 0 c8caa15ef882
equal deleted inserted replaced
17:2669f8761a99 18:fbd2e7cec7ef
       
     1 /*
       
     2 * Copyright (c) 2003 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 "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:   CXcapHttpResponse
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <XdmErrors.h>
       
    23 #include "XdmCredentials.h"
       
    24 #include "XcapHttpRequest.h"
       
    25 #include "XcapHttpResponse.h"
       
    26 #include "XcapHttpTransport.h"
       
    27 #include "XcapHttpAuthManager.h"
       
    28 
       
    29 const TUint KMaxRetryCount = 3;
       
    30 
       
    31 // ================= MEMBER FUNCTIONS =======================
       
    32 //
       
    33 
       
    34 
       
    35 // ----------------------------------------------------------
       
    36 // CXcapHttpResponse::CXcapHttpResponse
       
    37 // 
       
    38 // ----------------------------------------------------------
       
    39 //
       
    40 CXcapHttpResponse::CXcapHttpResponse( CXcapHttpRequest* aHttpRequest,
       
    41                                       CXcapHttpTransport& aTransportMain ) :
       
    42                                       iAuthPending( EFalse ),
       
    43                                       iHttpRequest( aHttpRequest ),
       
    44                                       iTransportMain( aTransportMain ),
       
    45                                       iAuthManager( iHttpRequest->AuthManager() )                                       
       
    46     {
       
    47     }
       
    48 
       
    49 // ----------------------------------------------------
       
    50 // CXcapHttpResponse::NewL
       
    51 // 
       
    52 // ----------------------------------------------------
       
    53 //
       
    54 CXcapHttpResponse* CXcapHttpResponse::NewL( CXcapHttpRequest* aHttpRequest,
       
    55                                             CXcapHttpTransport& aTransportMain )
       
    56     {
       
    57     CXcapHttpResponse* self = new ( ELeave ) CXcapHttpResponse( aHttpRequest, aTransportMain );
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL();
       
    60     CleanupStack::Pop();  //self
       
    61     return self;
       
    62     }
       
    63     
       
    64 // ----------------------------------------------------
       
    65 // CXcapHttpResponse::ConstructL
       
    66 // 
       
    67 // ----------------------------------------------------
       
    68 //
       
    69 void CXcapHttpResponse::ConstructL()
       
    70     {
       
    71     }
       
    72     
       
    73 // ----------------------------------------------------
       
    74 // CXcapHttpResponse::~CXcapHttpResponse()
       
    75 // Destructor
       
    76 // ----------------------------------------------------
       
    77 //
       
    78 CXcapHttpResponse::~CXcapHttpResponse()
       
    79     {
       
    80     }
       
    81 
       
    82 // ----------------------------------------------------
       
    83 // CXcapHttpResponse::MHFRunL
       
    84 // 
       
    85 // ----------------------------------------------------
       
    86 //
       
    87 void CXcapHttpResponse::MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent& aEvent )
       
    88     {
       
    89     TInt status = aTransaction.Response().StatusCode();
       
    90     #ifdef _DEBUG
       
    91         iTransportMain.WriteToLog( _L8( "CXcapHttpResponse::MHFRunL()" ) );
       
    92         iTransportMain.WriteToLog( _L8( "  HTTP status:  %d" ), status );
       
    93 		iTransportMain.WriteToLog( _L8( "  Event status: %d" ), aEvent.iStatus );
       
    94         iTransportMain.WriteToLog( _L8( "  TransID:      %d " ), aTransaction.Id() );
       
    95     #endif
       
    96     switch( aEvent.iStatus )
       
    97         {
       
    98         case THTTPEvent::EGotResponseHeaders:
       
    99             #ifdef _DEBUG
       
   100                 DumpHeadersL( aTransaction.Response().GetHeaderCollection(), aTransaction.Id() );
       
   101                 //DumpHeadersL( aTransaction.Request().GetHeaderCollection(), aTransaction.Id() );
       
   102             #endif
       
   103             TInt authType;
       
   104             if( IsUnauthRequest( aTransaction, authType ) )
       
   105                 {
       
   106                 // If server keeps on sending 401 resposenses. Will stop
       
   107                 // sending new requests after 3 trys.
       
   108                 if ( KMaxRetryCount == iUnauthRequestCounter )
       
   109                     {
       
   110                     #ifdef _DEBUG
       
   111                         iTransportMain.WriteToLog(
       
   112                         _L8( "  Max retry count. Stop sending auth requests to server." ) );
       
   113                     #endif   
       
   114                     iHttpRequest->FinaliseRequestL( KErrCancel );
       
   115                     aTransaction.Cancel();                   
       
   116                     }                
       
   117                 //We only support Digest => If Basic is defined, stop.
       
   118                 else if( iAuthManager.ParseHeaderL( aTransaction, authType ) )
       
   119                     {
       
   120                     iHttpRequest->ResendWithAuthL( authType );
       
   121                     iAuthPending = ETrue;
       
   122                     }
       
   123                 else
       
   124                     {
       
   125                     #ifdef _DEBUG
       
   126                         iTransportMain.WriteToLog( _L8( " Basic authentication not supported" ) );
       
   127                     #endif
       
   128                     iHttpRequest->FinaliseRequestL( KXcapErrorAuthentication );
       
   129                     aTransaction.Cancel();
       
   130                     }
       
   131                 }
       
   132             else if( iAuthPending && ( status != 401 && status != 403 ) )
       
   133                 {
       
   134                 iAuthPending = EFalse;
       
   135                 iAuthManager.SetAuthorized( ETrue );
       
   136                 }
       
   137             else if( !CheckAuthInfoHeaderL( aTransaction.Response().GetHeaderCollection() ) )
       
   138                 {
       
   139                 //This means that something was wrong with the Authentication-Info header
       
   140                 //the server returned. Do not take any chances here, but stop.
       
   141                 #ifdef _DEBUG
       
   142                     iTransportMain.WriteToLog( _L8( " Something's wrong with Authentication-Info => STOP" ) );
       
   143                 #endif
       
   144                 iHttpRequest->FinaliseRequestL( KXcapErrorAuthentication );
       
   145                 aTransaction.Cancel();
       
   146                 }
       
   147             break;
       
   148         case THTTPEvent::EGotResponseBodyData:
       
   149             #ifdef _DEBUG
       
   150                 iTransportMain.WriteToLog( _L8( "MHFRunL() - A body part received" ) );
       
   151             #endif
       
   152             HandleReceivedBodyDataL( aTransaction );
       
   153             break;
       
   154         case THTTPEvent::EResponseComplete:
       
   155             #ifdef _DEBUG
       
   156                 iTransportMain.WriteToLog( _L8( " * Transaction complete") );
       
   157             #endif
       
   158             break;
       
   159         case THTTPEvent::ESucceeded:
       
   160             #ifdef _DEBUG
       
   161                 iTransportMain.WriteToLog( _L8( " * Transaction succeeded") );
       
   162             #endif
       
   163             iHttpRequest->FinaliseRequestL( KErrNone );
       
   164             break;
       
   165         case THTTPEvent::EFailed:
       
   166             {
       
   167             TInt completion = aEvent.iStatus < 0 ? aEvent.iStatus : KErrNone;
       
   168             #ifdef _DEBUG
       
   169                 iTransportMain.WriteToLog( _L8( " * Transaction failed - Completion: %d"), completion );
       
   170             #endif
       
   171             iHttpRequest->FinaliseRequestL( completion );
       
   172             }
       
   173             break;
       
   174         case THTTPEvent::ERedirectedPermanently:
       
   175             break;
       
   176         case THTTPEvent::ERedirectedTemporarily:
       
   177             break;
       
   178         default:
       
   179             {
       
   180             if( aEvent.iStatus < KErrNone )
       
   181                 {
       
   182                 #ifdef _DEBUG
       
   183                     iTransportMain.WriteToLog( _L8( "  * Transaction failed, stop" ) );
       
   184                 #endif
       
   185                 iHttpRequest->FinaliseRequestL( aEvent.iStatus );
       
   186                 }
       
   187             else
       
   188                 {
       
   189                 #ifdef _DEBUG
       
   190                     iTransportMain.WriteToLog( _L8( "  * Unknown status, stop" ) );
       
   191                 #endif
       
   192                 iHttpRequest->FinaliseRequestL( KErrUnknown );
       
   193                 }
       
   194             }
       
   195             break;
       
   196         }  
       
   197     }
       
   198 
       
   199 // ----------------------------------------------------------
       
   200 // CXcapHttpAuthManager::CheckAuthInfoHeaderL
       
   201 // 
       
   202 // ----------------------------------------------------------
       
   203 //
       
   204 TBool CXcapHttpResponse::CheckAuthInfoHeaderL( RHTTPHeaders aHeaders )
       
   205     {
       
   206     #ifdef _DEBUG
       
   207         iTransportMain.WriteToLog( _L8( "CXcapHttpResponse::CheckAuthInfoHeaderL()" ) );
       
   208     #endif
       
   209     THTTPHdrVal fieldVal;
       
   210     TBool authOk = ETrue;
       
   211     TPtrC8 rawData( _L8( "" ) );
       
   212     RStringPool spool = iHttpRequest->Session().StringPool();
       
   213     RStringF authInfo = spool.OpenFStringL( TPtrC8( KAuthInfoParamArray[ENfoAuthInfo] ) );
       
   214     CleanupClosePushL( authInfo );
       
   215     RStringF prxAuthInfo = spool.OpenFStringL( TPtrC8( KAuthInfoParamArray[ENfoPrxAuthInfo] ) );
       
   216     CleanupClosePushL( prxAuthInfo );
       
   217     if( aHeaders.GetRawField( authInfo, rawData ) == KErrNone ||
       
   218         aHeaders.GetRawField( prxAuthInfo, rawData ) == KErrNone )
       
   219         {
       
   220         TInt length = 0;
       
   221         HBufC8* tempCopy = rawData.AllocLC();
       
   222         TPtr8 modDesc( tempCopy->Des() );
       
   223         while( authOk && modDesc.Length() > 0 )
       
   224             {
       
   225             TPtrC8 value;
       
   226             TAuthInfoParam name = ( TAuthInfoParam )-1;
       
   227             if( ParseAuthInfoParam( length, name, value, modDesc ) )
       
   228                 authOk = iAuthManager.ConsumeAuthInfoParamL( name, value );
       
   229             modDesc.Delete( 0, length );
       
   230             modDesc.TrimLeft();
       
   231             }
       
   232         CleanupStack::PopAndDestroy();  //tempCopy
       
   233         }
       
   234     CleanupStack::PopAndDestroy( 2 );  //prxAuthInfo, authInfo
       
   235     return authOk;
       
   236     }
       
   237 
       
   238 // ----------------------------------------------------------
       
   239 // CXcapHttpAuthManager::ParseAuthInfoParam
       
   240 // 
       
   241 // ----------------------------------------------------------
       
   242 //
       
   243 TBool CXcapHttpResponse::ParseAuthInfoParam( TInt& aLength, TAuthInfoParam& aName, TPtrC8& aValue, TPtr8& aParam )
       
   244     {
       
   245     TBool found = EFalse;
       
   246     TInt delim = aParam.Locate( ',' );
       
   247     TPtrC8 param( delim > 0 ? aParam.Left( delim ) : aParam );
       
   248     TInt index = param.Locate( '=' );
       
   249     if( index > 0 )
       
   250         {
       
   251         TPtrC8 name( param.Left( index ) );
       
   252         TPtrC8 value( param.Mid( index + 1 ) );
       
   253         const TInt count = sizeof( KAuthInfoParamArray ) / sizeof( KAuthInfoParamArray[0] );
       
   254         for( TInt i = 0;!found && i < count;i++ )
       
   255             {
       
   256             if( name.CompareF( TPtrC8( KAuthInfoParamArray[i] ) ) == 0 )
       
   257                 {
       
   258                 aValue.Set( value );
       
   259                 aName = ( TAuthInfoParam )i;
       
   260                 found = ETrue;
       
   261                 }
       
   262             }
       
   263         }
       
   264     aLength = delim > 0 ? delim + 1 : aParam.Length();
       
   265     return found;
       
   266     }
       
   267 
       
   268                
       
   269 // ----------------------------------------------------------
       
   270 // CXcapHttpResponse::IsUnauthRequest
       
   271 // 
       
   272 // ----------------------------------------------------------
       
   273 //
       
   274 TBool CXcapHttpResponse::IsUnauthRequest( RHTTPTransaction aTransaction, TInt& aAuthType )
       
   275     {
       
   276     iUnauthRequestCounter++;
       
   277     TInt status = aTransaction.Response().StatusCode();
       
   278     switch( status )
       
   279         {
       
   280         case 401:  //Normal authentication
       
   281             aAuthType = 401;
       
   282             return ETrue;
       
   283         case 407:  //Proxy authentication
       
   284             aAuthType = 407;
       
   285             return ETrue;
       
   286         default:
       
   287             return EFalse;
       
   288         }
       
   289     }
       
   290        
       
   291 // ----------------------------------------------------------
       
   292 // CXcapHttpResponse::HandleReceivedBodyDataL
       
   293 // 
       
   294 // ----------------------------------------------------------
       
   295 //
       
   296 TBool CXcapHttpResponse::HandleReceivedBodyDataL( const RHTTPTransaction aTransaction )
       
   297     {
       
   298     #ifdef _DEBUG
       
   299         iTransportMain.WriteToLog( _L8( "CXcapHttpResponse::HandleReceivedBodyDataL()") );
       
   300     #endif
       
   301     TPtrC8 bodyData;
       
   302     MHTTPDataSupplier* respBody = aTransaction.Response().Body();
       
   303     TBool lastChunk = respBody->GetNextDataPart( bodyData );
       
   304     iHttpRequest->AppendDataL( bodyData );
       
   305     respBody->ReleaseData();
       
   306     return lastChunk;
       
   307     }
       
   308 
       
   309 // ----------------------------------------------------------
       
   310 // CImpsHttpTransactionSender::ContentLengthL
       
   311 // 
       
   312 // ----------------------------------------------------------
       
   313 //
       
   314 TInt CXcapHttpResponse::ContentLengthL() const
       
   315     {
       
   316     TInt retVal = KMaxTInt;
       
   317     THTTPHdrVal fieldValue;
       
   318     _LIT8( KContentLength, "Content-Length" );
       
   319     RHTTPHeaders headers = ResponseHeaderCollection();
       
   320     RStringPool stringPool = iHttpRequest->Session().StringPool();
       
   321     RStringF lengthString = stringPool.OpenFStringL( KContentLength );
       
   322     headers.GetField( lengthString, 0, fieldValue );
       
   323     lengthString.Close();
       
   324     if( fieldValue.Type() == THTTPHdrVal::KTIntVal )
       
   325         retVal = fieldValue.Int();
       
   326     return retVal;
       
   327     }
       
   328     
       
   329 // ----------------------------------------------------
       
   330 // CXcapHttpResponse::HeaderCollection
       
   331 // 
       
   332 // ----------------------------------------------------
       
   333 //
       
   334 RHTTPHeaders CXcapHttpResponse::ResponseHeaderCollection() const
       
   335     {
       
   336     return iHttpRequest->Transaction().Response().GetHeaderCollection();
       
   337     }
       
   338 
       
   339 // ----------------------------------------------------
       
   340 // CXcapHttpResponse::HeaderCollection
       
   341 // 
       
   342 // ----------------------------------------------------
       
   343 //
       
   344 RHTTPHeaders CXcapHttpResponse::RequestHeaderCollection() const
       
   345     {
       
   346     return iHttpRequest->Transaction().Request().GetHeaderCollection();
       
   347     }
       
   348 
       
   349 // ----------------------------------------------------
       
   350 // CXcapHttpResponse::MHFRunError
       
   351 // HTTP Stack callback interface
       
   352 // ----------------------------------------------------
       
   353 //
       
   354 TInt CXcapHttpResponse::MHFRunError( TInt /*aInt*/, RHTTPTransaction /*aTransaction*/,
       
   355                                     const THTTPEvent& /*aEvent*/ )
       
   356     {
       
   357     return KErrNone;
       
   358     }
       
   359     
       
   360 #ifdef _DEBUG
       
   361 // ----------------------------------------------------
       
   362 // CXcapHttpResponse::DumpHeadersL
       
   363 // 
       
   364 // ----------------------------------------------------
       
   365 //
       
   366 void CXcapHttpResponse::DumpHeadersL( RHTTPHeaders aHeaders, TInt aId )
       
   367     {
       
   368     iTransportMain.WriteToLog( _L( "--------------------") );
       
   369     iTransportMain.WriteToLog( _L( "Headers of the transaction %d: "), aId );
       
   370     RStringPool strP = iHttpRequest->Session().StringPool();
       
   371     THTTPHdrFieldIter it = aHeaders.Fields();
       
   372     TBuf<KMaxHeaderNameLen>  fieldName16;
       
   373     TBuf<KMaxHeaderValueLen> fieldVal16;
       
   374 
       
   375     while( it.AtEnd() == EFalse )
       
   376         {
       
   377         RStringTokenF fieldName = it();
       
   378         RStringF fieldNameStr = strP.StringF( fieldName );
       
   379         THTTPHdrVal fieldVal;
       
   380         if( aHeaders.GetField( fieldNameStr, 0, fieldVal ) == KErrNone )
       
   381             {
       
   382             const TDesC8& fieldNameDesC = fieldNameStr.DesC();
       
   383             fieldName16.Copy( fieldNameDesC.Left( KMaxHeaderNameLen ) );
       
   384             switch( fieldVal.Type() )
       
   385                 {
       
   386             case THTTPHdrVal::KTIntVal:
       
   387                 iTransportMain.WriteToLog( _L("%S: %d"), &fieldName16, fieldVal.Int() );
       
   388                 break;
       
   389             case THTTPHdrVal::KStrFVal:
       
   390                 {
       
   391                 RStringF fieldValStr = strP.StringF( fieldVal.StrF() );
       
   392                 const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   393                 fieldVal16.Copy( fieldValDesC.Left( KMaxHeaderValueLen ) );
       
   394                 iTransportMain.WriteToLog( _L( "%S: %S" ), &fieldName16, &fieldVal16 );
       
   395                 }
       
   396                 break;
       
   397             case THTTPHdrVal::KStrVal:
       
   398                 {
       
   399                 RString fieldValStr = strP.String(fieldVal.Str());
       
   400                 const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   401                 fieldVal16.Copy( fieldValDesC.Left( KMaxHeaderValueLen ) );
       
   402                 iTransportMain.WriteToLog( _L( "%S: %S" ), &fieldName16, &fieldVal16 );
       
   403                 }
       
   404                 break;
       
   405             case THTTPHdrVal::KDateVal:
       
   406                 {
       
   407                 TDateTime date = fieldVal.DateTime();
       
   408                 TBuf<40> dateTimeString;
       
   409                 TTime t(date);
       
   410                 t.FormatL( dateTimeString,KTransportDateFormat );
       
   411                 iTransportMain.WriteToLog( _L( "%S: %S" ), &fieldName16, &dateTimeString );
       
   412                 } 
       
   413                 break;
       
   414             default:
       
   415                 iTransportMain.WriteToLog( _L( "%S: <unrecognised value type>" ), &fieldName16 );
       
   416                 break;
       
   417                 }
       
   418             // Display realm for WWW-Authenticate header
       
   419             RStringF wwwAuth = strP.StringF( HTTP::EWWWAuthenticate, RHTTPSession::GetTable() );
       
   420             if( fieldNameStr == wwwAuth )
       
   421                 {
       
   422                 // check the auth scheme is 'basic'
       
   423                 RStringF basic = strP.StringF( HTTP::EBasic,RHTTPSession::GetTable() );
       
   424                 RStringF realm = strP.StringF( HTTP::ERealm,RHTTPSession::GetTable() );
       
   425                 THTTPHdrVal realmVal;
       
   426                 if ( (fieldVal.StrF() == basic ) && 
       
   427                     ( !aHeaders.GetParam(wwwAuth, realm, realmVal) ) )
       
   428                     {
       
   429                     RStringF realmValStr = strP.StringF( realmVal.StrF() );
       
   430                     fieldVal16.Copy( realmValStr.DesC() );
       
   431                     iTransportMain.WriteToLog( _L( "Realm is: %S" ), &fieldVal16 );
       
   432                     }
       
   433                 }
       
   434             }
       
   435         ++it;
       
   436         }
       
   437         iTransportMain.WriteToLog( _L( "--------------------") );
       
   438     }
       
   439     #endif
       
   440 
       
   441 // End of File  
       
   442