remotestoragefw/webdavaccessplugin/src/rsfwdavtransaction.cpp
changeset 0 3ad9d5175a89
equal deleted inserted replaced
-1:000000000000 0:3ad9d5175a89
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:  Handle WebDAV transactions
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 //#include <HttpStringConstants.h>
       
    21 #include <http/rhttpheaders.h>
       
    22 #include <httperr.h>
       
    23 #include <es_sock.h>
       
    24 
       
    25 #include "rsfwremoteaccess.h"
       
    26 #include "rsfwdavtransaction.h"
       
    27 #include "rsfwdavsession.h"
       
    28 #include "rsfwdavfileinfo.h"
       
    29 #include "mdebug.h"
       
    30 
       
    31 // ============================ MEMBER FUNCTIONS ==============================
       
    32 // Destructor
       
    33 CRsfwDavTransaction::~CRsfwDavTransaction()
       
    34     {
       
    35     DEBUGSTRING(("WebDAV transaction %d in destructor ...", Id()));
       
    36     iHttpTransaction.Close();
       
    37     iBodyFile.Close();
       
    38     delete iRequestBodyBuffer;
       
    39     delete iPropFindPath;
       
    40     delete iResponseBuffer;
       
    41     DEBUGSTRING(("... done"));
       
    42     }
       
    43 
       
    44 // ----------------------------------------------------------------------------
       
    45 // CRsfwDavTransaction:::NewL
       
    46 // Two-phased constructor.
       
    47 // ----------------------------------------------------------------------------
       
    48 //
       
    49 CRsfwDavTransaction* CRsfwDavTransaction::NewL(CRsfwDavSession* aWebDavSession,
       
    50                                              TWebDavOp aWebDavOp,
       
    51                                              const TUriC8& aUri,
       
    52                                              RStringF aMethod,
       
    53                                              TUint aTransactionId)
       
    54     {
       
    55     CRsfwDavTransaction* self = new (ELeave) CRsfwDavTransaction;
       
    56     CleanupStack::PushL(self);
       
    57     self->ConstructL(aWebDavSession,
       
    58                      aWebDavOp,
       
    59                      aUri,
       
    60                      aMethod,
       
    61                      aTransactionId);
       
    62     CleanupStack::Pop(self);
       
    63     return self;
       
    64     }
       
    65 
       
    66 // ----------------------------------------------------------------------------
       
    67 // CRsfwDavTransaction::ConstructL
       
    68 // Symbian 2nd phase constructor can leave.
       
    69 // ----------------------------------------------------------------------------
       
    70 //
       
    71 void CRsfwDavTransaction::ConstructL(CRsfwDavSession* aWebDavSession,
       
    72                                     TWebDavOp aWebDavOp,
       
    73                                     const TUriC8& aUri, 
       
    74                                     RStringF aMethod,
       
    75                                     TInt aTransactionId)
       
    76     {
       
    77     iWebDavSession = aWebDavSession;
       
    78     iTransactionId = aTransactionId;
       
    79     // Borrow the file server from the parent
       
    80     iFs = iWebDavSession->FileServerSession();
       
    81     iWebDavOp = aWebDavOp;
       
    82     // User may cancel the IAP selection
       
    83     iStatus = KErrCancel;
       
    84     iHttpTransaction = iWebDavSession->HttpSession().OpenTransactionL(aUri,
       
    85                                                                       *this,
       
    86                                                                       aMethod);
       
    87     // Set body supplier as me
       
    88     switch (aWebDavOp)
       
    89         {
       
    90     case EWebDavOpPut:
       
    91     case EWebDavOpPropFindSingle:
       
    92     case EWebDavOpPropFindMulti:
       
    93     case EWebDavOpLock:
       
    94         iHttpTransaction.Request().SetBody(*this);
       
    95         break;
       
    96 
       
    97     default:
       
    98         break;
       
    99         }
       
   100     }
       
   101 
       
   102 // ----------------------------------------------------------------------------
       
   103 // CRsfwDavTransaction::SetBodyDataL
       
   104 // ----------------------------------------------------------------------------
       
   105 //
       
   106 void CRsfwDavTransaction::SetBodyData(HBufC8* aRequestBodyBuffer)
       
   107     {
       
   108     iRequestBodyBuffer = aRequestBodyBuffer;
       
   109     }
       
   110 
       
   111 // ----------------------------------------------------------------------------
       
   112 // CRsfwDavTransaction::SetBodyFileL
       
   113 // ----------------------------------------------------------------------------
       
   114 //
       
   115 void CRsfwDavTransaction::SetBodyFileL(const TDesC& aPath,
       
   116                                       TInt aOffset,
       
   117                                       TInt* aLength,
       
   118                                       TUint aFlags)
       
   119     {
       
   120     iBodyFilePath = aPath;
       
   121     iBodyFileOffset = aOffset;
       
   122     iBodyFileFlags = aFlags;
       
   123    
       
   124     iParsedBodyFilePath.Set(iBodyFilePath, NULL, NULL);
       
   125     DEBUGBUFFER((iParsedBodyFilePath.FullName()));
       
   126     if (iWebDavOp == EWebDavOpPut)
       
   127         {
       
   128         if (iBodyFilePath.Length())
       
   129             {
       
   130             
       
   131             // Check it exists and open a file handle
       
   132             if (!iFs.IsValidName(iBodyFilePath))
       
   133                 {
       
   134                 User::Leave(KErrPathNotFound);
       
   135                 }
       
   136             TInt err = iBodyFile.Open(iFs,
       
   137                                       iParsedBodyFilePath.FullName(),
       
   138                                       EFileRead | EFileShareAny);
       
   139             if (err != KErrNone)
       
   140                 {
       
   141                 DEBUGSTRING(("Cannot set body file (err=%d)", err));
       
   142                 User::Leave(err);
       
   143                 }
       
   144             if ((*aLength) > 0) // partial PUT
       
   145                 {
       
   146                 iOverallDataSize =  *aLength;
       
   147                 }
       
   148             else
       
   149                 {
       
   150                 User::LeaveIfError(iBodyFile.Size(iOverallDataSize));
       
   151                 iOverallDataSize -= iBodyFileOffset;
       
   152                 }
       
   153             iRequestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize);
       
   154             }
       
   155         }
       
   156     else
       
   157         {
       
   158         // EWebDavOpGet
       
   159         iClientsLength = aLength;
       
   160         if (iClientsLength)
       
   161             {
       
   162             *iClientsLength = 0;
       
   163             }
       
   164         // store pointer to client's length variable and set it to zero
       
   165         // we will later reset it based on the content-length header
       
   166             
       
   167         if (!iFs.IsValidName(iBodyFilePath))
       
   168             {
       
   169             User::Leave(KErrPathNotFound);
       
   170             }
       
   171         }
       
   172     }
       
   173 
       
   174 // ----------------------------------------------------------------------------
       
   175 // CRsfwDavTransaction::SetDavFileInfoL
       
   176 // ----------------------------------------------------------------------------
       
   177 //
       
   178 void CRsfwDavTransaction::SetDavFileInfoL(CRsfwDavFileInfo** aDavFileInfo,
       
   179                                          const TDesC& aPath)
       
   180     {
       
   181     if (aDavFileInfo)
       
   182         {
       
   183         iDavFileInfo = CRsfwDavFileInfo::NewL();
       
   184         iDavFileInfo->SetNameL(aPath);
       
   185         *aDavFileInfo = iDavFileInfo;
       
   186         }
       
   187     }
       
   188 
       
   189 // ----------------------------------------------------------------------------
       
   190 // CRsfwDavTransaction::SetPropFindDirEntryArray
       
   191 // ----------------------------------------------------------------------------
       
   192 //
       
   193 void CRsfwDavTransaction::SetPropFindDirEntryArray(
       
   194     RPointerArray<CRsfwDirEnt>& aDirEnts)
       
   195     {
       
   196     // We do not get the ownership
       
   197     iDirEnts = &aDirEnts;
       
   198     }
       
   199 
       
   200 // ----------------------------------------------------------------------------
       
   201 // CRsfwDavTransaction::SetPropfindPath
       
   202 // ----------------------------------------------------------------------------
       
   203 void CRsfwDavTransaction::SetPropFindPath(HBufC* aPropFindPath)
       
   204     {
       
   205     // We get the ownership
       
   206     iPropFindPath = aPropFindPath;
       
   207     }
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // CRsfwDavTransaction::Submit
       
   211 // ----------------------------------------------------------------------------
       
   212 //
       
   213 void CRsfwDavTransaction::SubmitL()
       
   214     {
       
   215     DEBUGSTRING(("submitting WebDav operation %d, id=%d ...",
       
   216                  iWebDavOp,
       
   217                  Id()));
       
   218     TRAPD(err, iHttpTransaction.SubmitL());
       
   219     if (err != KErrNone)
       
   220         {
       
   221         DEBUGSTRING(("WebDav transaction %d left with err %d!",
       
   222                      Id(),
       
   223                      err));
       
   224         // Release resources
       
   225         Cleanup();
       
   226         User::Leave(err);
       
   227         }
       
   228     }
       
   229 
       
   230 // ----------------------------------------------------------------------------
       
   231 // CRsfwDavTransaction::Cancel
       
   232 // ----------------------------------------------------------------------------
       
   233 //
       
   234 void CRsfwDavTransaction::Cancel()
       
   235     {
       
   236     DEBUGSTRING(("Canceling WebDav transaction %d ...", Id()));
       
   237     iHttpTransaction.Cancel();
       
   238     // Cancel XML parsing, if ongoing
       
   239     iWebDavSession->CancelParsing(iWebDavOp);
       
   240     
       
   241     // We don't receive any callback from the HTTP stack,
       
   242     // as we have not registered a filter to get ECancel event,
       
   243     // so we have to initiate the cleanup process ourselves...
       
   244     iStatus = KErrCancel;
       
   245     TransactionError();
       
   246     }
       
   247 
       
   248 // ------------------------------------------------------------------
       
   249 // From MHTTPTransactionCallback
       
   250 // ------------------------------------------------------------------
       
   251 
       
   252 // ----------------------------------------------------------------------------
       
   253 // CRsfwDavTransaction::MHFRunL
       
   254 // Called when an action takes place on the transaction.
       
   255 // ----------------------------------------------------------------------------
       
   256 //
       
   257 void CRsfwDavTransaction::MHFRunL(RHTTPTransaction aTransaction,
       
   258                                  const THTTPEvent& aEvent)
       
   259     {
       
   260     DEBUGSTRING(("MHFRunL() transaction %d (http id = %d) status: %d",
       
   261                  iTransactionId,
       
   262                  aTransaction.Id(),
       
   263                  aEvent.iStatus));
       
   264 
       
   265     TBool done = EFalse;
       
   266     TBool ok = EFalse;
       
   267     switch (aEvent.iStatus)
       
   268         {
       
   269     case THTTPEvent::EGotResponseHeaders:     // process the headers
       
   270         {
       
   271         // HTTP response headers have been received.
       
   272         // We can determine now if there is
       
   273         // going to be a response body to save.
       
   274         RHTTPResponse response = aTransaction.Response();
       
   275         iStatus = response.StatusCode();
       
   276         DEBUGSTRING(("MHFRunL() THTTPEvent::EGotResponseHeaders, status %d",
       
   277                      iStatus));
       
   278         
       
   279         if (iWebDavOp == EWebDavOpOptions)
       
   280             {
       
   281             // Get a pointer to the session owned by WebDavSession
       
   282             RHTTPSession session = aTransaction.Session();
       
   283             RHTTPHeaders hdr = response.GetHeaderCollection();
       
   284             
       
   285             // Get DAV:- header,
       
   286             // which should be DAV: 1 if WebDAV v. 1 supported
       
   287             // or DAV: 1, 2 if also WebDAV v. 2 is supported
       
   288             TBuf8<KMaxDavVersionValue> davBuffer;
       
   289             _LIT8(KDav, "DAV");
       
   290             davBuffer.Append(KDav);
       
   291             RStringF davString =
       
   292                 session.StringPool().OpenFStringL(davBuffer); 
       
   293             THTTPHdrVal val;
       
   294             TInt r = hdr.GetField(davString, 0, val);
       
   295             davString.Close();
       
   296             
       
   297             if (r == KErrNone)
       
   298                 {
       
   299                 RStringF valStr;
       
   300                 valStr = val.StrF();
       
   301                 TPtrC8 davTag = valStr.DesC();
       
   302                 DEBUGSTRING8(("DAV: DAV=%S", &davTag));
       
   303                 TLex8 lex(davTag);        
       
   304                 // Skip over non-numeric chars as long as the list continues...
       
   305                 TChar theChar;
       
   306                 TInt supportedLevel = -1;
       
   307                 while (lex.Peek()) 
       
   308                     {
       
   309                     theChar = lex.Get();
       
   310                     if (theChar.IsDigit()) 
       
   311                     	{
       
   312                     	supportedLevel = theChar.GetNumericValue();
       
   313                     	}
       
   314                     }
       
   315                 if (supportedLevel == -1) 
       
   316                 	{
       
   317                		// DAV not supported...
       
   318                     User::Leave(KErrNotSupported);	
       
   319                 	}
       
   320                 iWebDavSession->SetWebDavSupportClass(supportedLevel);
       
   321                 }
       
   322             else
       
   323                 {
       
   324                 DEBUGSTRING(("DAV=<empty>"));
       
   325                 if (iStatus == HTTPStatus::EUnauthorized)
       
   326                     {
       
   327                     User::Leave(KErrAccessDenied);
       
   328                     }
       
   329                 else
       
   330                     {
       
   331                     if (iStatus == HTTPStatus::EOk) 
       
   332                     	{
       
   333                     	// everything seemed to be ok,
       
   334                     	// but no DAV: header
       
   335                     	User::Leave(KErrNotSupported);
       
   336                     	}
       
   337                     else 
       
   338                     	{
       
   339                     	User::Leave(iStatus);
       
   340                    		}
       
   341                     }
       
   342                 }
       
   343             }
       
   344         // Get the content length and create iResponseBuffer,
       
   345         // where the body will be stored.
       
   346         // However, if we are copying file from the server,
       
   347         // the body (file) will just be stored into
       
   348         // the container file, no memory buffer is needed
       
   349         if (response.HasBody() &&
       
   350             // iStatus must be in 'Successful' range of HTTP codes 2xx
       
   351             (iStatus >= 200) && 
       
   352             (iStatus < 300) &&
       
   353             (iStatus != HTTPStatus::ENoContent))
       
   354             {
       
   355             DEBUGSTRING(("MHFRunL() response has a body..."));
       
   356             MHTTPDataSupplier* responseBody = response.Body();
       
   357             switch (iWebDavOp)
       
   358                 {
       
   359             case EWebDavOpGet:
       
   360                 {
       
   361                 // Prepare to dump the body to container file
       
   362                 TInt err;
       
   363                 if (iStatus == HTTPStatus::EPartialContent) 
       
   364                     {
       
   365                     err = iBodyFile.Open(iFs,
       
   366                                          iParsedBodyFilePath.FullName(),
       
   367                                          EFileWrite | EFileShareAny);
       
   368                     if (err == KErrNone)
       
   369                         {
       
   370                         if (!(iBodyFileFlags &
       
   371                               KRemoteAccessOptionGetToStartOfFile))
       
   372                             {
       
   373                             TInt pos = iBodyFileOffset;
       
   374                             DEBUGSTRING(("Get: partial content received, seek to %d", pos));
       
   375                             iBodyFile.Seek(ESeekStart, pos);
       
   376                             if (pos != iBodyFileOffset)
       
   377                                 {
       
   378                                 // Should never happen
       
   379                                 DEBUGSTRING(("Get: seek to %d failed (pos=%d)",
       
   380                                              iBodyFileOffset,
       
   381                                              pos));
       
   382                                 User::Leave(KErrArgument);
       
   383                                 }
       
   384                             }
       
   385                         }
       
   386                     else 
       
   387                         {
       
   388                         DEBUGSTRING(("Get: partial content received, will overwrite the cache file, err=%d", err));
       
   389                         User::LeaveIfError(
       
   390                             iBodyFile.Replace(
       
   391                                 iFs,
       
   392                                 iParsedBodyFilePath.FullName(),
       
   393                                 EFileWrite | EFileShareAny));
       
   394                         }
       
   395                     }
       
   396                 else // overwrite...
       
   397                     {
       
   398                     DEBUGSTRING(("Get: full content received"));
       
   399                     User::LeaveIfError(
       
   400                         iBodyFile.Replace(
       
   401                             iFs,
       
   402                             iParsedBodyFilePath.FullName(),
       
   403                             EFileStream | EFileWrite | EFileShareAny));
       
   404                     }
       
   405                 
       
   406                 // larger memory buffer
       
   407                 TInt dataSize = responseBody->OverallDataSize();
       
   408                 DEBUGSTRING(("MHFRunL() creating a response buffer, size=%d",
       
   409                              dataSize));
       
   410                 if (dataSize <= KDefaultFileBufferSize) // 40k
       
   411                     {
       
   412                     iResponseBuffer = HBufC8::NewL(dataSize);
       
   413                     }
       
   414                 else
       
   415                     {
       
   416                     iResponseBuffer = HBufC8::NewL(KDefaultFileBufferSize);
       
   417                     }
       
   418                 
       
   419                 }
       
   420                 break;
       
   421 
       
   422             case EWebDavOpPropFindSingle:
       
   423             case EWebDavOpPropFindMulti:
       
   424             case EWebDavOpLock:
       
   425             case EWebDavOpRefreshLock:
       
   426                 {
       
   427                 if (iWebDavOp == EWebDavOpPropFindMulti)
       
   428                     {
       
   429                     PropFindResponseBeginL(KDavResourceTypeCollection);
       
   430                     }
       
   431                 else if (iWebDavOp == EWebDavOpPropFindSingle)
       
   432                     {
       
   433                     PropFindResponseBeginL(KDavResourceTypeOther);
       
   434                     }
       
   435                 else
       
   436                     {
       
   437                     LockQueryResponseBegin();
       
   438                     }
       
   439                 }
       
   440                 break;
       
   441                 
       
   442             default:
       
   443                 {
       
   444                 // We are not interested in any body
       
   445                 iDiscardBody = ETrue;
       
   446                 }
       
   447                 break;
       
   448                 }
       
   449             }
       
   450         else
       
   451             {
       
   452             DEBUGSTRING(("MHFRunL() response does not have a body..."));
       
   453             iDiscardBody = ETrue;
       
   454             }
       
   455         }
       
   456         break;
       
   457 
       
   458     case THTTPEvent::EGotResponseBodyData:
       
   459         {
       
   460         DEBUGSTRING(("MHFRunL() THTTPEvent::EGotResponseBodyData"));
       
   461         // Get the body data supplier
       
   462         TBool allDone;
       
   463         
       
   464         MHTTPDataSupplier* responseBody = aTransaction.Response().Body();
       
   465         ASSERT(responseBody);
       
   466                
       
   467         // Some (more) body data has been received (in the HTTP response)   
       
   468         TPtrC8 bodyData;
       
   469         allDone = responseBody->GetNextDataPart(bodyData);
       
   470         DEBUGSTRING(("MHFRunL() body size = %d (all=%d)",
       
   471                      bodyData.Length(),
       
   472                      allDone));
       
   473 
       
   474         if (!iDiscardBody)
       
   475             {
       
   476             switch (iWebDavOp) 
       
   477                 {
       
   478             case EWebDavOpPropFindSingle:
       
   479             case EWebDavOpPropFindMulti:
       
   480                 {
       
   481                 ParsePropFindResponseL(bodyData);
       
   482                 if (allDone)
       
   483                     {
       
   484                     PropFindResponseEndL();
       
   485                     }             
       
   486                 }
       
   487                 break;
       
   488             case EWebDavOpLock:
       
   489             case EWebDavOpRefreshLock:
       
   490                 {
       
   491                 ParseLockResponseL(bodyData);
       
   492                 if (allDone)
       
   493                     {
       
   494                     LockResponseEndL();
       
   495                     }             
       
   496                 }
       
   497                 break;
       
   498             case EWebDavOpGet: 
       
   499                 {
       
   500                 // set client's length variable
       
   501                 // based on the amount of data fetched
       
   502                 if (iClientsLength) 
       
   503                     {
       
   504                     *iClientsLength += bodyData.Length();
       
   505                     }
       
   506            
       
   507                 TPtr8 responseBodyPtr = iResponseBuffer->Des();
       
   508                 if ((responseBodyPtr.Length() + bodyData.Length()) <=
       
   509                     KDefaultFileBufferSize)
       
   510                     {
       
   511                     responseBodyPtr.Append(bodyData);
       
   512                     }
       
   513                 else 
       
   514                     {
       
   515                     DEBUGSTRING(("Get: writing to cache file: %d bytes",
       
   516                                  responseBodyPtr.Length()));
       
   517                     User::LeaveIfError(iBodyFile.Write(responseBodyPtr));
       
   518                     // Reset buffer with new data
       
   519                     responseBodyPtr.Copy(bodyData);
       
   520                     }
       
   521                 
       
   522                 if (allDone) // this was the last chunk
       
   523                     {
       
   524                     DEBUGSTRING(("Get: writing to cache file %d bytes and closing",
       
   525                                  responseBodyPtr.Length()));
       
   526                     User::LeaveIfError(iBodyFile.Write(responseBodyPtr));
       
   527                     iBodyFile.Close();
       
   528                     }
       
   529                 }
       
   530                 break;
       
   531             
       
   532             default:
       
   533                 break;
       
   534                 }
       
   535             }
       
   536         
       
   537         // Done with that bit of body data
       
   538         responseBody->ReleaseData();
       
   539         }
       
   540         break;
       
   541         
       
   542     case THTTPEvent::EResponseComplete:
       
   543         {
       
   544         // The transaction's response is complete
       
   545         DEBUGSTRING(("Transaction Complete"));
       
   546         }
       
   547         break;
       
   548 
       
   549     case THTTPEvent::ESucceeded:
       
   550         {
       
   551         DEBUGSTRING(("Transaction Successful"));
       
   552         // We need to process the iStatus for the different cases
       
   553         switch (iWebDavOp)
       
   554             {
       
   555         case EWebDavOpPropFindMulti:
       
   556         case EWebDavOpPropFindSingle:
       
   557             if (iStatus == RsfwDavStatus::EMultiStatus)
       
   558                 {
       
   559                 iStatus = KErrNone;
       
   560                 ok = ETrue;
       
   561                 }
       
   562             break;                            
       
   563             // Other states which need processing of reponses
       
   564         case EWebDavOpDelete:
       
   565             {
       
   566             // DELETE contains the status of the response in a XML document
       
   567             // STATUS tag which should be parsed to produce an error
       
   568             // condition for this working is that we get back a
       
   569             // status from the server of 204: No Content
       
   570             if ((iStatus == HTTPStatus::ENoContent ||
       
   571             	iStatus == HTTPStatus::EOk))
       
   572                 {
       
   573                 ok = ETrue;
       
   574                 }
       
   575             
       
   576             // Note that if the server reported an error they usually
       
   577             // return 207 multistatus with an xml body
       
   578             // containing the status of the DELETE
       
   579             // should parse the body here
       
   580             }
       
   581             break;
       
   582 
       
   583         case EWebDavOpMove:
       
   584         case EWebDavOpMkCol:
       
   585         case EWebDavOpPut:
       
   586             if ((iStatus == HTTPStatus::EOk) ||
       
   587             	(iStatus == HTTPStatus::ECreated) ||
       
   588                 (iStatus == HTTPStatus::ENoContent))
       
   589                 {
       
   590                 // 200, 201 or 204 would be the expected response
       
   591                 // that everything went well
       
   592                 DEBUGSTRING(("Move/MkCol/Put: status ok"));
       
   593                 ok = ETrue;
       
   594                 }
       
   595             else
       
   596                 {
       
   597                 // 207 responses contains a status tag in xml data
       
   598                 // 409 would indicate there was a conflict
       
   599                 DEBUGSTRING(("Move/MkCol/Put: bad status!"));
       
   600                 }
       
   601             break;
       
   602 
       
   603         case EWebDavOpGet:
       
   604             if ((iStatus == HTTPStatus::EOk) ||
       
   605                 (iStatus == HTTPStatus::EPartialContent))
       
   606                 {
       
   607                 ok = ETrue;
       
   608                 }
       
   609             break;
       
   610                 
       
   611         case EWebDavOpOptions: 
       
   612             if (iStatus == 200) 
       
   613                 {
       
   614                 ok = ETrue;
       
   615                 }
       
   616             break;
       
   617             
       
   618         case EWebDavOpLock:
       
   619         case EWebDavOpRefreshLock:
       
   620             {
       
   621             if ((iStatus == HTTPStatus::ECreated) || 
       
   622                 (iStatus == HTTPStatus::EOk)) 
       
   623                 {
       
   624                 ok = ETrue;
       
   625                 }
       
   626             }
       
   627             break;
       
   628 
       
   629         case EWebDavOpUnlock:
       
   630             ok = ETrue;
       
   631             break;
       
   632 
       
   633         default:
       
   634             break;
       
   635             }
       
   636 
       
   637         done = ETrue;
       
   638         }
       
   639         break;
       
   640         
       
   641     case THTTPEvent::EFailed:
       
   642         {
       
   643         switch (iWebDavOp)
       
   644             {
       
   645         case EWebDavOpOptions:
       
   646             iStatus = KErrAccessDenied;
       
   647             break;
       
   648             
       
   649         default:
       
   650             break;
       
   651             }
       
   652         
       
   653         DEBUGSTRING(("Transaction failed"));
       
   654         done = ETrue;
       
   655         }
       
   656         break;
       
   657         
       
   658     case THTTPEvent::ERedirectedPermanently:
       
   659     case KErrHttpRedirectNoLocationField:
       
   660         {
       
   661         DEBUGSTRING(("Permanent Redirection"));
       
   662         iStatus = HTTPStatus::EMovedPermanently;
       
   663         done = ETrue;
       
   664         }
       
   665         break;
       
   666 
       
   667     case THTTPEvent::ERedirectedTemporarily:
       
   668         {
       
   669         DEBUGSTRING(("Temporary Redirection"));
       
   670         iStatus = HTTPStatus::ETemporaryRedirect;
       
   671         done = ETrue;
       
   672         }
       
   673         break;
       
   674         
       
   675     case THTTPEvent::ERedirectRequiresConfirmation:
       
   676         iStatus = HTTPStatus::EMovedPermanently;
       
   677         DEBUGSTRING(("Requires Confirmation"));
       
   678         // we don't want to resend the request with the new url
       
   679         // let's just close the request
       
   680         iHttpTransaction.Close();
       
   681         done = ETrue;
       
   682         break;
       
   683         
       
   684     case THTTPEvent::EUnrecoverableError:
       
   685         DEBUGSTRING(("Unrecoverable error"));
       
   686         // Go on - we will end up to EFailed later
       
   687         break;
       
   688         
       
   689     case THTTPEvent::ETooMuchRequestData:
       
   690         DEBUGSTRING(("Too much request data"));
       
   691         break;
       
   692     // ESock errors:
       
   693    	case KErrConnectionTerminated:
       
   694         DEBUGSTRING(("Connection Terminated"));	
       
   695         iStatus = KErrCommsLineFail;
       
   696     	break;
       
   697     default:
       
   698         {
       
   699         // Check the httperr.h header for the meaning of the different fields
       
   700         DEBUGSTRING(("unrecognized event: %d", aEvent.iStatus));
       
   701         iStatus = aEvent.iStatus;
       
   702         // Close off the transaction if it's an error
       
   703         if (iStatus < 0)
       
   704             {
       
   705             done = ETrue;
       
   706             }       
       
   707         }
       
   708         break;
       
   709         }
       
   710 
       
   711     if (done)
       
   712         {
       
   713         if (ok)
       
   714             {
       
   715             TransactionCompleteL();
       
   716             }
       
   717         else
       
   718             {
       
   719             TransactionError();
       
   720             }
       
   721         }
       
   722     }
       
   723 
       
   724 // ----------------------------------------------------------------------------
       
   725 // CRsfwDavTransaction::MHFRunError
       
   726 // ----------------------------------------------------------------------------
       
   727 //
       
   728 TInt CRsfwDavTransaction::MHFRunError(TInt aError,
       
   729                                      RHTTPTransaction /* aTransaction*/ ,
       
   730                                      const THTTPEvent& /* aEvent */)
       
   731     {    
       
   732     DEBUGSTRING(("MHFRunError() http transaction fired with error %d",
       
   733                  aError));
       
   734 
       
   735     iStatus = aError;
       
   736     TransactionError();
       
   737     return KErrNone;
       
   738     }
       
   739 
       
   740 // ------------------------------------------------------------------
       
   741 // From MHTTPDataSupplier
       
   742 // ------------------------------------------------------------------
       
   743 
       
   744 // ----------------------------------------------------------------------------
       
   745 // CRsfwDavTransaction::GetNextDataPart
       
   746 // return ETrue if all data has been sent, EFalse otherwise
       
   747 // ----------------------------------------------------------------------------
       
   748 //
       
   749 TBool CRsfwDavTransaction::GetNextDataPart(TPtrC8& aDataPart)
       
   750     {
       
   751     DEBUGSTRING(("GetNextDataPart() (iMoreToCome = EFalse)"));
       
   752     // Read from the request body file
       
   753     iMoreToCome = EFalse;
       
   754 
       
   755     // we cannot supply more data if the condition is true
       
   756     if ((!iRequestBodyBuffer) ||
       
   757         (iOverallDataSize == 0 && iWebDavOp == EWebDavOpPut)) 
       
   758         {
       
   759         DEBUGSTRING(("All data supplied"));
       
   760         return !iMoreToCome;
       
   761         }
       
   762 
       
   763     switch (iWebDavOp)
       
   764         {
       
   765     case EWebDavOpOptions:
       
   766     case EWebDavOpPropFindSingle:
       
   767     case EWebDavOpPropFindMulti:
       
   768     case EWebDavOpLock:
       
   769         {
       
   770         // Called when the request body is being filled
       
   771         aDataPart.Set(*iRequestBodyBuffer);
       
   772         }
       
   773         break;
       
   774         
       
   775     case EWebDavOpPut:
       
   776         {
       
   777         DEBUGSTRING(("Put: GetNextDataPart()"));
       
   778         if (iSendDataCount == 0) 
       
   779             {
       
   780             // first run
       
   781             DEBUGSTRING(("first run"));
       
   782             TInt pos = iBodyFileOffset;
       
   783             iBodyFile.Seek(ESeekStart, pos);            
       
   784             }
       
   785         else 
       
   786             {
       
   787             DEBUGSTRING(("%d bytes of data have been sent", iSendDataCount));
       
   788             }
       
   789             
       
   790         // We read data that will be given to the stack next time,
       
   791         // or we will find out that there is no more data...
       
   792         TInt readLength;
       
   793         if ((iOverallDataSize - iSendDataCount) >= KDefaultSubmitSize)
       
   794             {
       
   795             readLength = KDefaultSubmitSize;
       
   796             }
       
   797         else
       
   798             {
       
   799             readLength = iOverallDataSize - iSendDataCount;
       
   800             }
       
   801             
       
   802         
       
   803         TPtr8 requestBodyBufferPtr = iRequestBodyBuffer->Des();
       
   804         TInt err = iBodyFile.Read(requestBodyBufferPtr, readLength);
       
   805         iSendDataCount = iSendDataCount + iRequestBodyBuffer->Length();
       
   806         if (err == KErrNone) 
       
   807             {
       
   808             DEBUGSTRING(("passing %d bytes of data to the HTTP stack", iRequestBodyBuffer->Length()));
       
   809             if ((iSendDataCount < iOverallDataSize) &&  iRequestBodyBuffer->Length() > 0)
       
   810                 {  
       
   811                 DEBUGSTRING(("Put: More data to come (iMoreToCome = ETrue)"));
       
   812                 iMoreToCome = ETrue;
       
   813                 }
       
   814              else 
       
   815                 {
       
   816                 DEBUGSTRING(("Put: all data has been exhausted"));
       
   817                 iMoreToCome = EFalse;
       
   818                 }
       
   819             }
       
   820         else
       
   821             {
       
   822             DEBUGSTRING(("Put: failed to read the local file (err=%d)",
       
   823                          err));
       
   824             iMoreToCome = EFalse;
       
   825             }
       
   826         aDataPart.Set(*iRequestBodyBuffer); 
       
   827             
       
   828         break;
       
   829         }
       
   830 
       
   831     default:
       
   832         break;
       
   833         }
       
   834     
       
   835     return !iMoreToCome;
       
   836     }
       
   837 
       
   838 // ----------------------------------------------------------------------------
       
   839 // CRsfwDavTransaction::ReleaseData
       
   840 // ----------------------------------------------------------------------------
       
   841 //
       
   842 void CRsfwDavTransaction::ReleaseData()
       
   843     {
       
   844     if (iMoreToCome) 
       
   845         {
       
   846         TRAP_IGNORE(iHttpTransaction.NotifyNewRequestBodyPartL());
       
   847         }
       
   848     else 
       
   849         {
       
   850         DEBUGSTRING(("Releasing request body buffer"));
       
   851         delete iRequestBodyBuffer;
       
   852         iRequestBodyBuffer = NULL;
       
   853         }
       
   854     }
       
   855 
       
   856 // ----------------------------------------------------------------------------
       
   857 // CRsfwDavTransaction::OverallDataSize
       
   858 // ----------------------------------------------------------------------------
       
   859 //
       
   860 TInt CRsfwDavTransaction::OverallDataSize()
       
   861     {
       
   862     TInt ods;
       
   863     switch (iWebDavOp)
       
   864         {
       
   865     case EWebDavOpPut:
       
   866         DEBUGSTRING(("Put: OverallDataSize returned %d",
       
   867                      iOverallDataSize));
       
   868         // the size of the file to be copied
       
   869         ods = iOverallDataSize;
       
   870         break;
       
   871         
       
   872     default:
       
   873         if (!iRequestBodyBuffer) 
       
   874             {
       
   875             ods = 0;
       
   876             }
       
   877         else 
       
   878             {
       
   879             ods = iRequestBodyBuffer->Length();
       
   880             }
       
   881         
       
   882         break;
       
   883         }
       
   884     return ods;
       
   885     }
       
   886 
       
   887 // ----------------------------------------------------------------------------
       
   888 // CRsfwDavTransaction::Reset
       
   889 // ----------------------------------------------------------------------------
       
   890 //
       
   891 TInt CRsfwDavTransaction::Reset()
       
   892     {
       
   893     DEBUGSTRING(("Reset data suplier"));
       
   894     switch (iWebDavOp)
       
   895         {
       
   896     case EWebDavOpPut:
       
   897         iSendDataCount = 0;
       
   898         break;
       
   899         
       
   900     default:
       
   901         break;
       
   902         }
       
   903     return KErrNone;
       
   904     }
       
   905 
       
   906 // ----------------------------------------------------------------------------
       
   907 // CRsfwDavTransaction::TransactionComplete
       
   908 // ----------------------------------------------------------------------------
       
   909 //
       
   910 void CRsfwDavTransaction::TransactionCompleteL()
       
   911     {
       
   912     iStatus = KErrNone;
       
   913     if (iWebDavOp == EWebDavOpOptions)
       
   914         {
       
   915         iWebDavSession->SetConnected(ETrue);
       
   916         }
       
   917     iWebDavOp = EWebDavOpNone;
       
   918     iWebDavSession->WebDavTransactionCompleteL(this);
       
   919     // Must not do anything with this transaction object
       
   920     // after calling the completion callback because this will be destroyed
       
   921     }
       
   922 
       
   923 // ----------------------------------------------------------------------------
       
   924 // CRsfwDavTransaction::TransactionError
       
   925 // ----------------------------------------------------------------------------
       
   926 //
       
   927 void CRsfwDavTransaction::TransactionError()
       
   928     {
       
   929     Cleanup();
       
   930     iWebDavOp = EWebDavOpNone;
       
   931     iWebDavSession->WebDavTransactionError(this);
       
   932     // Must not do anything with this transaction object
       
   933     // after calling the error callback because this will be destroyed
       
   934     }
       
   935 
       
   936 // ----------------------------------------------------------------------------
       
   937 // CRsfwDavTransaction::Cleanup
       
   938 // ----------------------------------------------------------------------------
       
   939 //
       
   940 void CRsfwDavTransaction::Cleanup()
       
   941     { 
       
   942     // Cleanup (e.g., after a failed transaction).
       
   943     // Only release resources that may block further transactions
       
   944     // before this transaction has been destroyed.
       
   945     switch (iWebDavOp)
       
   946         {
       
   947     case EWebDavOpGet:
       
   948     case EWebDavOpPut:
       
   949         iBodyFile.Close();
       
   950         break;
       
   951         
       
   952     default:
       
   953         break;
       
   954         }
       
   955     }
       
   956     
       
   957 // ----------------------------------------------------------------------------
       
   958 // CRsfwDavTransaction::PropFindResponseBeginL
       
   959 // ----------------------------------------------------------------------------
       
   960 //
       
   961 void CRsfwDavTransaction::PropFindResponseBeginL(TInt aDepth) 
       
   962     {
       
   963     iWebDavSession->SetPropFindParametersL(iDirEnts,
       
   964                                           *iPropFindPath,
       
   965                                           aDepth);
       
   966     }
       
   967 
       
   968 // ----------------------------------------------------------------------------
       
   969 // CRsfwDavTransaction::LockQueryResponseBeginL
       
   970 // ----------------------------------------------------------------------------
       
   971 //
       
   972 void CRsfwDavTransaction::LockQueryResponseBegin() 
       
   973     {
       
   974     iWebDavSession->SetLockQueryParameters(iDavFileInfo);
       
   975     }
       
   976 
       
   977 // ----------------------------------------------------------------------------
       
   978 // CRsfwDavTransaction::PropFindResponseEndL
       
   979 // ----------------------------------------------------------------------------
       
   980 //
       
   981 void CRsfwDavTransaction::PropFindResponseEndL()
       
   982     {
       
   983     iWebDavSession->PropFindResponseEndL();
       
   984     }
       
   985 
       
   986 // ----------------------------------------------------------------------------
       
   987 // CRsfwDavTransaction::LockResponseEndL
       
   988 // ----------------------------------------------------------------------------
       
   989 //
       
   990 void CRsfwDavTransaction::LockResponseEndL()
       
   991     {
       
   992     iWebDavSession->LockResponseEndL();
       
   993     }
       
   994 
       
   995 // ----------------------------------------------------------------------------
       
   996 // CRsfwDavTransaction::ParsePropFindResponseL
       
   997 // ----------------------------------------------------------------------------
       
   998 //
       
   999 void CRsfwDavTransaction::ParsePropFindResponseL(const TDesC8& aResponse)
       
  1000     { 
       
  1001     iWebDavSession->ParsePropFindResponseL(aResponse);
       
  1002     }
       
  1003 
       
  1004 // ----------------------------------------------------------------------------
       
  1005 // CRsfwDavTransaction::ParseLockResponseL
       
  1006 // ----------------------------------------------------------------------------
       
  1007 //
       
  1008 void CRsfwDavTransaction::ParseLockResponseL(const TDesC8& aResponse)
       
  1009     { 
       
  1010     iWebDavSession->ParseLockResponseL(aResponse);
       
  1011     }
       
  1012 
       
  1013 //  End of File