javacommons/gcfprotocols/http/src.s60/chttptransactionclient.cpp
branchRCL_3
changeset 19 04becd199f91
child 34 71c436fe3ce0
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     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             if (err==KErrNone)
       
   299             {
       
   300                 rawFieldLength += fieldNameStr.DesC().Length();
       
   301                 rawFieldLength += 2;//KSeperator Length;
       
   302                 rawFieldLength += rawFldPtr.Length();
       
   303                 rawHeader = HBufC8::NewL(rawFieldLength);
       
   304                 rawHeader->Des().Append(fieldNameStr.DesC());
       
   305                 rawHeader->Des().Append(KSeperator);
       
   306                 rawHeader->Des().Append(rawFldPtr);
       
   307                 aRawHeaders->Append(rawHeader);
       
   308                 rawFieldLength=0;
       
   309             }
       
   310         }
       
   311         ++it;
       
   312     }
       
   313     while (!it.AtEnd());
       
   314 }
       
   315 
       
   316 
       
   317 /*
       
   318 * Returns the total number of bytes read into the buffer,
       
   319 * or -1 if there is no more data because the end of the stream
       
   320 * has been reached.
       
   321 */
       
   322 TInt CHttpTransactionClient::ReadBytes(TDes8& aBytesPtr)
       
   323 {
       
   324     LOG(ESOCKET,EInfo,"CHttpTransactionClient:: ReadBytes");
       
   325     TInt maxBufLength = aBytesPtr.MaxLength();
       
   326     TInt bodyDataPartLength = 0;
       
   327     if (iDrmDownload == false)
       
   328     {
       
   329         bodyDataPartLength = iBuf->Length();
       
   330     }
       
   331     else
       
   332     {
       
   333         bodyDataPartLength = iDrmBuf->Length();
       
   334     }
       
   335     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: maxRead: %d," , maxBufLength);
       
   336     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: bodyDataPartLength:: %d " ,bodyDataPartLength);
       
   337     TInt bytesRead = (maxBufLength+iJavaReadOffset > bodyDataPartLength) ? (bodyDataPartLength - iJavaReadOffset) : maxBufLength;
       
   338     if (bytesRead>0)
       
   339     {
       
   340         LOG1(ESOCKET,EInfo,"Bytes read : %d " ,bytesRead);
       
   341 
       
   342         if (iDrmDownload == false)
       
   343         {
       
   344             TPtrC8 bufPtr = iBuf->Mid(iJavaReadOffset,bytesRead);
       
   345             aBytesPtr.Copy(bufPtr);
       
   346         }
       
   347         else
       
   348         {
       
   349             TPtrC8 bufPtr = iDrmBuf->Mid(iJavaReadOffset,bytesRead);
       
   350             aBytesPtr.Copy(bufPtr);
       
   351         }
       
   352 
       
   353         LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: iJavaReadOffset:: %d " ,iJavaReadOffset);
       
   354         if (iDrmDownload == false)
       
   355         {
       
   356             if ((iJavaReadOffset+bytesRead) == bodyDataPartLength && iLastChunk)
       
   357             {
       
   358                 //All body data from the http transaction has been read
       
   359                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: EOF iLastChunk");
       
   360                 iRead = ETrue;
       
   361 
       
   362                 iJavaWaitingOnReadCallBack=EFalse;
       
   363                 TRAP_IGNORE(iObserver->DataReadyForRead(-1));
       
   364             }
       
   365         }
       
   366         else
       
   367         {
       
   368             if ((iJavaReadOffset+bytesRead) == iDrmBuf->Length() && iLastChunk)
       
   369             {
       
   370                 //All DRM body data from the http transaction has been read
       
   371                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: EOF iLastChunk");
       
   372                 iRead = ETrue;
       
   373 
       
   374                 iJavaWaitingOnReadCallBack=EFalse;
       
   375                 TRAP_IGNORE(iObserver->DataReadyForRead(-1));
       
   376             }
       
   377         }
       
   378     } // if(bytesread > 0)
       
   379     if ((iJavaReadOffset+bytesRead)<=bodyDataPartLength)
       
   380     {
       
   381 
       
   382         if (iJavaReadOffset+bytesRead < bodyDataPartLength)
       
   383         {
       
   384             //Java hasn't read all the current body data buffer, inform java
       
   385             //amount of bytes left to read in buffer.
       
   386 
       
   387             iJavaReadOffset+=bytesRead;
       
   388             TInt  bytesLeftInBuffer = bodyDataPartLength-iJavaReadOffset;
       
   389             LOG1(ESOCKET,EInfo," CHttpTransactionClient::ReadBytes: bytesLeftInBuffer: %d",bytesLeftInBuffer);
       
   390             //Unblock java so it can read the remaining buffered data
       
   391             iJavaWaitingOnReadCallBack=ETrue;
       
   392             TRAP_IGNORE(iObserver->DataReadyForRead(bytesLeftInBuffer));
       
   393         }
       
   394         else
       
   395         {
       
   396             // in this call, the iBuf data was completely read, so call release data to get the next chunk(part) of body from
       
   397             // the native stack
       
   398 
       
   399             if (iDrmDownload == false)
       
   400             {
       
   401                 // Non-Drm case, offset is reset to 0, starting reading newly from iBuf from the next call
       
   402                 iJavaReadOffset=0;
       
   403                 LOG(ESOCKET,EInfo,"CHttpTransactionClient:: ReadBytes ReleaseData!");
       
   404                 iReleasedData=ETrue;
       
   405                 if (iBuf)
       
   406                 {
       
   407                     delete iBuf;
       
   408                     iBuf = NULL;
       
   409                 }
       
   410                 iRespBody->ReleaseData();   // tell the stack to send the next response body data, stack will call mhfrunl after this
       
   411             }
       
   412             else
       
   413             {
       
   414                 // DRM file download, index is never reset to 0 , continue reading from drm buffer
       
   415                 iJavaReadOffset+=bytesRead;
       
   416 
       
   417             }
       
   418 
       
   419         }
       
   420 
       
   421     }
       
   422 
       
   423     LOG1(ESOCKET,EInfo,"CHttpTransactionClient::ReadBytes: return bytesRead %d " , bytesRead);
       
   424     return bytesRead;
       
   425 }
       
   426 
       
   427 
       
   428 
       
   429 void CHttpTransactionClient::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   430 {
       
   431     LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL +");
       
   432 
       
   433     if (iTransaction== aTransaction)
       
   434     {
       
   435         LOG1(ESOCKET,EInfo,"before switch aEvent.iStatus = %d ",aEvent.iStatus);
       
   436         switch (aEvent.iStatus)
       
   437         {
       
   438         case THTTPEvent::ESubmit:
       
   439             LOG1(ESOCKET,EInfo,"MHFRunL::ESubmit : aEvent.iStatus = %d",aEvent.iStatus);
       
   440             iStatus= CHttpTransactionClient::ESubmitted;
       
   441             //Only send an event to Java when we've got a response
       
   442             break;
       
   443         case THTTPEvent::ECancel:
       
   444             LOG(ESOCKET,EInfo,"MHFRunL::ECancel");
       
   445             iStatus =CHttpTransactionClient:: ECancelled;
       
   446             if (iJavaWaitingOnCallBack)
       
   447             {
       
   448                 iObserver->SubmitComplete(iStatus);
       
   449                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL ECancel ");
       
   450                 iJavaWaitingOnCallBack=EFalse;
       
   451             }
       
   452 
       
   453             if (iJavaWaitingOnReadCallBack)
       
   454             {
       
   455                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   456                 iJavaWaitingOnCallBack=EFalse;
       
   457                 iObserver->DataReadyForRead(-1);
       
   458             }
       
   459 
       
   460             break;
       
   461         case THTTPEvent::EClosed:
       
   462             LOG(ESOCKET,EInfo,"MHFRunL::EClosed");
       
   463             iStatus = CHttpTransactionClient::EClosed;
       
   464             if (iJavaWaitingOnCallBack)
       
   465             {
       
   466                 iJavaWaitingOnCallBack=EFalse;
       
   467                 LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL EClosed");
       
   468                 iObserver->SubmitComplete(iStatus);
       
   469             }
       
   470             if (iJavaWaitingOnReadCallBack)
       
   471             {
       
   472                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   473                 iJavaWaitingOnCallBack=EFalse;
       
   474                 iObserver->DataReadyForRead(-1);
       
   475             }
       
   476 
       
   477             break;
       
   478             /*Receiving transaction events*/
       
   479         case THTTPEvent::EGotResponseTrailerHeaders:
       
   480         {
       
   481             LOG(ESOCKET,EInfo,"MHFRunL  EGotResponseTrailerHeaders");
       
   482             iStatus= CHttpTransactionClient::EGotResponse;
       
   483             break;
       
   484         }
       
   485         case THTTPEvent::ESucceeded:
       
   486         {
       
   487             LOG(ESOCKET,EInfo,"MHFRunL ESucceeded");
       
   488             break;
       
   489         }
       
   490         case THTTPEvent::EGotResponseHeaders:
       
   491         {
       
   492             LOG(ESOCKET,EInfo,"MHFRunL EGotResponseHeaders");
       
   493             iStatus = CHttpTransactionClient::EGotResponse;
       
   494             //If  we are secure attempt to get the security information.
       
   495             //At the moment the native HTTP stack only allows us to retrieve
       
   496             //Server cert info after and a submission and before the transaction is
       
   497             //complete, ignore any warnings as we may not be in sercure mode
       
   498 
       
   499             RStringPool strP = iTransaction.Session().StringPool();
       
   500             RHTTPResponse response = iTransaction.Response();
       
   501             RHTTPHeaders headers =response.GetHeaderCollection();
       
   502             THTTPHdrFieldIter it = headers.Fields();
       
   503             RStringTokenF token;
       
   504             RStringF fieldNameStr;
       
   505             TPtrC8 rawFldPtr;
       
   506             do
       
   507             {
       
   508                 token = it();
       
   509                 fieldNameStr=strP.StringF(token);
       
   510                 // Work around for DRM download
       
   511                 RStringF contentType = strP.StringF(HTTP::EContentType,RHTTPSession::GetTable());
       
   512                 if (fieldNameStr == contentType)
       
   513                 {
       
   514                     //LOG(ESOCKET,EInfo,"content type header is  present");
       
   515                     TInt err = headers.GetRawField(fieldNameStr,rawFldPtr);
       
   516                     TInt index = rawFldPtr.Match(KDRMHeader1);
       
   517                     //  LOG1(ESOCKET,EInfo,"rawFldPtr = %s ",rawFldPtr.str());
       
   518                     //LOG1(ESOCKET,EInfo,"index of drm header is = %d",index);
       
   519                     if (index == 0)
       
   520                     {
       
   521                         iDrmDownload = true;
       
   522                     }
       
   523                     else
       
   524                     {
       
   525                         index = rawFldPtr.Match(KDRMHeader2);
       
   526                         if (index == 0)
       
   527                             iDrmDownload = true;
       
   528                     }
       
   529                 }
       
   530                 ++it;
       
   531             }
       
   532             while (!it.AtEnd());
       
   533 
       
   534             GetSecurityInfo();
       
   535             if (iJavaWaitingOnCallBack)
       
   536             {
       
   537                 iJavaWaitingOnCallBack=EFalse;
       
   538                 //LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL Notifiy Java Got Response");
       
   539                 iObserver->SubmitComplete(iStatus);
       
   540             }
       
   541             break;
       
   542         }
       
   543         case THTTPEvent::EResponseComplete:
       
   544         {
       
   545             LOG(ESOCKET,EInfo,"MHFRunL EResponseComplete");
       
   546             if (iJavaWaitingOnReadCallBack)
       
   547             {
       
   548                 LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   549                 iJavaWaitingOnCallBack=EFalse;
       
   550                 iStatus=CHttpTransactionClient::EComplete;
       
   551                 if (iDrmDownload == false)
       
   552                     iObserver->DataReadyForRead(-1);
       
   553             }
       
   554 
       
   555             break;
       
   556         }
       
   557         case THTTPEvent::EUnrecoverableError:
       
   558         case THTTPEvent::ETooMuchRequestData:
       
   559         case THTTPEvent::EFailed:
       
   560         {
       
   561             LOG(ESOCKET,EInfo, "MHFRunL EUnrecoverableError/EFailed");
       
   562             iStatus=CHttpTransactionClient::EFailed;
       
   563             NotifyErrorL(iStatus);
       
   564             break;
       
   565         }
       
   566         case THTTPEvent::EGotResponseBodyData:
       
   567         {
       
   568             LOG(ESOCKET,EInfo,"MHFRunL EGotResponseBodyData");
       
   569             iReleasedData=EFalse;
       
   570             //More data is ready for Java to read.
       
   571             iRespBody = aTransaction.Response().Body();
       
   572 
       
   573             TPtrC8 bodyData;
       
   574             iStatus=KErrNotReady;
       
   575             //We may be closing if so we don't want to request more data.
       
   576             if (!iClosing)
       
   577             {
       
   578                 if (iDrmDownload == true)
       
   579                 {
       
   580                     iFlag = iFlag + 1;
       
   581                     iLastChunk = iRespBody->GetNextDataPart(bodyData);
       
   582                     TInt curLen = iDrmBuf->Length();
       
   583                     TInt reqLen = curLen + bodyData.Length();
       
   584                     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL DRM case  bodyData.Length() = %d",bodyData.Length());
       
   585                     TRAP_IGNORE((iDrmBuf = iDrmBuf->ReAllocL(reqLen + bodyData.Length())));
       
   586                     TPtr8 bodyPtr1 = iDrmBuf->Des();
       
   587                     //HBufC8* bodyBuffer1 = HBufC8::NewLC(bodyData.Length());
       
   588                     LOG1(ESOCKET,EInfo,"length of iDrmBuf = %d", iDrmBuf->Length());
       
   589                     bodyPtr1.Append(bodyData);
       
   590                     iRespBody->ReleaseData();
       
   591 
       
   592 
       
   593                     iStatus = CHttpTransactionClient::EGotResponseBodyData;
       
   594                     //if(iFlag == 1)
       
   595                     TInt bodyDataPartLength;
       
   596                     bodyDataPartLength = iDrmBuf->Length();
       
   597                     TInt  bytesLeftInBuffer = bodyDataPartLength-iJavaReadOffset;
       
   598                     if (bytesLeftInBuffer > 0)
       
   599                         iObserver->DataReadyForRead(bytesLeftInBuffer);
       
   600                 }
       
   601                 else
       
   602                 {
       
   603                     iLastChunk = iRespBody->GetNextDataPart(bodyData);
       
   604                     HBufC8* bodyBuffer = HBufC8::NewLC(bodyData.Length());
       
   605                     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL after getnextdatapart ,bodyData.Length() = %d",bodyData.Length());
       
   606                     TPtr8 bodyPtr = bodyBuffer->Des();
       
   607                     bodyPtr.Append(bodyData);
       
   608                     if (iBuf)
       
   609                     {
       
   610                         delete iBuf;
       
   611                         iBuf = NULL;
       
   612                     }
       
   613                     CleanupStack::Pop(bodyBuffer);
       
   614                     iBuf = bodyBuffer;
       
   615                     iStatus = CHttpTransactionClient::EGotResponseBodyData;
       
   616                     LOG(ESOCKET,EInfo," CHttpTransactionClient::MHFRunL Notify got more data");
       
   617                     iObserver->DataReadyForRead(iStatus);
       
   618                 }
       
   619             }
       
   620 
       
   621             break;
       
   622         }
       
   623         case THTTPEvent::ENotifyNewRequestBodyPart:
       
   624         {
       
   625             LOG(ESOCKET,EInfo,"MHFRunL ENotifyNewRequestBodyPart");
       
   626             iStatus = CHttpTransactionClient::ERequestNextBodayData;
       
   627             break;
       
   628         }
       
   629         /*
       
   630         * -j2me expects the http stack to be able to post body data with no content type
       
   631         *   the native stack default validation filter does not allow this.
       
   632         * -j2me expects the http stack to allow post requests to have body data
       
   633         *   the native stack default validation filter does not allow this. */
       
   634         case KErrHttpEntityHeaderMissingContentType:
       
   635         case KErrHttpInvalidHeaderInRequest:
       
   636         case KErrHttpGeneralHeaderMissingHost:
       
   637             break;
       
   638 
       
   639         case THTTPEvent::ERedirectRequiresConfirmation:
       
   640         {
       
   641             LOG(ESOCKET,EInfo,"MHFRunL ERedirectRequiresConfirmation");
       
   642         }
       
   643         case THTTPEvent::ENeedTunnel:
       
   644         {
       
   645             LOG(ESOCKET,EInfo,"MHFRunL ENeedTunnel");
       
   646         }
       
   647         case THTTPEvent::EGetCipherSuite:
       
   648         {
       
   649             LOG(ESOCKET,EInfo,"MHFRunL EGetCipherSuite");
       
   650         }
       
   651         default:
       
   652         {
       
   653             LOG(ESOCKET,EInfo,"MHFRunL Unkown Event");
       
   654             //__ASSERT_DEBUGCOMP( EFalse, User::Panic(_L("Unhandled native Http event"), aEvent.iStatus) );
       
   655             NotifyErrorL(aEvent.iStatus);
       
   656             break;
       
   657         }
       
   658         };
       
   659     }
       
   660     LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL -");
       
   661 }
       
   662 
       
   663 TInt CHttpTransactionClient::MHFRunError(TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& /*aEvent*/)
       
   664 {
       
   665     LOG1(ESOCKET,EInfo," CHttpTransactionClient::MHFRunError: %d ",aError);
       
   666     if (aError!=KErrNone && iTransaction== aTransaction)
       
   667     {
       
   668         iStatus=CHttpTransactionClient::EFailed;
       
   669         if (iJavaWaitingOnCallBack)
       
   670             iObserver->SubmitComplete(iStatus);
       
   671 
       
   672 
       
   673         if (iJavaWaitingOnReadCallBack)
       
   674         {
       
   675             LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   676             iJavaWaitingOnCallBack=EFalse;
       
   677             iObserver->DataReadyForRead(-1);
       
   678         }
       
   679 
       
   680     }
       
   681     return aError;
       
   682 }
       
   683 
       
   684 /*
       
   685 * Java may be waiting on an async call back
       
   686 * If this is the case notify of the error code so we don't block java.
       
   687 */
       
   688 
       
   689 void CHttpTransactionClient::NotifyErrorL(TInt aErrorCode)
       
   690 {
       
   691     LOG1(ESOCKET,EInfo," CHttpTransactionClient::NotifyErrorL: %d ",aErrorCode);
       
   692     if ((aErrorCode  ==  KErrNotReady))
       
   693     {
       
   694         iTransaction.Cancel();
       
   695         iHttpSession.RestartConnection();
       
   696 
       
   697 
       
   698     }
       
   699     if (iJavaWaitingOnCallBack)
       
   700     {
       
   701         iJavaWaitingOnCallBack=EFalse;
       
   702         LOG(ESOCKET,EInfo,"CHttpTransactionClient::MHFRunL  Notifiy Java unknown Event");
       
   703         iObserver->SubmitComplete(aErrorCode);
       
   704     }
       
   705     if (iJavaWaitingOnReadCallBack)
       
   706     {
       
   707         LOG(ESOCKET,EInfo,"Notifiy Read EOF / Cancel");
       
   708         iJavaWaitingOnCallBack=EFalse;
       
   709         //Notify Java of error if it is waiting for a read
       
   710         iObserver->DataReadyForRead(-1);
       
   711     }
       
   712 
       
   713 }
       
   714 
       
   715 
       
   716 void CHttpTransactionClient::CloseTransaction()
       
   717 {
       
   718     LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction + ");
       
   719     iClosing=ETrue;
       
   720     if (!iReleasedData)
       
   721     {
       
   722         LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction NOT RELEASED DATA!!! release and close");
       
   723         if (iDrmDownload == false)
       
   724             iRespBody->ReleaseData();
       
   725         iReleasedData=ETrue;
       
   726     }
       
   727     iTransaction.Close();
       
   728     iClosing=EFalse;
       
   729     LOG(ESOCKET,EInfo,"CHttpTransactionClient::CloseTransaction - ");
       
   730 }
       
   731 
       
   732 CHttpTransactionClient::~CHttpTransactionClient()
       
   733 {
       
   734     LOG(ESOCKET,EInfo,"CHttpTransactionClient::~CHttpTransactionClient");
       
   735     //CloseTransaction();
       
   736     if (iBuf)
       
   737     {
       
   738         delete iBuf;
       
   739         iBuf=NULL;
       
   740     }
       
   741     if (iDrmBuf)
       
   742     {
       
   743         delete iDrmBuf;
       
   744         iDrmBuf=NULL;
       
   745     }
       
   746     delete iCertInfo;
       
   747 }
       
   748 
       
   749 
       
   750 /** Obtain a data part from the supplier.  The data is guaranteed
       
   751     to survive until a call is made to ReleaseData().
       
   752     @param aDataPart - the data part
       
   753     @return ETrue if this is the last part. EFalse otherwise */
       
   754 TBool CHttpTransactionClient::GetNextDataPart(TPtrC8& aDataPart)
       
   755 {
       
   756     LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetNextDataPart");
       
   757     TBool lastPart=EFalse;
       
   758     if (iBuf!=NULL)
       
   759     {
       
   760         lastPart = ETrue;
       
   761         aDataPart.Set(iBuf->Des());
       
   762     }
       
   763     return lastPart;
       
   764 }
       
   765 
       
   766 /** Release the current data part being held at the data
       
   767     supplier.  This call indicates to the supplier that the part
       
   768     is no longer needed, and another one can be supplied, if
       
   769     appropriate.  */
       
   770 void CHttpTransactionClient::ReleaseData()
       
   771 {
       
   772     LOG(ESOCKET,EInfo," CHttpTransactionClient::ReleaseData: delete iBuf");
       
   773     if (iBuf)
       
   774     {
       
   775         delete iBuf;
       
   776         iBuf=NULL;
       
   777     }
       
   778 }
       
   779 
       
   780 /** Obtain the overall size of the data being supplied, if known
       
   781     to the supplier.  Where a body of data is supplied in several
       
   782     parts this size will be the sum of all the part sizes. If
       
   783     the size is not known, KErrNotFound is returned; in this case
       
   784     the client must use the return code of GetNextDataPart to find
       
   785     out when the data is complete.
       
   786 
       
   787     @return A size in bytes, or KErrNotFound if the size is not known.  */
       
   788 TInt CHttpTransactionClient::OverallDataSize()
       
   789 {
       
   790     TInt overallSize = KErrNotFound;
       
   791     if (iBuf)
       
   792     {
       
   793         overallSize=iBuf->Length();
       
   794     }
       
   795     LOG1(ESOCKET,EInfo," CHttpTransactionClient::OverallDataSize: %d",overallSize);
       
   796     return overallSize;
       
   797 }
       
   798 
       
   799 /** Reset the data supplier.  This indicates to the data supplier that it should
       
   800     return to the first part of the data.  This could be used in a situation where
       
   801     the data consumer has encountered an error and needs the data to be supplied
       
   802     afresh.  Even if the last part has been supplied (i.e. GetNextDataPart has
       
   803     returned ETrue), the data supplier should reset to the first part.
       
   804 
       
   805     If the supplier cannot reset it should return an error code; otherwise it should
       
   806     return KErrNone, where the reset will be assumed to have succeeded*/
       
   807 TInt CHttpTransactionClient::Reset()
       
   808 {
       
   809     LOG(ESOCKET,EInfo,"CHttpTransactionClient::Reset");
       
   810     TInt err = KErrNone;
       
   811     return err;
       
   812 }
       
   813 
       
   814 
       
   815 MNativeSecureConnectionInformation* CHttpTransactionClient::GetSecurityInfo()
       
   816 {
       
   817     //LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetSecurityInfo");
       
   818     MNativeSecureConnectionInformation* handle=NULL;
       
   819     if (!iCertInfo)
       
   820     {
       
   821         TRAP_IGNORE(GetCertInfoL());
       
   822         //If we fail to read the cert java is returned a null handle.
       
   823     }
       
   824     if (iCertInfo)
       
   825     {
       
   826         handle = iCertInfo;
       
   827     }
       
   828     return handle;
       
   829 }
       
   830 
       
   831 void CHttpTransactionClient::GetCertInfoL()
       
   832 {
       
   833     //LOG(ESOCKET,EInfo,"CHttpTransactionClient::GetCertInfoL ");
       
   834     TCertInfo info;
       
   835 
       
   836     //Get the server certificate
       
   837     if (iCertInfo!=NULL)
       
   838     {
       
   839         delete iCertInfo;
       
   840         iCertInfo= NULL;
       
   841     }
       
   842     const CX509Certificate* cert = static_cast<const CX509Certificate*>(iTransaction.ServerCert());
       
   843 
       
   844     TInt err = iTransaction.ServerCert(info);
       
   845     if (err==KErrNone)
       
   846     {
       
   847         //Get the cipher suite
       
   848         const TDesC8& cipherCode = iTransaction.CipherSuite().DesC();
       
   849         if (!cipherCode.Length())
       
   850         {
       
   851             //LOG(ESOCKET,EInfo, "CHttpTransactionClient::GetCertInfoL No Cipher Suite Name found in Transaction");
       
   852             User::Leave(KErrNotFound);
       
   853         }
       
   854 
       
   855         HBufC* cipherSuiteBuf = HBufC::NewLC(KMaxCipherSuiteDescriptionLength);
       
   856 
       
   857         const TDesC8& cipherDesc = CipherSuiteDescription(cipherCode);
       
   858         if (cipherDesc.Length())
       
   859         {
       
   860             cipherSuiteBuf->Des().Copy(cipherDesc);
       
   861         }
       
   862         else
       
   863         {
       
   864             // We will use the code as no description is available.
       
   865             //LOG(ESOCKET,EInfo, "CHttpTransactionClient::GetCertInfoL No Cipher Suite description found");
       
   866             cipherSuiteBuf->Des().Copy(cipherCode);
       
   867         }
       
   868 
       
   869         CleanupStack::Pop(cipherSuiteBuf);
       
   870         iCertInfo= CHttpsCertInfo::NewL(*cert,cipherSuiteBuf);
       
   871     }
       
   872 }
       
   873 
       
   874 TInt CHttpTransactionClient::Available()
       
   875 {
       
   876     TInt avail=KErrNone;
       
   877     if (iBuf)
       
   878     {
       
   879         avail=(iBuf->Length()-iJavaReadOffset);
       
   880     }
       
   881     LOG1(ESOCKET,EInfo," CHttpTransactionClient::Available: %d ",avail);
       
   882     return avail;
       
   883 }
       
   884 
       
   885 void CHttpTransactionClient::SetHTTPAuthenticationCallbackL(MHTTPAuthenticationCallback& aCallBack)
       
   886 {
       
   887     aCallBack.InstallAuthenticationL(iHttpSession.Session());
       
   888 }
       
   889 
       
   890 
       
   891 // NOTE : When adding a new cipher description string,
       
   892 // make sure KMaxCipherSuiteDescriptionLength is greater than the length.
       
   893 const TDesC8& CHttpTransactionClient::CipherSuiteDescription(const TDesC8& aCode)
       
   894 {
       
   895     TInt length = aCode.Length();
       
   896     if (length < 2)
       
   897     {
       
   898         // This is not a TLS code we recognise.
       
   899         //LOG(ESOCKET,EInfo,"CHttpTransactionClient::CipherSuiteDescription, unknown cipher suite");
       
   900         return KNullDesC8;
       
   901     }
       
   902 
       
   903     TInt code = aCode[1];
       
   904 
       
   905     //LOG1(ESOCKET,EInfo,"CHttpTransactionClient::CipherSuiteDescription, code=%d", code);
       
   906 
       
   907     switch (code)
       
   908     {
       
   909 // The Cipher Suite codes and matching string descriptions are taken from the TLS specification
       
   910 // (see A.5. The CipherSuite, The TLS Protocol, RFC 2246)
       
   911 // The list below contains those currently supported by Symbian. See tlstypedef.h
       
   912 
       
   913     case 0x03:
       
   914         _LIT8(KTls_03, "TLS_RSA_EXPORT_WITH_RC4_40_MD5");
       
   915         return KTls_03();
       
   916     case 0x04:
       
   917         _LIT8(KTls_04, "TLS_RSA_WITH_RC4_128_MD5");
       
   918         return KTls_04();
       
   919     case 0x05:
       
   920         _LIT8(KTls_05, "TLS_RSA_WITH_RC4_128_SHA");
       
   921         return KTls_05();
       
   922     case 0x08:
       
   923         _LIT8(KTls_08, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA");
       
   924         return KTls_08();
       
   925     case 0x09:
       
   926         _LIT8(KTls_09, "TLS_RSA_WITH_DES_CBC_SHA");
       
   927         return KTls_09();
       
   928     case 0x0A:
       
   929         _LIT8(KTls_0A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA");
       
   930         return KTls_0A();
       
   931     case 0x11:
       
   932         _LIT8(KTls_11, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA");
       
   933         return KTls_11();
       
   934     case 0x12:
       
   935         _LIT8(KTls_12, "TLS_DHE_DSS_WITH_DES_CBC_SHA");
       
   936         return KTls_12();
       
   937     case 0x13:
       
   938         _LIT8(KTls_13, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA");
       
   939         return KTls_13();
       
   940     case 0x14:
       
   941         _LIT8(KTls_14, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
       
   942         return KTls_14();
       
   943     case 0x16:
       
   944         _LIT8(KTls_16, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
       
   945         return KTls_16();
       
   946     case 0x19:
       
   947         _LIT8(KTls_19, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
       
   948         return KTls_19();
       
   949 
       
   950 // from RFC 3268 : Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)
       
   951     case 0x2F:
       
   952         _LIT8(KTls_2F, "TLS_RSA_WITH_AES_128_CBC_SHA");
       
   953         return KTls_2F();
       
   954     case 0x35:
       
   955         _LIT8(KTls_35, "TLS_RSA_WITH_AES_256_CBC_SHA");
       
   956         return KTls_35();
       
   957     default:
       
   958         return KNullDesC8;
       
   959     }   // end switch
       
   960 }
       
   961 
       
   962 void CHttpTransactionClient::StoreOneCookieL(HBufC8*& aRawHeader, RHTTPHeaders aHeaders, TInt aPartIndex, RStringF aFieldName)
       
   963 {
       
   964     THTTPHdrVal name, value;
       
   965     RStringPool strP = iTransaction.Session().StringPool();
       
   966 
       
   967     RStringF cookieName = strP.StringF(HTTP::ECookieName, RHTTPSession::GetTable());
       
   968     RStringF cookieValue= strP.StringF(HTTP::ECookieValue, RHTTPSession::GetTable());
       
   969     RStringF cookiePath= strP.StringF(HTTP::EPath, RHTTPSession::GetTable());
       
   970     RStringF cookieDomain= strP.StringF(HTTP::EDomain, RHTTPSession::GetTable());
       
   971     RStringF cookieMaxAge= strP.StringF(HTTP::EMaxAge, RHTTPSession::GetTable());
       
   972     RStringF cookiePort= strP.StringF(HTTP::ECookiePort, RHTTPSession::GetTable());
       
   973     RStringF cookieComment= strP.StringF(HTTP::EComment, RHTTPSession::GetTable());
       
   974     RStringF cookieCommentURL= strP.StringF(HTTP::ECommentURL, RHTTPSession::GetTable());
       
   975     RStringF cookieSecure= strP.StringF(HTTP::ESecure, RHTTPSession::GetTable());
       
   976     RStringF cookieDiscard= strP.StringF(HTTP::EDiscard, RHTTPSession::GetTable());
       
   977     RStringF cookieVersion= strP.StringF(HTTP::EVersion, RHTTPSession::GetTable());
       
   978     RStringF cookieExpires= strP.StringF(HTTP::EExpires, RHTTPSession::GetTable());
       
   979 
       
   980     aHeaders.GetParam(aFieldName, cookieName , name, aPartIndex);
       
   981     aHeaders.GetParam(aFieldName, cookieValue, value, aPartIndex);
       
   982 
       
   983     TInt len1 = name.Str().DesC().Length();
       
   984     TInt len2 = value.Str().DesC().Length();
       
   985     HBufC8* temp = HBufC8::NewLC(KCookieBufferAllocLength);
       
   986     if (((temp->Des().Length()+1+len1+len2)) <(KCookieBufferAllocLength-iMinLength))
       
   987     {
       
   988         temp->Des().Append(name.Str().DesC());
       
   989         temp->Des().Append(KEquals);
       
   990         temp->Des().Append(value.Str().DesC());
       
   991         temp->Des().Append(KSemiColonSpace);
       
   992     }
       
   993     else
       
   994     {
       
   995         iDiscardCookie = true;
       
   996     }
       
   997 
       
   998     THTTPHdrVal hdrVal;
       
   999 
       
  1000     if (aHeaders.GetParam(aFieldName, cookieComment, hdrVal, aPartIndex) == KErrNone)
       
  1001         AddParam(temp, cookieComment.DesC(), hdrVal.StrF().DesC());
       
  1002 
       
  1003     if (aHeaders.GetParam(aFieldName, cookieCommentURL, hdrVal, aPartIndex) == KErrNone)
       
  1004         AddParam(temp, cookieCommentURL.DesC(), hdrVal.StrF().DesC());
       
  1005 
       
  1006     if (aHeaders.GetParam(aFieldName, cookieDiscard, hdrVal, aPartIndex) == KErrNone)
       
  1007         AddParam(temp, cookieDiscard.DesC(), hdrVal.StrF().DesC());
       
  1008 
       
  1009     if (aHeaders.GetParam(aFieldName, cookieDomain, hdrVal, aPartIndex) == KErrNone)
       
  1010         AddParam(temp, cookieDomain.DesC(), hdrVal.StrF().DesC());
       
  1011 
       
  1012     if (aHeaders.GetParam(aFieldName, cookieMaxAge, hdrVal, aPartIndex) == KErrNone)
       
  1013         AddParam(temp, cookieMaxAge.DesC(), hdrVal.StrF().DesC());
       
  1014 
       
  1015     if (aHeaders.GetParam(aFieldName, cookiePath, hdrVal, aPartIndex) == KErrNone)
       
  1016         AddParam(temp, cookiePath.DesC(), hdrVal.StrF().DesC());
       
  1017 
       
  1018     if (aHeaders.GetParam(aFieldName, cookiePort, hdrVal, aPartIndex) == KErrNone)
       
  1019         AddParam(temp, cookiePort.DesC(), hdrVal.StrF().DesC());
       
  1020 
       
  1021     if (aHeaders.GetParam(aFieldName, cookieSecure, hdrVal, aPartIndex) == KErrNone)
       
  1022         AddParam(temp, cookieSecure.DesC(), hdrVal.StrF().DesC());
       
  1023 
       
  1024     if (aHeaders.GetParam(aFieldName, cookieVersion, hdrVal, aPartIndex) == KErrNone)
       
  1025         AddParam(temp, cookieVersion.DesC(), hdrVal.StrF().DesC());
       
  1026 
       
  1027     if (aHeaders.GetParam(aFieldName, cookieExpires, hdrVal, aPartIndex) == KErrNone)
       
  1028         AddParam(temp, cookieExpires.DesC(), hdrVal.StrF().DesC());
       
  1029 
       
  1030 // If the cookie size is more than 4K, the cookie is discarded
       
  1031     if (iDiscardCookie != true)
       
  1032         aRawHeader->Des().Append(*temp);
       
  1033 
       
  1034     CleanupStack::PopAndDestroy(temp);
       
  1035 }
       
  1036 
       
  1037 void CHttpTransactionClient::AddParam(HBufC8*& aTemp, const TDesC8& aName, const TDesC8& aValue)
       
  1038 {
       
  1039     TInt len = aName.Length()+aValue.Length();
       
  1040     if ((aTemp->Des().Length()+len+1) < (KCookieBufferAllocLength - iMinLength))
       
  1041     {
       
  1042         aTemp->Des().Append(aName);
       
  1043         aTemp->Des().Append(KEquals);
       
  1044         aTemp->Des().Append(aValue);
       
  1045         aTemp->Des().Append(KSemiColonSpace);
       
  1046     }
       
  1047     else
       
  1048     {
       
  1049         iDiscardCookie = true;
       
  1050     }
       
  1051 }