javacommons/gcfprotocols/http/src.s60/chttptransactionclient.cpp
changeset 21 2a9601315dfc
child 23 98ccebc37403
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*
       
     2 * Copyright (c) 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:  CHttpTransactionClient
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <http/rhttpresponse.h>
       
    20 #include <http/rhttpheaders.h>
       
    21 #include <httpstringconstants.h>
       
    22 #include <http/thttphdrval.h>
       
    23 #include <http/mhttpauthenticationcallback.h>
       
    24 #include <httperr.h>
       
    25 #include <stringpool.h>
       
    26 #include <e32svr.h>
       
    27 #include <x509cert.h>
       
    28 #include <ssl.h>
       
    29 #include "logger.h"
       
    30 #include "chttptransactionclient.h"
       
    31 #include "httpsessionclient.h"
       
    32 #include "chttpscertinfo.h"
       
    33 #include "mrefhttpclientobserver.h"
       
    34 
       
    35 
       
    36 _LIT8(KSeperator , ";;");
       
    37 _LIT8(KComma , ",");
       
    38 _LIT8(KDot , ".");
       
    39 _LIT8(KCommaSpace , ", ");
       
    40 _LIT8(KSemiColonSpace , "; ");
       
    41 _LIT8(KEquals , "=");
       
    42 _LIT8(KDRMHeader1,"application/vnd.oma.drm.content");
       
    43 _LIT8(KDRMHeader2,"application/vnd.oma.drm.message");
       
    44 
       
    45 // A maximum length of the cipher suite description strings,
       
    46 // see CipherSuiteDescription().
       
    47 const TUint8 KMaxCipherSuiteDescriptionLength = 40;
       
    48 
       
    49 const TInt KCookieBufferAllocLength = 4096;
       
    50 
       
    51 
       
    52 CHttpTransactionClient::CHttpTransactionClient(HttpSessionClient& aSession, MRefHttpClientObserver* aObserver)
       
    53         :iHttpSession(aSession) , iObserver(aObserver), iReleasedData(ETrue),iClosing(EFalse)
       
    54 {}
       
    55 
       
    56 
       
    57 CHttpTransactionClient* CHttpTransactionClient::NewL(HttpSessionClient& aSession,
       
    58         MRefHttpClientObserver* aObserver,
       
    59         const TDesC* aUri,
       
    60         const TDesC* aRequestMethod)
       
    61 {
       
    62     CHttpTransactionClient* self =  new(ELeave) CHttpTransactionClient(aSession,aObserver);
       
    63     CleanupStack::PushL(self);
       
    64     self->ConstructL(aUri, aRequestMethod);
       
    65     CleanupStack::Pop(self);
       
    66     return self;
       
    67 }
       
    68 
       
    69 void CHttpTransactionClient::ConstructL(const TDesC* aUri, const TDesC* aRequestMethod)
       
    70 {
       
    71     //open the transaction
       
    72     LOG(ESOCKET,EInfo, "CHttpTransactionClient::ConstructL ");
       
    73     iFlag = 0;
       
    74     iDrmBuf = HBufC8::NewL(256);
       
    75     OpenTransactionL(aUri , aRequestMethod);
       
    76 }
       
    77 
       
    78 void CHttpTransactionClient::OpenTransactionL(const TDesC* aUri, const TDesC* aRequestMethod)
       
    79 {
       
    80     LOG(ESOCKET,EInfo,"CHttpTransactionClient::OpenTransactionL + ");
       
    81     TUriParser8 uri;
       
    82     HBufC8* uriBuf= HBufC8::NewLC(aUri->Length());
       
    83     TPtr8 uriPtr = uriBuf->Des();
       
    84     uriPtr.Copy(*aUri);
       
    85     uri.Parse(*uriBuf);
       
    86     //Get Request Method String
       
    87     TBuf8<32> reqestType; //GET //POST // HEAD // Only options available in Midp 2.0 Http
       
    88 
       
    89     LOG(ESOCKET,EInfo,"Open TransactionL : Transaction Uri  ");
       
    90     reqestType.Copy(*aRequestMethod);
       
    91     LOG(ESOCKET,EInfo,"Open TransactionL : ReqestType ");
       
    92 
       
    93     RStringF requestMethoStr = iHttpSession.Session().StringPool().OpenFStringL(reqestType);
       
    94     CleanupClosePushL(requestMethoStr);
       
    95     iTransaction = iHttpSession.Session().OpenTransactionL(uri,*this,requestMethoStr);
       
    96 
       
    97     CleanupStack::PopAndDestroy(2);//requestMethoStr// uriBuf
       
    98     LOG(ESOCKET,EInfo,"CHttpTransactionClient::OpenTransactionL - ");
       
    99 }
       
   100 
       
   101 void CHttpTransactionClient::SubmitL(RPointerArray<HBufC8>* aRawHeaders , TDesC8* aPostData, int aResponseTimeout)
       
   102 {
       
   103     //ELOG(ESOCKET,"CHttpTransactionClient::SubmitL + ");
       
   104     //retrieve the headers
       
   105     TInt respTimeOut = aResponseTimeout;
       
   106     delete iBuf;
       
   107     iBuf=NULL;
       
   108     if (aPostData!=NULL && aPostData->Length()>0)
       
   109     {
       
   110         HBufC8* buf = aPostData->AllocL();
       
   111         iBuf=buf;
       
   112         LOG(ESOCKET,EInfo,"SubmitL : Posting Data ");
       
   113     }
       
   114 
       
   115     // Disable pipelining on this transaction
       
   116     RStringPool stringPool = iHttpSession.Session().StringPool();
       
   117     RStringF property = stringPool.StringF(HTTP::EHttpPipelining, RHTTPSession::GetTable());
       
   118     THTTPHdrVal disablePipelining = stringPool.StringF(HTTP::EDisablePipelining, RHTTPSession::GetTable());
       
   119     iTransaction.PropertySet().SetPropertyL(property, disablePipelining);
       
   120 
       
   121     if (respTimeOut != -1)
       
   122     {
       
   123         LOG1(ESOCKET,EInfo,"Setting response timeout to http stack with value = %d ",aResponseTimeout);
       
   124         property = stringPool.StringF(HTTP::EReceiveTimeOutValue, RHTTPSession::GetTable());
       
   125         THTTPHdrVal responseTimeout(respTimeOut);
       
   126         iTransaction.PropertySet().SetPropertyL(property, responseTimeout);
       
   127     }
       
   128 
       
   129     //Submit the transaction
       
   130     RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
       
   131     TInt headerCount = aRawHeaders->Count();
       
   132     for (TInt ii=0; ii < headerCount; ++ii)
       
   133     {
       
   134         SetHeaderL(hdr, (*aRawHeaders)[ii]);
       
   135     }
       
   136 
       
   137     //iHttpSession.CustomiseHeadersL(hdr);
       
   138 
       
   139     //Set Data
       
   140     if (iBuf && iBuf->Length() > KErrNone)
       
   141         iTransaction.Request().SetBody(*this);
       
   142     /* The data will be requested from MHttpDataSupplier*/
       
   143     iJavaWaitingOnCallBack=ETrue;
       
   144     iJavaWaitingOnReadCallBack=ETrue; // Assume somebody opened an input Stream
       
   145     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::SubmitL :iTransaction.Id %d ",iTransaction.Id());
       
   146     TRAP_IGNORE(iTransaction.SubmitL());
       
   147     LOG(ESOCKET,EInfo,"CHttpTransactionClient::SubmitL - ");
       
   148 }
       
   149 
       
   150 
       
   151 void CHttpTransactionClient::SetHeaderL(RHTTPHeaders& aHeaders, const TDesC8* aRawField)
       
   152 {
       
   153     /*Raw Headers are passed in from java of the format
       
   154     * ValueKey ;; property
       
   155     * HTTP requires all request properties which can legally have
       
   156     * multiple instances with the same key to use a comma-separated list
       
   157     * syntax which enables multiple properties to be appended into a
       
   158     * single property.
       
   159     */
       
   160     //Find the value field
       
   161     //Seperated from values in Java by KSeperator
       
   162     TInt valueIndex = aRawField->Find(KSeperator);
       
   163     User::LeaveIfError(valueIndex);
       
   164     TPtrC8 value =aRawField->Left(valueIndex);
       
   165     RStringF valueF = iHttpSession.Session().StringPool().OpenFStringL(value);
       
   166     CleanupClosePushL(valueF);
       
   167     TPtrC8 propertyRaw= aRawField->Mid(valueIndex+2);
       
   168     LOG(ESOCKET,EInfo,"CHttpTransactionClient Add header value ");
       
   169     aHeaders.SetRawFieldL(valueF, propertyRaw , KComma);
       
   170     CleanupStack::PopAndDestroy();//valueF
       
   171 }
       
   172 
       
   173 void CHttpTransactionClient::GetResponseL(RPointerArray<HBufC8>* aRawHeaders)
       
   174 {
       
   175     LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetResponseL(RPointerArray<HBufC8>* aRawHeaders)");
       
   176     RStringPool strP = iTransaction.Session().StringPool();
       
   177     //First element in response array is the status line of the form
       
   178     //HTTP-Version (major.minor) ;; Status-Code ;; Reason-Phrase
       
   179     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::GetResponseL :iTransaction.Id %d ",iTransaction.Id());
       
   180     RHTTPResponse response = iTransaction.Response();
       
   181 
       
   182     TInt statusLineLength=0;
       
   183 
       
   184     //HTTP-Version
       
   185     TVersion serverVersion = response.Version();
       
   186     TBuf<16> major;
       
   187     major.Num(serverVersion.iMajor);
       
   188     TBuf<16> minor;
       
   189     minor.Num(serverVersion.iMinor);
       
   190     statusLineLength+=major.Length();
       
   191     statusLineLength+=1;//KDot
       
   192     statusLineLength+=minor.Length();
       
   193 
       
   194     //Status code
       
   195     TBuf<16> stausCode;
       
   196     TInt serverStatusCode = response.StatusCode();
       
   197     stausCode.Num(serverStatusCode);
       
   198     statusLineLength+=stausCode.Length();
       
   199 
       
   200     //Status Text
       
   201     RStringF serverResponseTextF = response.StatusText();
       
   202     statusLineLength+= serverResponseTextF.DesC().Length();
       
   203 
       
   204     //Sepearators KSeperator *2
       
   205     statusLineLength+=4;//
       
   206 
       
   207     HBufC8* responseText = HBufC8::NewLC(statusLineLength);
       
   208     //Create Status Line
       
   209     //Version
       
   210     responseText->Des().Append(major);
       
   211     responseText->Des().Append(KDot);
       
   212     responseText->Des().Append(minor);
       
   213     //Status Code
       
   214     responseText->Des().Append(KSeperator);
       
   215     responseText->Des().Append(stausCode);
       
   216     //Status Text
       
   217     responseText->Des().Append(KSeperator);
       
   218     responseText->Des().Append(serverResponseTextF.DesC());
       
   219     aRawHeaders->Append(responseText);
       
   220     CleanupStack::Pop(responseText);
       
   221 
       
   222     //Package up all the transaction headers in to an array of java strings
       
   223     RHTTPHeaders headers =response.GetHeaderCollection();
       
   224     THTTPHdrFieldIter it = headers.Fields();
       
   225     RStringTokenF token;
       
   226     RStringF fieldNameStr;
       
   227     TPtrC8 rawFldPtr;
       
   228     HBufC8* rawHeader = NULL; // field name  and values
       
   229     TInt rawFieldLength=0;
       
   230     do
       
   231     {
       
   232         token = it();
       
   233         fieldNameStr=strP.StringF(token);
       
   234         //Get the field data assume we get comma seperated values and
       
   235         //don't have to use aPartIdx
       
   236 
       
   237         RStringF setCookie = strP.StringF(HTTP::ESetCookie,RHTTPSession::GetTable());
       
   238         if (fieldNameStr == setCookie)
       
   239         {
       
   240             // Buffer for storing a single cookie
       
   241             HBufC8* cookieBuf = HBufC8::NewLC(KCookieBufferAllocLength);
       
   242 
       
   243             cookieBuf->Des().Append(fieldNameStr.DesC());
       
   244             cookieBuf->Des().Append(KSeperator);
       
   245             iMinLength = cookieBuf->Des().Length();
       
   246 
       
   247             TInt totalCookiesLength = 0;
       
   248             TInt cookieCount = headers.FieldPartsL(setCookie);
       
   249 
       
   250             if (cookieCount != 0)
       
   251             {
       
   252                 for (TInt ii = 0; ii < cookieCount; ii++)
       
   253                 {
       
   254                     iDiscardCookie = false;
       
   255                     StoreOneCookieL(cookieBuf, headers, ii, setCookie);
       
   256                     if (ii < cookieCount-1)
       
   257                     {
       
   258                         // Replace last semicolon with comma
       
   259                         if (iDiscardCookie!=true)
       
   260                         {
       
   261                             cookieBuf->Des().SetLength(cookieBuf->Des().Length() - KSemiColonSpace().Length());
       
   262                             cookieBuf->Des().Append(KCommaSpace);
       
   263                         }
       
   264                         else
       
   265                         {
       
   266                             cookieBuf->Des().Append(KCommaSpace);
       
   267                         }
       
   268                     }
       
   269 
       
   270                     if (ii > 0)
       
   271                     {
       
   272                         totalCookiesLength += cookieBuf->Des().Length();
       
   273                         rawHeader = rawHeader->ReAllocL(totalCookiesLength);
       
   274                         rawHeader->Des().Append(*cookieBuf);
       
   275                     }
       
   276                     else
       
   277                     {
       
   278                         rawHeader = cookieBuf->AllocL();
       
   279                         totalCookiesLength = rawHeader->Length();
       
   280                     }
       
   281 
       
   282                     cookieBuf->Des().Zero();
       
   283                 }
       
   284             }
       
   285             else
       
   286             {
       
   287                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetResponseL 'Set-Cookie:' header field is empty");
       
   288                 rawHeader = cookieBuf->AllocL();
       
   289             }
       
   290 
       
   291             CleanupStack::PopAndDestroy(cookieBuf);
       
   292             aRawHeaders->Append(rawHeader);
       
   293         }
       
   294         else
       
   295         {
       
   296             TInt err = headers.GetRawField(fieldNameStr,rawFldPtr);
       
   297 
       
   298             // Work around for DRM download
       
   299 //          RStringF contentType = strP.StringF(HTTP::EContentType,RHTTPSession::GetTable());
       
   300 //          if (fieldNameStr == contentType)
       
   301 //          {
       
   302 //                  LOG(ESOCKET,EInfo,"content type header is  present");
       
   303 //                  TInt index = rawFldPtr.Match(KDRMHeader1);
       
   304 //                  //  LOG1(ESOCKET,EInfo,"rawFldPtr = %s ",rawFldPtr.str());
       
   305 //                      LOG1(ESOCKET,EInfo,"index of drm header is = %d",index);
       
   306 //              if(index == 0)
       
   307 //              {
       
   308 //                      iDrmDownload = true;
       
   309 //              }
       
   310 //              else
       
   311 //              {
       
   312 //                      index = rawFldPtr.Match(KDRMHeader2);
       
   313 //                      if(index == 0)
       
   314 //                              iDrmDownload = true;
       
   315 //              }
       
   316 //          }
       
   317             if (err==KErrNone)
       
   318             {
       
   319                 rawFieldLength += fieldNameStr.DesC().Length();
       
   320                 rawFieldLength += 2;//KSeperator Length;
       
   321                 rawFieldLength += rawFldPtr.Length();
       
   322                 rawHeader = HBufC8::NewL(rawFieldLength);
       
   323                 rawHeader->Des().Append(fieldNameStr.DesC());
       
   324                 rawHeader->Des().Append(KSeperator);
       
   325                 rawHeader->Des().Append(rawFldPtr);
       
   326                 aRawHeaders->Append(rawHeader);
       
   327                 rawFieldLength=0;
       
   328             }
       
   329         }
       
   330         ++it;
       
   331     }
       
   332     while (!it.AtEnd());
       
   333 }
       
   334 
       
   335 // RHTTPResponse CHttpTransactionClient::GetResponseL()
       
   336 //  {
       
   337 //  LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetResponseL");
       
   338 //  return iTransaction.Response();
       
   339 //  }
       
   340 /*
       
   341 * Returns the total number of bytes read into the buffer,
       
   342 * or -1 if there is no more data because the end of the stream
       
   343 * has been reached.
       
   344 */
       
   345 TInt CHttpTransactionClient::ReadBytes(TDes8& aBytesPtr)
       
   346 {
       
   347     LOG(ESOCKET,EInfo,"CHttpTransactionClient:: ReadBytes");
       
   348     TInt maxBufLength = aBytesPtr.MaxLength();
       
   349     TInt bodyDataPartLength = 0;
       
   350     if (iDrmDownload == false)
       
   351     {
       
   352         bodyDataPartLength = iBuf->Length();
       
   353     }
       
   354     else
       
   355     {
       
   356         bodyDataPartLength = iDrmBuf->Length();
       
   357     }
       
   358     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: maxRead: %d," , maxBufLength);
       
   359     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: bodyDataPartLength:: %d " ,bodyDataPartLength);
       
   360     TInt bytesRead = (maxBufLength+iJavaReadOffset > bodyDataPartLength) ? (bodyDataPartLength - iJavaReadOffset) : maxBufLength;
       
   361     if (bytesRead>0)
       
   362     {
       
   363         LOG1(ESOCKET,EInfo,"Bytes read : %d " ,bytesRead);
       
   364 
       
   365         if (iDrmDownload == false)
       
   366         {
       
   367             TPtrC8 bufPtr = iBuf->Mid(iJavaReadOffset,bytesRead);
       
   368             aBytesPtr.Copy(bufPtr);
       
   369         }
       
   370         else
       
   371         {
       
   372             TPtrC8 bufPtr = iDrmBuf->Mid(iJavaReadOffset,bytesRead);
       
   373             aBytesPtr.Copy(bufPtr);
       
   374         }
       
   375 
       
   376         LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: iJavaReadOffset:: %d " ,iJavaReadOffset);
       
   377         if (iDrmDownload == false)
       
   378         {
       
   379             if ((iJavaReadOffset+bytesRead) == bodyDataPartLength && iLastChunk)
       
   380             {
       
   381                 //All body data from the http transaction has been read
       
   382                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: EOF iLastChunk");
       
   383                 iRead = ETrue;
       
   384 
       
   385                 iJavaWaitingOnReadCallBack=EFalse;
       
   386                 TRAP_IGNORE(iObserver->DataReadyForRead(-1));
       
   387             }
       
   388         }
       
   389         else
       
   390         {
       
   391             if ((iJavaReadOffset+bytesRead) == iDrmBuf->Length() && iLastChunk)
       
   392             {
       
   393                 //All DRM body data from the http transaction has been read
       
   394                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: EOF iLastChunk");
       
   395                 iRead = ETrue;
       
   396 
       
   397                 iJavaWaitingOnReadCallBack=EFalse;
       
   398                 TRAP_IGNORE(iObserver->DataReadyForRead(-1));
       
   399             }
       
   400         }
       
   401     } // if(bytesread > 0)
       
   402     if ((iJavaReadOffset+bytesRead)<=bodyDataPartLength)
       
   403     {
       
   404 
       
   405         if (iJavaReadOffset+bytesRead < bodyDataPartLength)
       
   406         {
       
   407             //Java hasn't read all the current body data buffer, inform java
       
   408             //amount of bytes left to read in buffer.
       
   409 
       
   410             iJavaReadOffset+=bytesRead;
       
   411             TInt  bytesLeftInBuffer = bodyDataPartLength-iJavaReadOffset;
       
   412             LOG1(ESOCKET,EInfo," CHttpTransactionClient::ReadBytes: bytesLeftInBuffer: %d",bytesLeftInBuffer);
       
   413             //Unblock java so it can read the remaining buffered data
       
   414             iJavaWaitingOnReadCallBack=ETrue;
       
   415             TRAP_IGNORE(iObserver->DataReadyForRead(bytesLeftInBuffer));
       
   416         }
       
   417         else
       
   418         {
       
   419             // in this call, the iBuf data was completely read, so call release data to get the next chunk(part) of body from
       
   420             // the native stack
       
   421 
       
   422             if (iDrmDownload == false)
       
   423             {
       
   424                 // Non-Drm case, offset is reset to 0, starting reading newly from iBuf from the next call
       
   425                 iJavaReadOffset=0;
       
   426                 LOG(ESOCKET,EInfo,"CHttpTransactionClient:: ReadBytes ReleaseData!");
       
   427                 iReleasedData=ETrue;
       
   428                 if (iBuf)
       
   429                 {
       
   430                     delete iBuf;
       
   431                     iBuf = NULL;
       
   432                 }
       
   433                 iRespBody->ReleaseData();   // tell the stack to send the next response body data, stack will call mhfrunl after this
       
   434             }
       
   435             else
       
   436             {
       
   437                 // DRM file download, index is never reset to 0 , continue reading from drm buffer
       
   438                 iJavaReadOffset+=bytesRead;
       
   439 
       
   440             }
       
   441 
       
   442         }
       
   443 
       
   444     }
       
   445 
       
   446     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: return bytesRead %d " , bytesRead);
       
   447     return bytesRead;
       
   448 }
       
   449 
       
   450 
       
   451 
       
   452 void CHttpTransactionClient::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   453 {
       
   454     LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL +");
       
   455 
       
   456     if (iTransaction== aTransaction)
       
   457     {
       
   458         LOG1(ESOCKET,EInfo,"before switch aEvent.iStatus = %d ",aEvent.iStatus);
       
   459         switch (aEvent.iStatus)
       
   460         {
       
   461         case THTTPEvent::ESubmit:
       
   462             LOG1(ESOCKET,EInfo,"MHFRunL::ESubmit : aEvent.iStatus = %d",aEvent.iStatus);
       
   463             iStatus= CHttpTransactionClient::ESubmitted;
       
   464             //Only send an event to Java when we've got a response
       
   465             break;
       
   466         case THTTPEvent::ECancel:
       
   467             LOG(ESOCKET,EInfo,"MHFRunL::ECancel");
       
   468             iStatus =CHttpTransactionClient:: ECancelled;
       
   469             if (iJavaWaitingOnCallBack)
       
   470             {
       
   471                 iObserver->SubmitComplete(iStatus);
       
   472                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL ECancel ");
       
   473                 iJavaWaitingOnCallBack=EFalse;
       
   474             }
       
   475 
       
   476             if (iJavaWaitingOnReadCallBack)
       
   477             {
       
   478                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   479                 iJavaWaitingOnCallBack=EFalse;
       
   480                 iObserver->DataReadyForRead(-1);
       
   481             }
       
   482 
       
   483             break;
       
   484         case THTTPEvent::EClosed:
       
   485             LOG(ESOCKET,EInfo,"MHFRunL::EClosed");
       
   486             iStatus = CHttpTransactionClient::EClosed;
       
   487             if (iJavaWaitingOnCallBack)
       
   488             {
       
   489                 iJavaWaitingOnCallBack=EFalse;
       
   490                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL EClosed");
       
   491                 iObserver->SubmitComplete(iStatus);
       
   492             }
       
   493             if (iJavaWaitingOnReadCallBack)
       
   494             {
       
   495                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   496                 iJavaWaitingOnCallBack=EFalse;
       
   497                 iObserver->DataReadyForRead(-1);
       
   498             }
       
   499 
       
   500             break;
       
   501             /*Receiving transaction events*/
       
   502         case THTTPEvent::EGotResponseTrailerHeaders:
       
   503         {
       
   504             LOG(ESOCKET,EInfo,"MHFRunL  EGotResponseTrailerHeaders");
       
   505             iStatus= CHttpTransactionClient::EGotResponse;
       
   506             break;
       
   507         }
       
   508         case THTTPEvent::ESucceeded:
       
   509         {
       
   510             LOG(ESOCKET,EInfo,"MHFRunL ESucceeded");
       
   511             break;
       
   512         }
       
   513         case THTTPEvent::EGotResponseHeaders:
       
   514         {
       
   515             LOG(ESOCKET,EInfo,"MHFRunL EGotResponseHeaders");
       
   516             iStatus = CHttpTransactionClient::EGotResponse;
       
   517             //If  we are secure attempt to get the security information.
       
   518             //At the moment the native HTTP stack only allows us to retrieve
       
   519             //Server cert info after and a submission and before the transaction is
       
   520             //complete, ignore any warnings as we may not be in sercure mode
       
   521 
       
   522             RStringPool strP = iTransaction.Session().StringPool();
       
   523             RHTTPResponse response = iTransaction.Response();
       
   524             RHTTPHeaders headers =response.GetHeaderCollection();
       
   525             THTTPHdrFieldIter it = headers.Fields();
       
   526             RStringTokenF token;
       
   527             RStringF fieldNameStr;
       
   528             TPtrC8 rawFldPtr;
       
   529             do
       
   530             {
       
   531                 token = it();
       
   532                 fieldNameStr=strP.StringF(token);
       
   533                 // Work around for DRM download
       
   534                 RStringF contentType = strP.StringF(HTTP::EContentType,RHTTPSession::GetTable());
       
   535                 if (fieldNameStr == contentType)
       
   536                 {
       
   537                     //LOG(ESOCKET,EInfo,"content type header is  present");
       
   538                     TInt err = headers.GetRawField(fieldNameStr,rawFldPtr);
       
   539                     TInt index = rawFldPtr.Match(KDRMHeader1);
       
   540                     //  LOG1(ESOCKET,EInfo,"rawFldPtr = %s ",rawFldPtr.str());
       
   541                     //LOG1(ESOCKET,EInfo,"index of drm header is = %d",index);
       
   542                     if (index == 0)
       
   543                     {
       
   544                         iDrmDownload = true;
       
   545                     }
       
   546                     else
       
   547                     {
       
   548                         index = rawFldPtr.Match(KDRMHeader2);
       
   549                         if (index == 0)
       
   550                             iDrmDownload = true;
       
   551                     }
       
   552                 }
       
   553                 ++it;
       
   554             }
       
   555             while (!it.AtEnd());
       
   556 
       
   557             GetSecurityInfo();
       
   558             if (iJavaWaitingOnCallBack)
       
   559             {
       
   560                 iJavaWaitingOnCallBack=EFalse;
       
   561                 //LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL Notifiy Java Got Response");
       
   562                 iObserver->SubmitComplete(iStatus);
       
   563             }
       
   564             break;
       
   565         }
       
   566         case THTTPEvent::EResponseComplete:
       
   567         {
       
   568             LOG(ESOCKET,EInfo,"MHFRunL EResponseComplete");
       
   569             if (iJavaWaitingOnReadCallBack)
       
   570             {
       
   571                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   572                 iJavaWaitingOnCallBack=EFalse;
       
   573                 iStatus=CHttpTransactionClient::EComplete;
       
   574                 if (iDrmDownload == false)
       
   575                     iObserver->DataReadyForRead(-1);
       
   576             }
       
   577 
       
   578             break;
       
   579         }
       
   580         case THTTPEvent::EUnrecoverableError:
       
   581         case THTTPEvent::ETooMuchRequestData:
       
   582         case THTTPEvent::EFailed:
       
   583         {
       
   584             LOG(ESOCKET,EInfo, "MHFRunL EUnrecoverableError/EFailed");
       
   585             iStatus=CHttpTransactionClient::EFailed;
       
   586             NotifyErrorL(iStatus);
       
   587             break;
       
   588         }
       
   589         case THTTPEvent::EGotResponseBodyData:
       
   590         {
       
   591             LOG(ESOCKET,EInfo,"MHFRunL EGotResponseBodyData");
       
   592             iReleasedData=EFalse;
       
   593             //More data is ready for Java to read.
       
   594             iRespBody = aTransaction.Response().Body();
       
   595 
       
   596             TPtrC8 bodyData;
       
   597             iStatus=KErrNotReady;
       
   598             //We may be closing if so we don't want to request more data.
       
   599             if (!iClosing)
       
   600             {
       
   601                 if (iDrmDownload == true)
       
   602                 {
       
   603                     iFlag = iFlag + 1;
       
   604                     iLastChunk = iRespBody->GetNextDataPart(bodyData);
       
   605                     TInt curLen = iDrmBuf->Length();
       
   606                     TInt reqLen = curLen + bodyData.Length();
       
   607                     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL DRM case  bodyData.Length() = %d",bodyData.Length());
       
   608                     TRAP_IGNORE((iDrmBuf = iDrmBuf->ReAllocL(reqLen + bodyData.Length())));
       
   609                     TPtr8 bodyPtr1 = iDrmBuf->Des();
       
   610                     //HBufC8* bodyBuffer1 = HBufC8::NewLC(bodyData.Length());
       
   611                     LOG1(ESOCKET,EInfo,"length of iDrmBuf = %d", iDrmBuf->Length());
       
   612                     bodyPtr1.Append(bodyData);
       
   613                     iRespBody->ReleaseData();
       
   614 
       
   615 
       
   616                     iStatus = CHttpTransactionClient::EGotResponseBodyData;
       
   617                     //if(iFlag == 1)
       
   618                     TInt bodyDataPartLength;
       
   619                     bodyDataPartLength = iDrmBuf->Length();
       
   620                     TInt  bytesLeftInBuffer = bodyDataPartLength-iJavaReadOffset;
       
   621                     if (bytesLeftInBuffer > 0)
       
   622                         iObserver->DataReadyForRead(bytesLeftInBuffer);
       
   623                 }
       
   624                 else
       
   625                 {
       
   626                     iLastChunk = iRespBody->GetNextDataPart(bodyData);
       
   627                     HBufC8* bodyBuffer = HBufC8::NewLC(bodyData.Length());
       
   628                     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL after getnextdatapart ,bodyData.Length() = %d",bodyData.Length());
       
   629                     TPtr8 bodyPtr = bodyBuffer->Des();
       
   630                     bodyPtr.Append(bodyData);
       
   631                     if (iBuf)
       
   632                     {
       
   633                         delete iBuf;
       
   634                         iBuf = NULL;
       
   635                     }
       
   636                     CleanupStack::Pop(bodyBuffer);
       
   637                     iBuf = bodyBuffer;
       
   638                     iStatus = CHttpTransactionClient::EGotResponseBodyData;
       
   639                     LOG(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL Notify got more data");
       
   640                     iObserver->DataReadyForRead(iStatus);
       
   641                 }
       
   642             }
       
   643 
       
   644             break;
       
   645         }
       
   646         case THTTPEvent::ENotifyNewRequestBodyPart:
       
   647         {
       
   648             LOG(ESOCKET,EInfo,"MHFRunL ENotifyNewRequestBodyPart");
       
   649             iStatus = CHttpTransactionClient::ERequestNextBodayData;
       
   650             break;
       
   651         }
       
   652         /*
       
   653         * -j2me expects the http stack to be able to post body data with no content type
       
   654         *   the native stack default validation filter does not allow this.
       
   655         * -j2me expects the http stack to allow post requests to have body data
       
   656         *   the native stack default validation filter does not allow this. */
       
   657         case KErrHttpEntityHeaderMissingContentType:
       
   658         case KErrHttpInvalidHeaderInRequest:
       
   659         case KErrHttpGeneralHeaderMissingHost:
       
   660             break;
       
   661 
       
   662         case THTTPEvent::ERedirectRequiresConfirmation:
       
   663         {
       
   664             LOG(ESOCKET,EInfo,"MHFRunL ERedirectRequiresConfirmation");
       
   665         }
       
   666         case THTTPEvent::ENeedTunnel:
       
   667         {
       
   668             LOG(ESOCKET,EInfo,"MHFRunL ENeedTunnel");
       
   669         }
       
   670         case THTTPEvent::EGetCipherSuite:
       
   671         {
       
   672             LOG(ESOCKET,EInfo,"MHFRunL EGetCipherSuite");
       
   673         }
       
   674         default:
       
   675         {
       
   676             LOG(ESOCKET,EInfo,"MHFRunL Unkown Event");
       
   677             //__ASSERT_DEBUGCOMP( EFalse, User::Panic(_L("Unhandled native Http event"), aEvent.iStatus) );
       
   678             NotifyErrorL(aEvent.iStatus);
       
   679             break;
       
   680         }
       
   681         };
       
   682     }
       
   683     LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL -");
       
   684 }
       
   685 
       
   686 TInt CHttpTransactionClient::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& /*aEvent*/)
       
   687 {
       
   688     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunError: %d ",aError);
       
   689     if (aError!=KErrNone && iTransaction== aTransaction)
       
   690     {
       
   691         iStatus=CHttpTransactionClient::EFailed;
       
   692         if (iJavaWaitingOnCallBack)
       
   693             iObserver->SubmitComplete(iStatus);
       
   694 
       
   695 
       
   696         if (iJavaWaitingOnReadCallBack)
       
   697         {
       
   698             LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   699             iJavaWaitingOnCallBack=EFalse;
       
   700             iObserver->DataReadyForRead(-1);
       
   701         }
       
   702 
       
   703     }
       
   704     return aError;
       
   705 }
       
   706 
       
   707 /*
       
   708 * Java may be waiting on an async call back
       
   709 * If this is the case notify of the error code so we don't block java.
       
   710 */
       
   711 
       
   712 void CHttpTransactionClient::NotifyErrorL(TInt aErrorCode)
       
   713 {
       
   714     LOG1(ESOCKET,EInfo," CHttpTransactionClient::NotifyErrorL: %d ",aErrorCode);
       
   715     if ((aErrorCode  ==  KErrNotReady))
       
   716     {
       
   717         iTransaction.Cancel();
       
   718         iHttpSession.RestartConnection();
       
   719 
       
   720 
       
   721     }
       
   722     if (iJavaWaitingOnCallBack)
       
   723     {
       
   724         iJavaWaitingOnCallBack=EFalse;
       
   725         LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL  Notifiy Java unknown Event");
       
   726         iObserver->SubmitComplete(aErrorCode);
       
   727     }
       
   728     if (iJavaWaitingOnReadCallBack)
       
   729     {
       
   730         LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   731         iJavaWaitingOnCallBack=EFalse;
       
   732         //Notify Java of error if it is waiting for a read
       
   733         iObserver->DataReadyForRead(-1);
       
   734     }
       
   735 
       
   736 }
       
   737 
       
   738 
       
   739 void CHttpTransactionClient::CloseTransaction()
       
   740 {
       
   741     //__ASSERT_DEBUGCOMP(iJavaWaitingOnCallBack==EFalse, User::Panic(_L("Http Java Waiting on notification"), KErrGeneral ));
       
   742     LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction + ");
       
   743     iClosing=ETrue;
       
   744     if (!iReleasedData)
       
   745     {
       
   746         LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction NOT RELEASED DATA!!! release and close");
       
   747         if (iDrmDownload == false)
       
   748             iRespBody->ReleaseData();
       
   749         iReleasedData=ETrue;
       
   750     }
       
   751     iTransaction.Close();
       
   752     iClosing=EFalse;
       
   753     LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction - ");
       
   754 }
       
   755 
       
   756 CHttpTransactionClient::~CHttpTransactionClient()
       
   757 {
       
   758     LOG(ESOCKET,EInfo,"CHttpTransactionClient::~CHttpTransactionClient");
       
   759     //CloseTransaction();
       
   760     if (iBuf)
       
   761     {
       
   762         delete iBuf;
       
   763         iBuf=NULL;
       
   764     }
       
   765     if (iDrmBuf)
       
   766     {
       
   767         delete iDrmBuf;
       
   768         iDrmBuf=NULL;
       
   769     }
       
   770     delete iCertInfo;
       
   771 }
       
   772 
       
   773 
       
   774 /** Obtain a data part from the supplier.  The data is guaranteed
       
   775     to survive until a call is made to ReleaseData().
       
   776     @param aDataPart - the data part
       
   777     @return ETrue if this is the last part. EFalse otherwise */
       
   778 TBool CHttpTransactionClient::GetNextDataPart(TPtrC8& aDataPart)
       
   779 {
       
   780     LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetNextDataPart");
       
   781     TBool lastPart=EFalse;
       
   782     if (iBuf!=NULL)
       
   783     {
       
   784         lastPart = ETrue;
       
   785         aDataPart.Set(iBuf->Des());
       
   786     }
       
   787     return lastPart;
       
   788 }
       
   789 
       
   790 /** Release the current data part being held at the data
       
   791     supplier.  This call indicates to the supplier that the part
       
   792     is no longer needed, and another one can be supplied, if
       
   793     appropriate.  */
       
   794 void CHttpTransactionClient::ReleaseData()
       
   795 {
       
   796     LOG(ESOCKET,EInfo," CHttpTransactionClient::ReleaseData: delete iBuf");
       
   797     if (iBuf)
       
   798     {
       
   799         delete iBuf;
       
   800         iBuf=NULL;
       
   801     }
       
   802 }
       
   803 
       
   804 /** Obtain the overall size of the data being supplied, if known
       
   805     to the supplier.  Where a body of data is supplied in several
       
   806     parts this size will be the sum of all the part sizes. If
       
   807     the size is not known, KErrNotFound is returned; in this case
       
   808     the client must use the return code of GetNextDataPart to find
       
   809     out when the data is complete.
       
   810 
       
   811     @return A size in bytes, or KErrNotFound if the size is not known.  */
       
   812 TInt CHttpTransactionClient::OverallDataSize()
       
   813 {
       
   814     TInt overallSize = KErrNotFound;
       
   815     if (iBuf)
       
   816     {
       
   817         overallSize=iBuf->Length();
       
   818     }
       
   819     LOG1(ESOCKET,EInfo," CHttpTransactionClient::OverallDataSize: %d",overallSize);
       
   820     return overallSize;
       
   821 }
       
   822 
       
   823 /** Reset the data supplier.  This indicates to the data supplier that it should
       
   824     return to the first part of the data.  This could be used in a situation where
       
   825     the data consumer has encountered an error and needs the data to be supplied
       
   826     afresh.  Even if the last part has been supplied (i.e. GetNextDataPart has
       
   827     returned ETrue), the data supplier should reset to the first part.
       
   828 
       
   829     If the supplier cannot reset it should return an error code; otherwise it should
       
   830     return KErrNone, where the reset will be assumed to have succeeded*/
       
   831 TInt CHttpTransactionClient::Reset()
       
   832 {
       
   833     LOG(ESOCKET,EInfo,"CHttpTransactionClient::Reset");
       
   834     TInt err = KErrNone;
       
   835     return err;
       
   836 }
       
   837 
       
   838 
       
   839 MNativeSecureConnectionInformation* CHttpTransactionClient::GetSecurityInfo()
       
   840 {
       
   841     //LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetSecurityInfo");
       
   842     MNativeSecureConnectionInformation* handle=NULL;
       
   843     if (!iCertInfo)
       
   844     {
       
   845         TRAP_IGNORE(GetCertInfoL());
       
   846         //If we fail to read the cert java is returned a null handle.
       
   847     }
       
   848     if (iCertInfo)
       
   849     {
       
   850         handle = iCertInfo;
       
   851     }
       
   852     return handle;
       
   853 }
       
   854 
       
   855 void CHttpTransactionClient::GetCertInfoL()
       
   856 {
       
   857     //LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetCertInfoL ");
       
   858     TCertInfo info;
       
   859 
       
   860     //Get the server certificate
       
   861     if (iCertInfo!=NULL)
       
   862     {
       
   863         delete iCertInfo;
       
   864         iCertInfo= NULL;
       
   865     }
       
   866     const CX509Certificate* cert = static_cast<const CX509Certificate*>(iTransaction.ServerCert());
       
   867 
       
   868     TInt err = iTransaction.ServerCert(info);
       
   869     if (err==KErrNone)
       
   870     {
       
   871         //Get the cipher suite
       
   872         const TDesC8& cipherCode = iTransaction.CipherSuite().DesC();
       
   873         if (!cipherCode.Length())
       
   874         {
       
   875             //LOG(ESOCKET,EInfo, "CHttpTransactionClient::GetCertInfoL No Cipher Suite Name found in Transaction");
       
   876             User::Leave(KErrNotFound);
       
   877         }
       
   878 
       
   879         HBufC* cipherSuiteBuf = HBufC::NewLC(KMaxCipherSuiteDescriptionLength);
       
   880 
       
   881         const TDesC8& cipherDesc = CipherSuiteDescription(cipherCode);
       
   882         if (cipherDesc.Length())
       
   883         {
       
   884             cipherSuiteBuf->Des().Copy(cipherDesc);
       
   885         }
       
   886         else
       
   887         {
       
   888             // We will use the code as no description is available.
       
   889             //LOG(ESOCKET,EInfo, "CHttpTransactionClient::GetCertInfoL No Cipher Suite description found");
       
   890             cipherSuiteBuf->Des().Copy(cipherCode);
       
   891         }
       
   892 
       
   893         CleanupStack::Pop(cipherSuiteBuf);
       
   894         iCertInfo= CHttpsCertInfo::NewL(*cert,cipherSuiteBuf);
       
   895     }
       
   896 }
       
   897 
       
   898 TInt CHttpTransactionClient::Available()
       
   899 {
       
   900     TInt avail=KErrNone;
       
   901     if (iBuf)
       
   902     {
       
   903         avail=(iBuf->Length()-iJavaReadOffset);
       
   904     }
       
   905     LOG1(ESOCKET,EInfo," CHttpTransactionClient::Available: %d ",avail);
       
   906     return avail;
       
   907 }
       
   908 
       
   909 void CHttpTransactionClient::SetHTTPAuthenticationCallbackL(MHTTPAuthenticationCallback& aCallBack)
       
   910 {
       
   911     aCallBack.InstallAuthenticationL(iHttpSession.Session());
       
   912 }
       
   913 
       
   914 
       
   915 // NOTE : When adding a new cipher description string,
       
   916 // make sure KMaxCipherSuiteDescriptionLength is greater than the length.
       
   917 const TDesC8& CHttpTransactionClient::CipherSuiteDescription(const TDesC8& aCode)
       
   918 {
       
   919     TInt length = aCode.Length();
       
   920     if (length < 2)
       
   921     {
       
   922         // This is not a TLS code we recognise.
       
   923         //LOG(ESOCKET,EInfo,"CHttpTransactionClient::CipherSuiteDescription, unknown cipher suite");
       
   924         return KNullDesC8;
       
   925     }
       
   926 
       
   927     TInt code = aCode[1];
       
   928 
       
   929     //LOG1(ESOCKET,EInfo,"CHttpTransactionClient::CipherSuiteDescription, code=%d", code);
       
   930 
       
   931     switch (code)
       
   932     {
       
   933 // The Cipher Suite codes and matching string descriptions are taken from the TLS specification
       
   934 // (see A.5. The CipherSuite, The TLS Protocol, RFC 2246)
       
   935 // The list below contains those currently supported by Symbian. See tlstypedef.h
       
   936 
       
   937     case 0x03:
       
   938         _LIT8(KTls_03, "TLS_RSA_EXPORT_WITH_RC4_40_MD5");
       
   939         return KTls_03();
       
   940     case 0x04:
       
   941         _LIT8(KTls_04, "TLS_RSA_WITH_RC4_128_MD5");
       
   942         return KTls_04();
       
   943     case 0x05:
       
   944         _LIT8(KTls_05, "TLS_RSA_WITH_RC4_128_SHA");
       
   945         return KTls_05();
       
   946     case 0x08:
       
   947         _LIT8(KTls_08, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA");
       
   948         return KTls_08();
       
   949     case 0x09:
       
   950         _LIT8(KTls_09, "TLS_RSA_WITH_DES_CBC_SHA");
       
   951         return KTls_09();
       
   952     case 0x0A:
       
   953         _LIT8(KTls_0A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA");
       
   954         return KTls_0A();
       
   955     case 0x11:
       
   956         _LIT8(KTls_11, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
       
   957         return KTls_11();
       
   958     case 0x12:
       
   959         _LIT8(KTls_12, "TLS_DHE_DSS_WITH_DES_CBC_SHA");
       
   960         return KTls_12();
       
   961     case 0x13:
       
   962         _LIT8(KTls_13, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
       
   963         return KTls_13();
       
   964     case 0x14:
       
   965         _LIT8(KTls_14, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
       
   966         return KTls_14();
       
   967     case 0x16:
       
   968         _LIT8(KTls_16, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
       
   969         return KTls_16();
       
   970     case 0x19:
       
   971         _LIT8(KTls_19, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
       
   972         return KTls_19();
       
   973 
       
   974 // from RFC 3268 : Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)
       
   975     case 0x2F:
       
   976         _LIT8(KTls_2F, "TLS_RSA_WITH_AES_128_CBC_SHA");
       
   977         return KTls_2F();
       
   978     case 0x35:
       
   979         _LIT8(KTls_35, "TLS_RSA_WITH_AES_256_CBC_SHA");
       
   980         return KTls_35();
       
   981     default:
       
   982         return KNullDesC8;
       
   983     }   // end switch
       
   984 }
       
   985 
       
   986 void CHttpTransactionClient::StoreOneCookieL(HBufC8*& aRawHeader, RHTTPHeaders aHeaders, TInt aPartIndex, RStringF aFieldName)
       
   987 {
       
   988     THTTPHdrVal name, value;
       
   989     RStringPool strP = iTransaction.Session().StringPool();
       
   990 
       
   991     RStringF cookieName = strP.StringF(HTTP::ECookieName, RHTTPSession::GetTable());
       
   992     RStringF cookieValue= strP.StringF(HTTP::ECookieValue, RHTTPSession::GetTable());
       
   993     RStringF cookiePath= strP.StringF(HTTP::EPath, RHTTPSession::GetTable());
       
   994     RStringF cookieDomain= strP.StringF(HTTP::EDomain, RHTTPSession::GetTable());
       
   995     RStringF cookieMaxAge= strP.StringF(HTTP::EMaxAge, RHTTPSession::GetTable());
       
   996     RStringF cookiePort= strP.StringF(HTTP::ECookiePort, RHTTPSession::GetTable());
       
   997     RStringF cookieComment= strP.StringF(HTTP::EComment, RHTTPSession::GetTable());
       
   998     RStringF cookieCommentURL= strP.StringF(HTTP::ECommentURL, RHTTPSession::GetTable());
       
   999     RStringF cookieSecure= strP.StringF(HTTP::ESecure, RHTTPSession::GetTable());
       
  1000     RStringF cookieDiscard= strP.StringF(HTTP::EDiscard, RHTTPSession::GetTable());
       
  1001     RStringF cookieVersion= strP.StringF(HTTP::EVersion, RHTTPSession::GetTable());
       
  1002     RStringF cookieExpires= strP.StringF(HTTP::EExpires, RHTTPSession::GetTable());
       
  1003 
       
  1004     aHeaders.GetParam(aFieldName, cookieName , name, aPartIndex);
       
  1005     aHeaders.GetParam(aFieldName, cookieValue, value, aPartIndex);
       
  1006 
       
  1007     TInt len1 = name.Str().DesC().Length();
       
  1008     TInt len2 = value.Str().DesC().Length();
       
  1009     HBufC8* temp = HBufC8::NewLC(KCookieBufferAllocLength);
       
  1010     if (((temp->Des().Length()+1+len1+len2)) <(KCookieBufferAllocLength-iMinLength))
       
  1011     {
       
  1012         temp->Des().Append(name.Str().DesC());
       
  1013         temp->Des().Append(KEquals);
       
  1014         temp->Des().Append(value.Str().DesC());
       
  1015         temp->Des().Append(KSemiColonSpace);
       
  1016     }
       
  1017     else
       
  1018     {
       
  1019         iDiscardCookie = true;
       
  1020     }
       
  1021 
       
  1022     THTTPHdrVal hdrVal;
       
  1023 
       
  1024     if (aHeaders.GetParam(aFieldName, cookieComment, hdrVal, aPartIndex) == KErrNone)
       
  1025         AddParam(temp, cookieComment.DesC(), hdrVal.StrF().DesC());
       
  1026 
       
  1027     if (aHeaders.GetParam(aFieldName, cookieCommentURL, hdrVal, aPartIndex) == KErrNone)
       
  1028         AddParam(temp, cookieCommentURL.DesC(), hdrVal.StrF().DesC());
       
  1029 
       
  1030     if (aHeaders.GetParam(aFieldName, cookieDiscard, hdrVal, aPartIndex) == KErrNone)
       
  1031         AddParam(temp, cookieDiscard.DesC(), hdrVal.StrF().DesC());
       
  1032 
       
  1033     if (aHeaders.GetParam(aFieldName, cookieDomain, hdrVal, aPartIndex) == KErrNone)
       
  1034         AddParam(temp, cookieDomain.DesC(), hdrVal.StrF().DesC());
       
  1035 
       
  1036     if (aHeaders.GetParam(aFieldName, cookieMaxAge, hdrVal, aPartIndex) == KErrNone)
       
  1037         AddParam(temp, cookieMaxAge.DesC(), hdrVal.StrF().DesC());
       
  1038 
       
  1039     if (aHeaders.GetParam(aFieldName, cookiePath, hdrVal, aPartIndex) == KErrNone)
       
  1040         AddParam(temp, cookiePath.DesC(), hdrVal.StrF().DesC());
       
  1041 
       
  1042     if (aHeaders.GetParam(aFieldName, cookiePort, hdrVal, aPartIndex) == KErrNone)
       
  1043         AddParam(temp, cookiePort.DesC(), hdrVal.StrF().DesC());
       
  1044 
       
  1045     if (aHeaders.GetParam(aFieldName, cookieSecure, hdrVal, aPartIndex) == KErrNone)
       
  1046         AddParam(temp, cookieSecure.DesC(), hdrVal.StrF().DesC());
       
  1047 
       
  1048     if (aHeaders.GetParam(aFieldName, cookieVersion, hdrVal, aPartIndex) == KErrNone)
       
  1049         AddParam(temp, cookieVersion.DesC(), hdrVal.StrF().DesC());
       
  1050 
       
  1051     if (aHeaders.GetParam(aFieldName, cookieExpires, hdrVal, aPartIndex) == KErrNone)
       
  1052         AddParam(temp, cookieExpires.DesC(), hdrVal.StrF().DesC());
       
  1053 
       
  1054 // If the cookie size is more than 4K, the cookie is discarded
       
  1055     if (iDiscardCookie != true)
       
  1056         aRawHeader->Des().Append(*temp);
       
  1057 
       
  1058     CleanupStack::PopAndDestroy(temp);
       
  1059 }
       
  1060 
       
  1061 void CHttpTransactionClient::AddParam(HBufC8*& aTemp, const TDesC8& aName, const TDesC8& aValue)
       
  1062 {
       
  1063     TInt len = aName.Length()+aValue.Length();
       
  1064     if ((aTemp->Des().Length()+len+1) < (KCookieBufferAllocLength - iMinLength))
       
  1065     {
       
  1066         aTemp->Des().Append(aName);
       
  1067         aTemp->Des().Append(KEquals);
       
  1068         aTemp->Des().Append(aValue);
       
  1069         aTemp->Des().Append(KSemiColonSpace);
       
  1070     }
       
  1071     else
       
  1072     {
       
  1073         iDiscardCookie = true;
       
  1074     }
       
  1075 }