ncdengine/engine/transport/src/catalogshttprequestparser.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2007-2008 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:   Implements CCatalogsHttpRequestParser
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "catalogshttprequestparser.h"
       
    20 
       
    21 #include "catalogshttprequestparserobserver.h"
       
    22 #include "catalogshttpmessageconstants.h"
       
    23 #include "catalogsutils.h"
       
    24 
       
    25 #include "catalogsdebug.h"
       
    26 
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // 
       
    30 // ---------------------------------------------------------------------------
       
    31 //
       
    32 CCatalogsHttpRequestParser* CCatalogsHttpRequestParser::NewL()
       
    33     {
       
    34     CCatalogsHttpRequestParser* self = new( ELeave ) CCatalogsHttpRequestParser;
       
    35     return self;
       
    36     }
       
    37     
       
    38     
       
    39 // ---------------------------------------------------------------------------
       
    40 // 
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CCatalogsHttpRequestParser::~CCatalogsHttpRequestParser()
       
    44     {
       
    45     DeletePtr( iRequest );
       
    46     }
       
    47 
       
    48 
       
    49 // ---------------------------------------------------------------------------
       
    50 // 
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 void CCatalogsHttpRequestParser::ParseRequestL( 
       
    54     const TDesC8& aRequest,
       
    55     MCatalogsHttpRequestParserObserver& aObserver )
       
    56     {
       
    57     DLTRACEIN((""));
       
    58     if ( !aRequest.Size() ) 
       
    59         {
       
    60         DLERROR(("Empty request, leaving"));
       
    61         User::Leave( KErrArgument );
       
    62         }
       
    63     
       
    64     AssignDesL( iRequest, aRequest );    
       
    65     iLex.Assign( *iRequest );
       
    66     iObserver = &aObserver;
       
    67     iState = EParseStart;
       
    68     HandleStateL();
       
    69     
       
    70     DeletePtr( iRequest );
       
    71     }
       
    72 
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // 
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CCatalogsHttpRequestParser::CCatalogsHttpRequestParser()
       
    79     {
       
    80     }
       
    81 
       
    82 
       
    83 // ---------------------------------------------------------------------------
       
    84 // 
       
    85 // ---------------------------------------------------------------------------
       
    86 //
       
    87 void CCatalogsHttpRequestParser::HandleStateL()
       
    88     {
       
    89     DLTRACEIN((""));
       
    90     while( iState != EParseEnd ) 
       
    91         {
       
    92         
       
    93         switch( iState ) 
       
    94             {
       
    95             case EParseStart:
       
    96                 {
       
    97                 ParseStartLineL();
       
    98                 break;
       
    99                 }
       
   100                 
       
   101             case EParseHeaders:
       
   102                 {
       
   103                 ParseHeadersL();
       
   104                 break;
       
   105                 }
       
   106                 
       
   107             case EParseBody:
       
   108                 {
       
   109                 ParseBodyL();
       
   110                 break;
       
   111                 }
       
   112                 
       
   113             case EParseEnd:
       
   114                 {
       
   115                 DLTRACE(("End"));
       
   116                 break;
       
   117                 }
       
   118             
       
   119             default:
       
   120                 {
       
   121                 DASSERT( 0 );
       
   122                 }
       
   123             }
       
   124         }
       
   125     }
       
   126 
       
   127 // ---------------------------------------------------------------------------
       
   128 // 
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 void CCatalogsHttpRequestParser::ParseStartLineL()
       
   132     {
       
   133     DLTRACEIN((""));
       
   134     TPtrC8 method( KNullDesC8 );
       
   135     TPtrC8 uri( KNullDesC8 );
       
   136     TPtrC8 version( KNullDesC8 );
       
   137     
       
   138     ParseWordL( method );
       
   139     
       
   140     // Request-URI and HTTP-version are allowed to be missing
       
   141     TBool skippedEndOfLine = SkipEndOfLine();
       
   142     if ( !skippedEndOfLine )
       
   143         {        
       
   144         DLTRACE(("Parsing Request-URI"));
       
   145         ParseWordL( uri );
       
   146         
       
   147         skippedEndOfLine = SkipEndOfLine();
       
   148         if ( !skippedEndOfLine ) 
       
   149             {        
       
   150             DLTRACE(("Parsing HTTP-version"));
       
   151             ParseWordL( version );
       
   152             }
       
   153         }
       
   154     
       
   155     if ( skippedEndOfLine ) 
       
   156         {
       
   157         // Revert back to the end of the line so that CRLF counting in
       
   158         // ParseHeadersL works correctly
       
   159         iLex.UnGet();
       
   160         iLex.UnGet();
       
   161         }
       
   162     
       
   163     DASSERT( iObserver );
       
   164     iObserver->ParsedHttpRequestLineL( method, uri, version );
       
   165     iState = EParseHeaders;    
       
   166     }
       
   167 
       
   168 
       
   169 // ---------------------------------------------------------------------------
       
   170 // 
       
   171 // ---------------------------------------------------------------------------
       
   172 //
       
   173 void CCatalogsHttpRequestParser::ParseHeadersL()
       
   174     {
       
   175     DLTRACEIN((""));
       
   176     TPtrC8 header;
       
   177     TPtrC8 headerData;
       
   178     
       
   179     DASSERT( iObserver );
       
   180     
       
   181     while ( !iLex.Eos() && 
       
   182             // 1 CRLF means end of the line
       
   183             // 2 CRLFs means that headers ended and body begins
       
   184             SkipCrLfL() == 1 ) 
       
   185         {
       
   186         ParseWordL( header );
       
   187         TInt index = header.LocateReverse( 
       
   188             CatalogsHttpMessageConstants::KColon()[0] );
       
   189         if ( index == KErrNotFound ) 
       
   190             {
       
   191             DLERROR(("Invalid header"));
       
   192             User::Leave( KErrCorrupt );
       
   193             }
       
   194         ParseHeaderValueL( headerData );
       
   195         iObserver->ParsedHttpHeaderL( header.Left( index ), headerData );        
       
   196         }
       
   197     iState = EParseBody;    
       
   198     }
       
   199 
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // 
       
   203 // ---------------------------------------------------------------------------
       
   204 //
       
   205 void CCatalogsHttpRequestParser::ParseBodyL()
       
   206     {
       
   207     DLTRACEIN((""));
       
   208     DASSERT( iObserver );
       
   209     
       
   210     iObserver->ParsedHttpBodyL( iLex.Remainder() );
       
   211     iState = EParseEnd;
       
   212     }    
       
   213 
       
   214 
       
   215 // ---------------------------------------------------------------------------
       
   216 // 
       
   217 // ---------------------------------------------------------------------------
       
   218 //
       
   219 void CCatalogsHttpRequestParser::ParseWordL( 
       
   220     TPtrC8& aParsedWord )
       
   221     {
       
   222     DLTRACEIN((""));
       
   223 
       
   224     if ( iLex.Eos() ) 
       
   225         {
       
   226         DLERROR(("Out of data, leaving"));
       
   227         User::Leave( KErrCorrupt );
       
   228         }
       
   229     
       
   230     // skip space at beginning if any    
       
   231     iLex.SkipSpaceAndMark();
       
   232     
       
   233     // read only next word
       
   234     aParsedWord.Set( iLex.NextToken() );
       
   235 
       
   236     DLTRACE(("Word: %S", &aParsedWord ));
       
   237     }
       
   238 
       
   239 
       
   240 // ---------------------------------------------------------------------------
       
   241 // Parse header value
       
   242 // ---------------------------------------------------------------------------
       
   243 //
       
   244 void CCatalogsHttpRequestParser::ParseHeaderValueL( 
       
   245     TPtrC8& aParsedHeaderValue )
       
   246     {
       
   247     DLTRACEIN((""));
       
   248 
       
   249     if ( iLex.Eos() ) 
       
   250         {
       
   251         DLERROR(("Out of data, leaving"));
       
   252         User::Leave( KErrCorrupt );
       
   253         }
       
   254     
       
   255     // skip space at the beginning if any    
       
   256     iLex.SkipSpaceAndMark();
       
   257        
       
   258     while( !iLex.Eos() ) 
       
   259         {
       
   260         // If true, found end of line but we need to check if the header
       
   261         // continues on the next line
       
   262         if ( SkipEndOfLine() ) 
       
   263             {
       
   264             TChar peeked( iLex.Peek() );
       
   265             // headers span multiple lines if the next line starts with
       
   266             // at least one space or horizontal tab
       
   267             if ( peeked == CatalogsHttpMessageConstants::KSpace()[0] || 
       
   268                  peeked == CatalogsHttpMessageConstants::KHorizTab ) 
       
   269                 {
       
   270                 DLTRACE(("header spans on multiple lines"));
       
   271                 // Remove CrLf because platform components 
       
   272                 // will otherwise cut the header short
       
   273                 TInt current = iLex.Offset();
       
   274                 TPtr8 ptr( iRequest->Des() );
       
   275 
       
   276                 TInt length = CatalogsHttpMessageConstants::KCrLf().Length();
       
   277                 DLTRACE(("Length: %d", length));
       
   278                 
       
   279                 DLTRACE(("Deleting: %S", &ptr.Mid( current-length, length ) ));
       
   280                 ptr.Delete( current - length, length );
       
   281                 }
       
   282             else 
       
   283                 {
       
   284                 DLTRACE(("End of the header value"));
       
   285                 // revert back to the end of the last line so that
       
   286                 // we correctly identify the end of headers outside 
       
   287                 // this function
       
   288                 iLex.UnGet();
       
   289                 iLex.UnGet();
       
   290                 break;
       
   291                 }
       
   292             }
       
   293         else
       
   294             {            
       
   295             iLex.Inc();
       
   296             }
       
   297         }
       
   298     aParsedHeaderValue.Set( iLex.MarkedToken() );
       
   299 
       
   300     DLTRACE(("Word: %S", &aParsedHeaderValue ));
       
   301     }
       
   302     
       
   303     
       
   304 // ---------------------------------------------------------------------------
       
   305 // 
       
   306 // ---------------------------------------------------------------------------
       
   307 //
       
   308 TBool CCatalogsHttpRequestParser::SkipEndOfLine()
       
   309     {    
       
   310     if ( iLex.Peek() == CatalogsHttpMessageConstants::KCr  ) 
       
   311         {
       
   312         iLex.Inc();
       
   313         if ( iLex.Peek() == CatalogsHttpMessageConstants::KLf ) 
       
   314             {
       
   315             iLex.Inc();
       
   316             return ETrue;
       
   317             }
       
   318         // revert back to original index
       
   319         iLex.UnGet();
       
   320         }
       
   321     return EFalse;
       
   322     }
       
   323 
       
   324 
       
   325 // ---------------------------------------------------------------------------
       
   326 // 
       
   327 // ---------------------------------------------------------------------------
       
   328 //
       
   329 TInt CCatalogsHttpRequestParser::SkipCrLfL() 
       
   330     {
       
   331     TInt count = 0;
       
   332 
       
   333     while ( !iLex.Eos() ) 
       
   334         {
       
   335         if ( iLex.Peek() == CatalogsHttpMessageConstants::KCr ) 
       
   336             {
       
   337             iLex.Inc();
       
   338 
       
   339             if ( iLex.Peek() == CatalogsHttpMessageConstants::KLf ) 
       
   340                 {
       
   341                 iLex.Inc();
       
   342                 }
       
   343             else 
       
   344                 {
       
   345                 DLERROR(("LF should have followed CR"));
       
   346                 User::Leave( KErrCorrupt );
       
   347                 }
       
   348             count++;
       
   349             }
       
   350         else // nothing to skip
       
   351             {
       
   352             break;
       
   353             }
       
   354         }
       
   355     return count;     
       
   356     }