remotestoragefw/webdavaccessplugin/src/rsfwdavsession.cpp
branchRCL_3
changeset 19 88ee4cf65e19
parent 16 87c71b25c937
child 20 1aa8c82cb4cb
equal deleted inserted replaced
16:87c71b25c937 19:88ee4cf65e19
     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:  API for WebDAV operations
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <httpstringconstants.h>
       
    21 #include <http/rhttpheaders.h>
       
    22 #include <escapeutils.h>
       
    23 #include <xml/matchdata.h>
       
    24 
       
    25 #include "rsfwdavsession.h"
       
    26 #include "rsfwdavtransaction.h"
       
    27 #include "rsfwconnectionmanager.h"
       
    28 #include "rsfwpropfindparser.h"
       
    29 #include "rsfwlockqueryparser.h"
       
    30 #include "mdebug.h"
       
    31 
       
    32 // CONSTANTS
       
    33 // characters that will be encoded in the url
       
    34 _LIT8(KSpecials8, " \"<>#%{}|\\^~[]`");
       
    35 
       
    36 // ============================ MEMBER FUNCTIONS ==============================
       
    37 CRsfwDavSession* CRsfwDavSession::NewL(
       
    38     MRsfwDavResponseObserver* aWebDavResponseObserver,
       
    39     MRsfwConnectionObserver* aRsfwConnectionObserver)
       
    40     {
       
    41     CRsfwDavSession* self = new (ELeave) CRsfwDavSession;
       
    42     CleanupStack::PushL(self);
       
    43     self->ConstructL(aWebDavResponseObserver, aRsfwConnectionObserver);
       
    44     CleanupStack::Pop(self);
       
    45     return self;
       
    46     }
       
    47 
       
    48 void CRsfwDavSession::ConstructL(
       
    49     MRsfwDavResponseObserver* aWebDavResponseObserver,
       
    50     MRsfwConnectionObserver* aRsfwConnectionObserver)
       
    51     {
       
    52     DEBUGSTRING(("DavSess: ConstructL: enter"));
       
    53     User::LeaveIfError(iFs.Connect());
       
    54     iWebDavResponseObserver = aWebDavResponseObserver;
       
    55     iRsfwConnectionObserver = aRsfwConnectionObserver;
       
    56 
       
    57     // Create classes needed for parsing PropFind and Lock request replies
       
    58     // Creating these later seems to cause emulator hang-ups.
       
    59     // If the problem does not exist in the real device we may want to
       
    60     // delay especially Lock parser creation as locking may not be used at all.
       
    61     Xml::CMatchData* matchData = Xml::CMatchData::NewLC();
       
    62 	matchData->SetMimeTypeL(KTextXml);
       
    63 	// Select libxml2 parsesr
       
    64 	matchData->SetVariantL(_L8("libxml2"));
       
    65 	// Select Symbian XML Parser (=Expat)
       
    66 //	matchData->SetVariantL(_L8("Symbian"));
       
    67     iPropFindParserImpl = CRsfwPropFindParser::NewL();
       
    68     iPropFindParser = Xml::CParser::NewL(*matchData, *iPropFindParserImpl);
       
    69     iLockQueryParserImpl = CRsfwLockQueryParser::NewL();
       
    70     iLockQueryParser = Xml::CParser::NewL(*matchData, *iLockQueryParserImpl);
       
    71     CleanupStack::PopAndDestroy(matchData);
       
    72 
       
    73     // Open the RHTTPSession
       
    74     iHttpSession.OpenL();
       
    75     iHttpSession.FilterCollection().RemoveFilter( 
       
    76             iHttpSession.StringPool().StringF( HTTP::EAuthentication, RHTTPSession::GetTable() ));
       
    77     // Install this class as the callback for authentication requests:
       
    78     // it will take care of basic/digest auth, SSL
       
    79     InstallAuthenticationL(iHttpSession);
       
    80     DEBUGSTRING(("auth filter installed"));
       
    81     }
       
    82 
       
    83 CRsfwDavSession::~CRsfwDavSession()
       
    84     {
       
    85     DEBUGSTRING(("CRsfwDavSession::~CRsfwDavSession"));
       
    86     delete iPropFindParser;
       
    87     delete iPropFindParserImpl;
       
    88     delete iLockQueryParser;
       
    89     delete iLockQueryParserImpl;
       
    90     delete iEncodedHost;
       
    91     if (iUserName) 
       
    92     {
       
    93     	delete iUserName;	
       
    94     }
       
    95     if (iPassword) 
       
    96     {
       
    97     	delete iPassword;
       
    98     }
       
    99   	iHttpSession.Close();
       
   100   	delete iRsfwConnectionManager;
       
   101     iFs.Close();
       
   102     }
       
   103 
       
   104 // ----------------------------------------------------------------------------
       
   105 // CRsfwDavSession::SetConnected
       
   106 // ----------------------------------------------------------------------------
       
   107 //
       
   108 void CRsfwDavSession::SetConnected(TBool aConnected)
       
   109     {
       
   110     iConnected = aConnected;
       
   111     }
       
   112 
       
   113 // ----------------------------------------------------------------------------
       
   114 // CRsfwDavSession::SetWebDavSupportClass
       
   115 // ----------------------------------------------------------------------------
       
   116 //
       
   117 void CRsfwDavSession::SetWebDavSupportClass(TInt aWebDavSupportClass)
       
   118     {
       
   119     iWebDavSupportClass = aWebDavSupportClass;
       
   120     }
       
   121     
       
   122 // ----------------------------------------------------------------------------
       
   123 // CRsfwDavSession::WebDavSupportClass
       
   124 // ----------------------------------------------------------------------------
       
   125 //
       
   126 TInt CRsfwDavSession::WebDavSupportClass()
       
   127     {
       
   128     return iWebDavSupportClass;
       
   129     }
       
   130 
       
   131 
       
   132 // ----------------------------------------------------------------------------
       
   133 // CRsfwDavSession::OpenL
       
   134 // After calling this function, use options query
       
   135 // to trigger TCP level connection.
       
   136 // ----------------------------------------------------------------------------
       
   137 //
       
   138 void CRsfwDavSession::OpenL(const TDesC& aUri,
       
   139                            TInt aPort,
       
   140                            const TDesC& aUserName,
       
   141                            const TDesC& aPassword,
       
   142                            const TDesC& aAuxData)
       
   143     {
       
   144     // Store connection parameters
       
   145     iHost.Zero();
       
   146     iDavRoot.Zero();
       
   147 
       
   148     // Here we add the port using a simple approach:
       
   149     // it needs to go after http://name/
       
   150     TInt slashCnt = 0;
       
   151     TInt cnt = 0;
       
   152     while (cnt < aUri.Length())
       
   153         {
       
   154         TChar ch = aUri[cnt++];
       
   155         if (ch == '/')
       
   156             {
       
   157             slashCnt++;
       
   158             if (slashCnt == 3)
       
   159                 {
       
   160                 iHost.Append(':');
       
   161                 iHost.AppendNum(aPort);
       
   162                 // At this point we know that
       
   163                 // the remainder of the uri is the root directory
       
   164                 }  
       
   165             }
       
   166 
       
   167         if (slashCnt > 2)
       
   168             {
       
   169             iDavRoot.Append(ch);
       
   170             }
       
   171         else
       
   172             {
       
   173             iHost.Append(ch);
       
   174             }
       
   175         }
       
   176     // We elso need an encoded form of the host part
       
   177     iEncodedHost = EncodeL(iHost.Right(iHost.Length() - KProtocolPrefix));
       
   178 
       
   179     // iDavRoot must be a directory, and thus should end with a slash
       
   180     Slashify(iDavRoot);
       
   181 
       
   182     // Make the pair
       
   183     iHostRoot.Copy(iHost);
       
   184     iHostRoot.Append(iDavRoot);
       
   185 
       
   186     // Assume that the parameters are constant and stable across the session
       
   187     iUserName = EncodeL(aUserName);
       
   188     iPassword = EncodeL(aPassword);
       
   189     iAuxData.Copy(aAuxData);
       
   190 
       
   191     DEBUGSTRING16(("connecting to host='%S', port=%d, root='%S', data=%S",
       
   192                    &iHost,
       
   193                    aPort,
       
   194                    &iDavRoot,
       
   195                    &iAuxData));
       
   196 
       
   197    if (iAuxData.Length() == 0) 
       
   198    {
       
   199    		// in case of empty access point info, set it to '?' (ask user)
       
   200    		_LIT(KAskUser, "?");
       
   201    		iAuxData.Copy(KAskUser);
       
   202    }
       
   203    
       
   204    if (!iRsfwConnectionManager)
       
   205    		{
       
   206         iRsfwConnectionManager =
       
   207              CRsfwConnectionManager::NewL(iRsfwConnectionObserver);
       
   208         iRsfwConnectionManager->UseIapL(aAuxData);
       
   209         }
       
   210         
       
   211     }
       
   212 
       
   213 // ----------------------------------------------------------------------------
       
   214 // CRsfwDavSession::OptionsL
       
   215 // ----------------------------------------------------------------------------
       
   216 //
       
   217 CRsfwDavTransaction* CRsfwDavSession::OptionsL()
       
   218     {
       
   219     TPtrC null;
       
   220     TUriParser8 uriParser;
       
   221     HBufC8* uri = BuildUriLC(null, EFalse, &uriParser);
       
   222 
       
   223     DEBUGSTRING8(("OPTIONS '%S'", &uriParser.UriDes()));
       
   224 
       
   225     // Establish a link-layer connection
       
   226     if (iRsfwConnectionManager)
       
   227         {
       
   228         SetupConnectionL();
       
   229         }
       
   230 
       
   231     RStringPool stringPool = StringPool();
       
   232 
       
   233     // Introducing the webdav headers for the propfind
       
   234     RStringF mOptions = stringPool.OpenFStringL(KWebDavOptions);
       
   235     CleanupClosePushL(mOptions);
       
   236     CRsfwDavTransaction* webDavTransaction =
       
   237         CRsfwDavTransaction::NewL(this,
       
   238                                  EWebDavOpOptions,
       
   239                                  uriParser,
       
   240                                  mOptions,
       
   241                                  NextWebDavTransactionId());
       
   242     CleanupStack::PopAndDestroy(); // mOptions
       
   243     CleanupStack::PushL(webDavTransaction);
       
   244 
       
   245     RHTTPHeaders hdr = webDavTransaction->
       
   246         HttpTransaction().Request().GetHeaderCollection(); 
       
   247  
       
   248  	SetBasicHeadersL(hdr, uriParser, ETrue);
       
   249  	
       
   250     CleanupStack::Pop(2); //webDavTransaction, uri
       
   251     delete uri;
       
   252     return webDavTransaction;
       
   253     }
       
   254 
       
   255 // ----------------------------------------------------------------------------
       
   256 // CRsfwDavSession::PropFindL
       
   257 // Implements WebDAV PROPFIND method.
       
   258 // Parameters: Name of the directory or file
       
   259 //             CRsfwDirEnt pointer array to be filled with directory metadata
       
   260 //             PROPFIND depth
       
   261 //             aIsDir, is this directory or file,
       
   262 //                     some extra checks are made based on this...
       
   263 // ----------------------------------------------------------------------------
       
   264 //
       
   265 CRsfwDavTransaction* CRsfwDavSession::PropFindL(const TDesC &aPath,
       
   266                                               TInt aDepth,
       
   267                                               TBool aIsDir,
       
   268                                               RPointerArray<CRsfwDirEnt>& aDirEnts)
       
   269     {
       
   270     if (!IsConnected())
       
   271         {
       
   272         User::Leave(KErrNotReady);
       
   273         }
       
   274 
       
   275     TUriParser8 uriParser;
       
   276     HBufC8* uri = BuildUriLC(aPath, aIsDir, &uriParser);
       
   277 
       
   278     DEBUGSTRING8(("PROPFIND '%S'", &uriParser.UriDes()));
       
   279  
       
   280     // This function is used from several places
       
   281     TWebDavOp op;
       
   282     if (aDepth == 1)
       
   283         {
       
   284         op = EWebDavOpPropFindMulti;
       
   285         }
       
   286     else // (aDepth == 0)
       
   287         {
       
   288         op = EWebDavOpPropFindSingle;  
       
   289         }
       
   290 
       
   291     RStringPool stringPool = StringPool();
       
   292     RStringF mPropFind = stringPool.OpenFStringL(KWebDavPropFind);
       
   293     CleanupClosePushL(mPropFind);
       
   294     CRsfwDavTransaction* webDavTransaction =
       
   295         CRsfwDavTransaction::NewL(this,
       
   296                                  op,
       
   297                                  uriParser,
       
   298                                  mPropFind,
       
   299                                  NextWebDavTransactionId());
       
   300     CleanupStack::PopAndDestroy(); // mPropFind
       
   301     CleanupStack::PushL(webDavTransaction);
       
   302 
       
   303     RHTTPHeaders hdr = webDavTransaction->
       
   304         HttpTransaction().Request().GetHeaderCollection();
       
   305 
       
   306     // Add headers appropriate to all methods
       
   307     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   308 
       
   309     SetHeaderL(hdr, HTTP::EContentType, KTextXml);
       
   310 
       
   311     // Assumes that the target uri has been cached in an earlier connect
       
   312     SetDepthHeaderL(hdr, aDepth);
       
   313 
       
   314     // XML body
       
   315     HBufC8* requestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize);
       
   316     TPtr8 requestBodyBufferPtr = requestBodyBuffer->Des();
       
   317 
       
   318     // To make things at least little bit faster,
       
   319     // let's try to get "minimal" set
       
   320     // Maybe useful one day:
       
   321     // - <D:getcontentlanguage/>
       
   322     // - <D:creationdate/>
       
   323     // Apache mod_dav 1.0.3 doesn't support:
       
   324     //  - <D:displayname/>
       
   325     _LIT8(KPropFindRequestBody, "\
       
   326 <?xml version=\"1.0\"?>\
       
   327 <propfind xmlns=\"DAV:\">\
       
   328 <prop>\
       
   329 <getcontenttype/>\
       
   330 <getlastmodified/>\
       
   331 <getcontentlength/>\
       
   332 <resourcetype/>\
       
   333 <getetag/>\
       
   334 </prop>\
       
   335 </propfind>\
       
   336 ");
       
   337     requestBodyBufferPtr.Append(KPropFindRequestBody);
       
   338     webDavTransaction->SetBodyData(requestBodyBuffer);
       
   339 
       
   340     webDavTransaction->SetPropFindDirEntryArray(aDirEnts);
       
   341     // We must remember the work directory,
       
   342     // as we don't want to list that when building directory listing.
       
   343     HBufC* propFindPath = HBufC::NewL(iHostRoot.Length() +
       
   344                                        KMaxPath +
       
   345                                        1);
       
   346     TPtr propFindPathPtr = propFindPath->Des();
       
   347     propFindPathPtr.Copy(iDavRoot);
       
   348     propFindPathPtr.Append(aPath);
       
   349     // The whole path must end with a slash
       
   350     Slashify(propFindPathPtr);
       
   351     // Before comparing the path from the server is decoded,
       
   352     // so we can compare against the original 16-bit string.
       
   353     webDavTransaction->SetPropFindPath(propFindPath);
       
   354     CleanupStack::Pop(2); // webdavtransaction, uri
       
   355     delete uri;
       
   356     return webDavTransaction;
       
   357     }
       
   358 
       
   359 // ----------------------------------------------------------------------------
       
   360 // CRsfwDavSession::GetL
       
   361 // ----------------------------------------------------------------------------
       
   362 //
       
   363 CRsfwDavTransaction* CRsfwDavSession::GetL(const TDesC& aSrcPath,
       
   364                                          const TDesC& aDstPath,
       
   365                                          TInt aOffset,
       
   366                                          TInt* aLength,
       
   367                                          TUint aFlags)
       
   368     {
       
   369     // Basically just a HTTP get with some local processing
       
   370     if (!IsConnected())
       
   371         {
       
   372         User::Leave(KErrNotReady);
       
   373         }
       
   374 
       
   375     TUriParser8 uriParser;
       
   376     HBufC8* uri = BuildUriLC(aSrcPath, EFalse, &uriParser);
       
   377 
       
   378 #ifdef _DEBUG
       
   379     {
       
   380     TInt length;
       
   381     if (aLength)
       
   382         {
       
   383         length = *aLength;
       
   384         }
       
   385     else
       
   386         {
       
   387         length = 0;
       
   388         }
       
   389     DEBUGSTRING8(("GET '%S' (off=%d, len=%d)",
       
   390                   &uriParser.UriDes(),
       
   391                   aOffset,
       
   392                   length));
       
   393     }
       
   394 #endif // DEBUG
       
   395 
       
   396     // Introducing the webdav headers for GET
       
   397     RStringPool stringPool = StringPool();
       
   398     RStringF mGet = stringPool.StringF(HTTP::EGET,
       
   399                                        RHTTPSession::GetTable());  
       
   400     CRsfwDavTransaction* webDavTransaction =
       
   401         CRsfwDavTransaction::NewL(this,
       
   402                                  EWebDavOpGet,
       
   403                                  uriParser,
       
   404                                  mGet,
       
   405                                  NextWebDavTransactionId());
       
   406     CleanupStack::PushL(webDavTransaction);
       
   407 
       
   408     // Not sure if this is needed: we are setting conditions
       
   409     // which mod_dav never gets, cos this is a GET..
       
   410     RHTTPHeaders hdr =
       
   411         webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
       
   412 
       
   413     // Add headers appropriate to all methods
       
   414     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   415 
       
   416     if (aLength && (*aLength > 0)) // partial get
       
   417         {
       
   418         TBuf8<KMaxFieldValueLength> rangeHeader;
       
   419         _LIT8(KBytesEquals, "bytes=");
       
   420         rangeHeader.Append(KBytesEquals);
       
   421         rangeHeader.AppendNum(aOffset);
       
   422         rangeHeader.Append('-');
       
   423         rangeHeader.AppendNum(aOffset + *aLength - 1);
       
   424         SetHeaderL(hdr, HTTP::ERange, rangeHeader);
       
   425         }
       
   426 
       
   427     webDavTransaction->SetBodyFileL(aDstPath, aOffset, aLength, aFlags);
       
   428     CleanupStack::Pop(webDavTransaction);
       
   429     CleanupStack::PopAndDestroy(uri);
       
   430     return webDavTransaction;
       
   431     }
       
   432 
       
   433 // ----------------------------------------------------------------------------
       
   434 // CRsfwDavSession::PutL
       
   435 // This amounts to a PUT sending the src data to the destination.
       
   436 // Expects that the aSrcPath param is relative to iDavRoot.
       
   437 // If aSrcPath is empty, an empty file will be created.
       
   438 // ----------------------------------------------------------------------------
       
   439 //
       
   440 CRsfwDavTransaction* CRsfwDavSession::PutL(const TDesC& aSrcPath,
       
   441                                          const TDesC& aDstPath,
       
   442                                          const TDesC8& aMimeType,
       
   443                                          TInt aOffset,
       
   444                                          TInt aLength,
       
   445                                          TInt aTotalLength,
       
   446                                          TBool aUseContentRange,
       
   447                                          const TDesC8* aLockToken)
       
   448     {  
       
   449     if (!IsConnected())
       
   450         {
       
   451         User::Leave(KErrNotReady);
       
   452         }
       
   453 
       
   454     TUriParser8 uriParser;
       
   455     HBufC8* uri = BuildUriLC(aDstPath, EFalse, &uriParser);
       
   456 
       
   457     DEBUGSTRING8(("PUT '%S'", &uriParser.UriDes()));
       
   458 
       
   459     RStringPool stringPool = StringPool();
       
   460     RStringF mPut = stringPool.OpenFStringL(KWebDavPut);
       
   461     CleanupClosePushL(mPut);
       
   462     CRsfwDavTransaction* webDavTransaction =
       
   463         CRsfwDavTransaction::NewL(this,
       
   464                                  EWebDavOpPut,
       
   465                                  uriParser,
       
   466                                  mPut,
       
   467                                  NextWebDavTransactionId());
       
   468     CleanupStack::PopAndDestroy(); // mPut
       
   469     CleanupStack::PushL(webDavTransaction);
       
   470 
       
   471     RHTTPHeaders hdr =
       
   472         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   473 
       
   474     // Add headers appropriate to all methods
       
   475     SetBasicHeadersL(hdr, uriParser, ETrue);  
       
   476     SetHeaderL(hdr, HTTP::EContentType, aMimeType);
       
   477 
       
   478     if (aLength > 0) // partial put
       
   479         {
       
   480         if (aUseContentRange)
       
   481             {
       
   482             TBuf8<KMaxFieldValueLength> rangeHeader;
       
   483             _LIT8(KBytes, "bytes ");
       
   484             rangeHeader.Append(KBytes);
       
   485             rangeHeader.AppendNum(aOffset);
       
   486             rangeHeader.Append('-');
       
   487             rangeHeader.AppendNum(aOffset + aLength - 1);
       
   488             rangeHeader.Append('/');
       
   489             if (aTotalLength == 0) 
       
   490                 {
       
   491                 // The asterisk "*" character means that 
       
   492                 // the instance-length is unknown at the time when 
       
   493                 // the message was generated. 
       
   494                 rangeHeader.Append('*');
       
   495                 }
       
   496             else
       
   497                 {
       
   498                 rangeHeader.AppendNum(aTotalLength);
       
   499                 }
       
   500             SetHeaderL(hdr, HTTP::EContentRange, rangeHeader);
       
   501             }
       
   502         else
       
   503             {
       
   504             // server doesn't support Content-Range
       
   505             // Leave with KrrNotSupported
       
   506             // *aLength = aTotalLength;
       
   507             }  
       
   508         }
       
   509 
       
   510     if (aLockToken)
       
   511         {  
       
   512         SetLockTokenHeaderL(hdr, uri, aLockToken, ETrue);
       
   513         }
       
   514 
       
   515     webDavTransaction->SetBodyFileL(aSrcPath, aOffset, &aLength, 0);
       
   516     CleanupStack::Pop(webDavTransaction);
       
   517     CleanupStack::PopAndDestroy(uri);
       
   518     return webDavTransaction;
       
   519     }
       
   520 
       
   521 // ----------------------------------------------------------------------------
       
   522 // CRsfwDavSession::DeleteL
       
   523 // ----------------------------------------------------------------------------
       
   524 //
       
   525 CRsfwDavTransaction* CRsfwDavSession::DeleteL(const TDesC& aPath,
       
   526                                             TBool aIsDir,
       
   527                                             const TDesC8* aLockToken)
       
   528     {
       
   529     // Needs to take locking into account
       
   530     if (!IsConnected())
       
   531         {
       
   532         User::Leave(KErrNotReady);
       
   533         }
       
   534 
       
   535     TUriParser8 uriParser;
       
   536     HBufC8* uri = BuildUriLC(aPath, aIsDir, &uriParser);
       
   537 
       
   538     DEBUGSTRING8(("DELETE '%S'", &uriParser.UriDes()));
       
   539 
       
   540     RStringPool stringPool = StringPool();
       
   541     RStringF mDelete = stringPool.OpenFStringL(KWebDavDelete);
       
   542     CleanupClosePushL(mDelete);
       
   543     CRsfwDavTransaction* webDavTransaction =
       
   544         CRsfwDavTransaction::NewL(this,
       
   545                                  EWebDavOpDelete,
       
   546                                  uriParser,
       
   547                                  mDelete,
       
   548                                  NextWebDavTransactionId());
       
   549     CleanupStack::PopAndDestroy(); // mDelete
       
   550     CleanupStack::PushL(webDavTransaction);
       
   551 
       
   552     // need to add a special dir on the i
       
   553     RHTTPHeaders hdr =
       
   554         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   555     // Add headers appropriate to all methods
       
   556     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   557 
       
   558     if (aLockToken)
       
   559         {
       
   560         SetLockTokenHeaderL(hdr, uri, aLockToken, ETrue); 
       
   561         }
       
   562 
       
   563     CleanupStack::Pop(webDavTransaction);
       
   564     CleanupStack::PopAndDestroy(uri);
       
   565     return webDavTransaction;
       
   566     }
       
   567 
       
   568 // ----------------------------------------------------------------------------
       
   569 // CRsfwDavSession::MkDirL
       
   570 // ----------------------------------------------------------------------------
       
   571 //
       
   572 CRsfwDavTransaction* CRsfwDavSession::MkDirL(const TDesC& aPath)
       
   573     {
       
   574     // Executes a MKCOL with the specified name
       
   575     if (!IsConnected())
       
   576         {
       
   577         User::Leave(KErrNotReady);
       
   578         }
       
   579 
       
   580     TUriParser8 uriParser;
       
   581     HBufC8* uri = BuildUriLC(aPath, ETrue, &uriParser);
       
   582 
       
   583     DEBUGSTRING8(("MKCOL '%S'", &uriParser.UriDes()));
       
   584 
       
   585     RStringPool stringPool = StringPool();
       
   586     RStringF mMkCol = stringPool.OpenFStringL(KWebDavMkCol);
       
   587     CleanupClosePushL(mMkCol);
       
   588     CRsfwDavTransaction* webDavTransaction =
       
   589         CRsfwDavTransaction::NewL(this,
       
   590                                  EWebDavOpMkCol,
       
   591                                  uriParser,
       
   592                                  mMkCol,
       
   593                                  NextWebDavTransactionId());
       
   594     CleanupStack::PopAndDestroy(1); // mMkCol
       
   595     CleanupStack::PushL(webDavTransaction);
       
   596 
       
   597     // Neeed to add a special dir on the i
       
   598     RHTTPHeaders hdr =
       
   599         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   600 
       
   601     // Add headers appropriate to all methods
       
   602     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   603 
       
   604     CleanupStack::Pop(2); // webDavTransaction, uri
       
   605     delete uri;
       
   606     return webDavTransaction;
       
   607     }
       
   608 
       
   609 // ----------------------------------------------------------------------------
       
   610 // CRsfwDavSession::MoveL
       
   611 // ----------------------------------------------------------------------------
       
   612 //
       
   613 CRsfwDavTransaction* CRsfwDavSession::MoveL(const TDesC& aOldPath,
       
   614                                           const TDesC& aNewPath,
       
   615                                           TBool aOverwrite,
       
   616                                           const TDesC8* aSrcLockToken,
       
   617                                           const TDesC8* aDstLockToken)
       
   618     {
       
   619     if (!IsConnected())
       
   620         {
       
   621         User::Leave(KErrNotReady);
       
   622         }
       
   623 
       
   624     TUriParser8 uriParserNew;
       
   625     HBufC8* uriNew = BuildUriLC(aNewPath, EFalse, &uriParserNew);
       
   626     TUriParser8 uriParserOld;
       
   627     HBufC8* uriOld = BuildUriLC(aOldPath, EFalse, &uriParserOld);
       
   628 
       
   629     DEBUGSTRING8(("MOVE '%S' to '%S'",
       
   630                   &uriParserOld.UriDes(),
       
   631                   &uriParserNew.UriDes()));
       
   632 
       
   633     RStringPool stringPool = StringPool();
       
   634     RStringF mMove = stringPool.OpenFStringL(KWebDavMove);
       
   635     CleanupClosePushL(mMove);
       
   636     CRsfwDavTransaction* webDavTransaction =
       
   637         CRsfwDavTransaction::NewL(this,
       
   638                                  EWebDavOpMove,
       
   639                                  uriParserOld,
       
   640                                  mMove,
       
   641                                  NextWebDavTransactionId());
       
   642     CleanupStack::PopAndDestroy(); // mMove
       
   643     CleanupStack::PushL(webDavTransaction);
       
   644 
       
   645     RHTTPHeaders hdr =
       
   646         webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
       
   647 
       
   648     // Add headers appropriate to all methods
       
   649     SetBasicHeadersL(hdr, uriParserOld, ETrue);
       
   650     
       
   651     if (aSrcLockToken)
       
   652         {
       
   653         SetLockTokenHeaderL(hdr, uriOld, aSrcLockToken, ETrue);
       
   654         }
       
   655     
       
   656     
       
   657      if (aDstLockToken)
       
   658         {
       
   659         SetLockTokenHeaderL(hdr, uriNew, aDstLockToken, ETrue);
       
   660         }      
       
   661         
       
   662     SetHeaderL(hdr, KWebDavDest, *uriNew);
       
   663     if (aOverwrite)
       
   664         {
       
   665         SetHeaderL(hdr, KWebDavOverwrite, KWebDavOverwriteY);
       
   666         }
       
   667     else
       
   668         {
       
   669         SetHeaderL(hdr, KWebDavOverwrite, KWebDavOverwriteN);
       
   670         }
       
   671 
       
   672     CleanupStack::Pop(webDavTransaction);
       
   673     CleanupStack::PopAndDestroy(2, uriNew);   // uriOld, uriNew
       
   674     return webDavTransaction;
       
   675     }
       
   676 
       
   677 // ----------------------------------------------------------------------------
       
   678 // CRsfwDavSession::LockL
       
   679 // ----------------------------------------------------------------------------
       
   680 //
       
   681 CRsfwDavTransaction* CRsfwDavSession::LockL(const TDesC& aPath,
       
   682                                           TUint aFlags,
       
   683                                           TUint aTimeout,
       
   684                                           CRsfwDavFileInfo** aDavFileInfo)
       
   685     {
       
   686     // Opens LOCK transaction
       
   687     if (!IsConnected())
       
   688         {
       
   689         User::Leave(KErrNotReady);
       
   690         }
       
   691 
       
   692     TUriParser8 uriParser;
       
   693     HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
       
   694 
       
   695     DEBUGSTRING8(("LOCK '%S' (%d seconds)", &uriParser.UriDes(), aTimeout));
       
   696 
       
   697     RStringPool stringPool = StringPool();
       
   698     RStringF mLock = stringPool.OpenFStringL(KWebDavLock);
       
   699     CleanupClosePushL(mLock);
       
   700     CRsfwDavTransaction* webDavTransaction =
       
   701         CRsfwDavTransaction::NewL(this,
       
   702                                  EWebDavOpLock,
       
   703                                  uriParser,
       
   704                                  mLock,
       
   705                                  NextWebDavTransactionId());
       
   706     CleanupStack::PopAndDestroy(&mLock);
       
   707     CleanupStack::PushL(webDavTransaction);
       
   708 
       
   709     // headers
       
   710     RHTTPHeaders hdr =
       
   711         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   712 
       
   713     // Add headers appropriate to all methods
       
   714     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   715 
       
   716     SetHeaderL(hdr, HTTP::EContentType, KTextXml);
       
   717 
       
   718     HBufC8* timeoutBuffer = HBufC8::NewLC(KMaxFieldValueLength);
       
   719     TPtr8 timeoutBufferPtr = timeoutBuffer->Des();
       
   720     timeoutBufferPtr.Append(KSecondDash);
       
   721     if (aTimeout != 0)
       
   722         {
       
   723         timeoutBufferPtr.AppendNum(aTimeout);
       
   724         }
       
   725     SetHeaderL(hdr, KWebDavTimeout, timeoutBufferPtr);
       
   726     CleanupStack::PopAndDestroy(timeoutBuffer);
       
   727 
       
   728     // XML body
       
   729     HBufC8* requestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize);
       
   730     TPtr8 requestBodyBufferPtr = requestBodyBuffer->Des();
       
   731 
       
   732     // Note: locktype "write" is currently the only legal value
       
   733     _LIT8(KLockHeaderFormat, "\
       
   734 <?xml version=\"1.0\" encoding=\"utf-8\" ?>\
       
   735 <D:lockinfo xmlns:D=\"DAV:\">\
       
   736 <D:lockscope><D:%S/></D:lockscope>\
       
   737 <D:locktype><D:write/></D:locktype>\
       
   738 <D:owner xmlns:x=\"http://www.webdav.org/\">\
       
   739 <x:lock-user>%S</x:lock-user>\
       
   740 <x:created-by>%S</x:created-by>\
       
   741 </D:owner>\
       
   742 </D:lockinfo>");
       
   743 
       
   744     _LIT8(KLockScopeShared, "shared");
       
   745     _LIT8(KLockScopeExclusive, "exclusive");
       
   746     TPtrC8 lockScope;
       
   747     if (aFlags & EFileShareAny)
       
   748         {
       
   749         lockScope.Set(KLockScopeShared);
       
   750         }
       
   751     else
       
   752         {
       
   753         lockScope.Set(KLockScopeExclusive);
       
   754         }
       
   755      
       
   756     requestBodyBufferPtr.Format(KLockHeaderFormat, &lockScope, iUserName, iUserName);
       
   757     webDavTransaction->SetBodyData(requestBodyBuffer);
       
   758 
       
   759     HBufC* fileInfoPath = BuildFullPathLC(aPath, EFalse);
       
   760     webDavTransaction->SetDavFileInfoL(aDavFileInfo, *fileInfoPath);
       
   761     CleanupStack::PopAndDestroy(fileInfoPath);
       
   762     CleanupStack::Pop(webDavTransaction);
       
   763     CleanupStack::PopAndDestroy(uri);
       
   764     return webDavTransaction;
       
   765     }
       
   766 
       
   767 // ----------------------------------------------------------------------------
       
   768 // CRsfwDavSession::UnlockL
       
   769 // ----------------------------------------------------------------------------
       
   770 //
       
   771 CRsfwDavTransaction* CRsfwDavSession::UnlockL(const TDesC& aPath,
       
   772                                             const TDesC8* aLockToken)
       
   773     {
       
   774     // Opens LOCK transaction
       
   775     if (!IsConnected())
       
   776         {
       
   777         User::Leave(KErrNotReady);
       
   778         }
       
   779 
       
   780     if (iWebDavSupportClass < KDavVersionTwo)
       
   781         {
       
   782         User::Leave(KErrNotSupported);
       
   783         }
       
   784 
       
   785     TUriParser8 uriParser;
       
   786     HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
       
   787 
       
   788     DEBUGSTRING8(("UNLOCK '%S'", &uriParser.UriDes()));
       
   789 
       
   790     RStringPool stringPool = StringPool();
       
   791     RStringF mUnlock = stringPool.OpenFStringL(KWebDavUnlock);
       
   792     CleanupClosePushL(mUnlock);
       
   793     CRsfwDavTransaction* webDavTransaction =
       
   794         CRsfwDavTransaction::NewL(this,
       
   795                                  EWebDavOpUnlock,
       
   796                                  uriParser,
       
   797                                  mUnlock,
       
   798                                  NextWebDavTransactionId());
       
   799     CleanupStack::PopAndDestroy(); // mUnlock
       
   800     CleanupStack::PushL(webDavTransaction);
       
   801 
       
   802     RHTTPHeaders hdr =
       
   803         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   804 
       
   805     // Add headers appropriate to all methods
       
   806     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   807 
       
   808     HBufC8* lockToken = HBufC8::NewLC(aLockToken->Length() +
       
   809                                       KLockTokenOverhead);
       
   810     TPtr8 lockTokenPtr = lockToken->Des();
       
   811     lockTokenPtr.Append('<');
       
   812     lockTokenPtr.Append(*aLockToken);
       
   813     lockTokenPtr.Append('>');
       
   814     SetHeaderL(hdr, KWedDavLockToken, lockTokenPtr);
       
   815     CleanupStack::PopAndDestroy(lockToken);
       
   816 
       
   817     CleanupStack::Pop(2); // webdavtransaction , uri
       
   818     delete uri;
       
   819     return webDavTransaction;
       
   820     }
       
   821 
       
   822 // ----------------------------------------------------------------------------
       
   823 // CRsfwDavSession::RefreshLockL
       
   824 // ----------------------------------------------------------------------------
       
   825 //
       
   826 CRsfwDavTransaction* CRsfwDavSession::RefreshLockL(const TDesC& aPath,
       
   827                                                  TUint aTimeout,
       
   828                                                  const TDesC8* aLockToken,
       
   829                                                  CRsfwDavFileInfo** aDavFileInfo)
       
   830     {
       
   831     // Opens LOCK transaction
       
   832     if (!IsConnected())
       
   833         {
       
   834         User::Leave(KErrNotReady);
       
   835         }
       
   836 
       
   837     if (iWebDavSupportClass < KDavVersionTwo)
       
   838         {
       
   839         User::Leave(KErrNotSupported);
       
   840         }
       
   841 
       
   842     TUriParser8 uriParser;
       
   843     HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
       
   844 
       
   845     DEBUGSTRING8(("LOCK (refresh) '%S' (%d seconds)",
       
   846                   &uriParser.UriDes(),
       
   847                   aTimeout));
       
   848 
       
   849     RStringPool stringPool = StringPool();
       
   850     RStringF mLock = stringPool.OpenFStringL(KWebDavLock);
       
   851     CleanupClosePushL(mLock);
       
   852     CRsfwDavTransaction* webDavTransaction =
       
   853         CRsfwDavTransaction::NewL(this,
       
   854                                  EWebDavOpRefreshLock,
       
   855                                  uriParser,
       
   856                                  mLock,
       
   857                                  NextWebDavTransactionId());
       
   858     CleanupStack::PopAndDestroy(&mLock);
       
   859     CleanupStack::PushL(webDavTransaction);
       
   860 
       
   861     RHTTPHeaders hdr =
       
   862         webDavTransaction->HttpTransaction().Request().GetHeaderCollection(); 
       
   863 
       
   864     // Add headers appropriate to all methods
       
   865     SetBasicHeadersL(hdr, uriParser, ETrue);
       
   866 
       
   867     // do not use tagged lock token, as refresh 'If' header 
       
   868     // should always contain only a single lock token 
       
   869     // (only one lock may be refreshed at a time).
       
   870     SetLockTokenHeaderL(hdr, uri, aLockToken, EFalse);
       
   871 
       
   872     HBufC8* timeoutBuffer = HBufC8::NewLC(KMaxFieldValueLength);
       
   873     TPtr8 timeoutBufferPtr = timeoutBuffer->Des();
       
   874     timeoutBufferPtr.Append(KSecondDash);
       
   875     if (aTimeout != 0)
       
   876         {
       
   877         timeoutBufferPtr.AppendNum(aTimeout);
       
   878         }
       
   879     SetHeaderL(hdr, KWebDavTimeout, timeoutBufferPtr);
       
   880     CleanupStack::PopAndDestroy(timeoutBuffer);
       
   881 
       
   882     HBufC* fileInfoPath = BuildFullPathLC(aPath, EFalse);
       
   883     webDavTransaction->SetDavFileInfoL(aDavFileInfo, *fileInfoPath);
       
   884     CleanupStack::PopAndDestroy(fileInfoPath);
       
   885     CleanupStack::Pop(webDavTransaction);
       
   886     CleanupStack::PopAndDestroy(uri);
       
   887     return webDavTransaction;
       
   888     }
       
   889 
       
   890 // ----------------------------------------------------------------------------
       
   891 // CRsfwDavSession::GetCredentialsL
       
   892 // From MHTTPAuthenticationCallback
       
   893 // ----------------------------------------------------------------------------
       
   894 //
       
   895 TBool CRsfwDavSession::GetCredentialsL(const TUriC8& /* aURI */,
       
   896                                       RString aRealm,
       
   897                                       RStringF /*aAuthenticationType*/,
       
   898                                       RString& aUserName,
       
   899                                       RString& aPassword)
       
   900     {
       
   901     // if we have not tried to send the current credentials once,
       
   902     // and we have at least username proceed, othwise return KErrAccessDenied
       
   903     if (iCredentialRequestCount || (!iUserName))
       
   904         {
       
   905         iCredentialRequestCount = 0;
       
   906         User::Leave(KErrAccessDenied);
       
   907         }
       
   908     iCredentialRequestCount++;
       
   909 
       
   910     TRAPD(err, aUserName = aRealm.Pool().OpenStringL(*iUserName));
       
   911     if (!err)
       
   912         {
       
   913         TRAP(err, aPassword = aRealm.Pool().OpenStringL(*iPassword));
       
   914         if (!err)
       
   915             {
       
   916             return ETrue;
       
   917             }
       
   918         }  
       
   919     return EFalse;
       
   920     }
       
   921 
       
   922 // ----------------------------------------------------------------------------
       
   923 // CRsfwDavSession::SetHeaderL
       
   924 // Convenience method for setting up the header.
       
   925 // ----------------------------------------------------------------------------
       
   926 //
       
   927 void CRsfwDavSession::SetHeaderL(RHTTPHeaders aHeaders,
       
   928                                 TInt aHdrField,
       
   929                                 const TDesC8& aHdrValue)
       
   930     {
       
   931     RStringF valStr = StringPool().OpenFStringL(aHdrValue);
       
   932     CleanupClosePushL(valStr);
       
   933     THTTPHdrVal val(valStr);
       
   934     aHeaders.SetFieldL(
       
   935         StringPool().StringF(aHdrField, RHTTPSession::GetTable()), val);
       
   936     CleanupStack::PopAndDestroy(&valStr);
       
   937     }
       
   938 
       
   939 // ----------------------------------------------------------------------------
       
   940 // CRsfwDavSession::SetHeaderL
       
   941 // Convenience method for setting up the header.
       
   942 // ----------------------------------------------------------------------------
       
   943 //
       
   944 void CRsfwDavSession::SetHeaderL(RHTTPHeaders aHeaders,
       
   945                                 const TDesC8& aHdrName,
       
   946                                 const TDesC8& aHdrValue)
       
   947     {
       
   948     RStringF nameStr = StringPool().OpenFStringL(aHdrName);
       
   949     CleanupClosePushL(nameStr);
       
   950     RStringF valueStr = StringPool().OpenFStringL(aHdrValue);
       
   951     CleanupClosePushL(valueStr);
       
   952     THTTPHdrVal value(valueStr);
       
   953     aHeaders.SetFieldL(nameStr, value);
       
   954     CleanupStack::PopAndDestroy(2); // valueStr, nameStr
       
   955     }
       
   956 
       
   957 // ----------------------------------------------------------------------------
       
   958 // CRsfwDavSession::SetBasicHeadersL
       
   959 // Convenience method for setting up the header.
       
   960 // ----------------------------------------------------------------------------
       
   961 //
       
   962 void CRsfwDavSession::SetBasicHeadersL(RHTTPHeaders aHeaders, 
       
   963                                        const TUriC8& aUri,
       
   964                                        TBool aNoProxy)
       
   965     {
       
   966     // Add headers appropriate to all methods
       
   967     SetHeaderL(aHeaders, HTTP::EUserAgent, KUserAgent);
       
   968     SetHeaderL(aHeaders, HTTP::EAccept, KAccept);
       
   969     // do not send host header if using SSL (not supported currently)
       
   970     TPtrC8 scheme;
       
   971     if (aUri.IsPresent(EUriScheme))
       
   972         {
       
   973         scheme.Set(aUri.Extract(EUriScheme));
       
   974         }
       
   975     if (scheme.CompareF(KHttpsScheme8) != 0) 
       
   976     	{
       
   977     	SetHeaderL(aHeaders, HTTP::EHost, *iEncodedHost);
       
   978     	}
       
   979     SetHeaderL(aHeaders, HTTP::EConnection, KKeepAlive);
       
   980     if (aNoProxy) 
       
   981         {
       
   982         // see RFC 2518 10.4.5 If Header and Non-DAV Aware Proxies
       
   983         // "As in general clients may not be able to reliably detect 
       
   984         // non-DAV aware intermediates, they are advised to always 
       
   985         // prevent caching using the request directives mentioned above."
       
   986         SetHeaderL(aHeaders, HTTP::EPragma, KWebDavNoProxy);
       
   987         SetHeaderL(aHeaders, HTTP::ECacheControl, KWebDavNoProxy);
       
   988         }
       
   989     }
       
   990 
       
   991 // ----------------------------------------------------------------------------
       
   992 // CRsfwDavSession::SetDepthHeaderL
       
   993 // Some DAV requests require this for specifying depth of copies etc.
       
   994 // ----------------------------------------------------------------------------
       
   995 //
       
   996 void CRsfwDavSession::SetDepthHeaderL(RHTTPHeaders aHeaders, TInt aDepth)
       
   997     {
       
   998     RStringF depthStr = StringPool().OpenFStringL(KWebDavDepth);
       
   999     CleanupClosePushL(depthStr);
       
  1000     THTTPHdrVal depth(aDepth);
       
  1001     aHeaders.SetFieldL(depthStr, depth);
       
  1002     CleanupStack::PopAndDestroy(&depthStr);
       
  1003     }
       
  1004 
       
  1005 // ----------------------------------------------------------------------------
       
  1006 // CRsfwDavSession::SetLockTokenHeaderL
       
  1007 // The lock token header can be tagged with the resource (file) URI
       
  1008 // This is especially important for DELETE and MOVE of a file,
       
  1009 // as they will also affect the container (directory), which is not locked
       
  1010 // (in which case supplying a lock token is an error).
       
  1011 // ----------------------------------------------------------------------------
       
  1012 //
       
  1013 void CRsfwDavSession::SetLockTokenHeaderL(RHTTPHeaders aHeaders,
       
  1014                                          const TDesC8* aUri,
       
  1015                                          const TDesC8* aLockToken,
       
  1016                                          TBool aUseTaggedLockToken)
       
  1017     {
       
  1018     DEBUGSTRING(("using a tagged lock token"));
       
  1019     // KLockTokenOverhead for 'tagged' lock token is 2 chars around the uri,
       
  1020     // one space, and 4 chars around the locktoken
       
  1021     // i.e. <target-url> (<target-token>)
       
  1022     TInt tagoverhead;
       
  1023     if (aUseTaggedLockToken) 
       
  1024         {
       
  1025         tagoverhead = KTaggedLockTokenOverhead;
       
  1026         }
       
  1027     else 
       
  1028         {
       
  1029         tagoverhead = KLockTokenOverhead;
       
  1030         }
       
  1031     HBufC8* lockToken = HBufC8::NewLC(aUri->Length()+ aLockToken->Length() +
       
  1032                                       tagoverhead);
       
  1033     TPtr8 lockTokenPtr = lockToken->Des();
       
  1034     if (aUseTaggedLockToken) 
       
  1035         {
       
  1036         lockTokenPtr.Format(KTaggedParenthAngleFormat, aUri, aLockToken);
       
  1037         }
       
  1038     else 
       
  1039         {
       
  1040         lockTokenPtr.Format(KParenthAngleFormat, aLockToken);
       
  1041         }
       
  1042 
       
  1043     DEBUGSTRING8(("lt='%S'", &lockTokenPtr));
       
  1044     SetHeaderL(aHeaders, KWebDavIf, lockTokenPtr);
       
  1045     CleanupStack::PopAndDestroy(lockToken);
       
  1046     }
       
  1047 
       
  1048 // ----------------------------------------------------------------------------
       
  1049 // CRsfwDavSession::WebDavTransactionCompleteL
       
  1050 // ----------------------------------------------------------------------------
       
  1051 //
       
  1052 void CRsfwDavSession::WebDavTransactionCompleteL(
       
  1053     CRsfwDavTransaction* aWebDavTransaction)
       
  1054     {
       
  1055     TUint webDavTransactionId = aWebDavTransaction->Id();
       
  1056     delete aWebDavTransaction;
       
  1057     iWebDavResponseObserver->RequestCompleteL(webDavTransactionId);
       
  1058     }
       
  1059 
       
  1060 // ----------------------------------------------------------------------------
       
  1061 // CRsfwDavSession::WebDavTransactionError
       
  1062 // ----------------------------------------------------------------------------
       
  1063 //
       
  1064 void CRsfwDavSession::WebDavTransactionError(
       
  1065     CRsfwDavTransaction* aWebDavTransaction)
       
  1066     {
       
  1067     TUint webDavTransactionId = aWebDavTransaction->Id();
       
  1068     TInt status = aWebDavTransaction->Status();
       
  1069     delete aWebDavTransaction;
       
  1070     iWebDavResponseObserver->RequestError(webDavTransactionId, status);
       
  1071     }
       
  1072 
       
  1073 // ----------------------------------------------------------------------------
       
  1074 // CRsfwDavSession::SetPropFindParameters
       
  1075 // ----------------------------------------------------------------------------
       
  1076 //
       
  1077 void CRsfwDavSession::SetPropFindParametersL(
       
  1078     RPointerArray<CRsfwDirEnt>* aDirEntArray,
       
  1079     const TDesC& aPropFindPath,
       
  1080     TInt aDepth)
       
  1081     {
       
  1082     iPropFindParserImpl->SetDirEntArray(aDirEntArray);
       
  1083     iPropFindParserImpl->SetTargetDirectory(aPropFindPath, aDepth);
       
  1084     iPropFindParser->ParseBeginL();
       
  1085     }
       
  1086 
       
  1087 // ----------------------------------------------------------------------------
       
  1088 // CRsfwDavSession::SetLockQueryParameters
       
  1089 // ----------------------------------------------------------------------------
       
  1090 //
       
  1091 void CRsfwDavSession::SetLockQueryParameters(CRsfwDavFileInfo* aDavFileInfo)
       
  1092     {
       
  1093     iLockQueryParserImpl->SetDavFileInfo(aDavFileInfo);
       
  1094     }
       
  1095 
       
  1096 // ----------------------------------------------------------------------------
       
  1097 // CRsfwDavSession::ParsePropFindResponseL
       
  1098 // ----------------------------------------------------------------------------
       
  1099 //
       
  1100 void CRsfwDavSession::ParsePropFindResponseL(const TDesC8& aResponse)
       
  1101     {
       
  1102     // only first call to this function really initiates data structures in the XML parser
       
  1103     iPropfindParsingActive = ETrue;
       
  1104     iPropFindParser->ParseL(aResponse);
       
  1105     }
       
  1106 
       
  1107 // ----------------------------------------------------------------------------
       
  1108 // CRsfwDavSession::ParseLockResponseL
       
  1109 // ----------------------------------------------------------------------------
       
  1110 //
       
  1111 void CRsfwDavSession::ParseLockResponseL(const TDesC8& aResponse)
       
  1112     {
       
  1113     iLockQueryParser->ParseL(aResponse);
       
  1114     }
       
  1115 
       
  1116 // ----------------------------------------------------------------------------
       
  1117 // CRsfwDavSession::PropFindResponseEndL
       
  1118 // ----------------------------------------------------------------------------
       
  1119 //
       
  1120 void CRsfwDavSession::PropFindResponseEndL()
       
  1121     {
       
  1122     iPropFindParser->ParseEndL();
       
  1123     iPropfindParsingActive = EFalse;
       
  1124     TInt err = iPropFindParserImpl->GetLastError();
       
  1125     if (err) 
       
  1126    	 	{
       
  1127     	User::Leave(err);
       
  1128     	}
       
  1129     }
       
  1130 
       
  1131 // ----------------------------------------------------------------------------
       
  1132 // CRsfwDavSession::LockResponseEndL
       
  1133 // ----------------------------------------------------------------------------
       
  1134 //
       
  1135 void CRsfwDavSession::LockResponseEndL()
       
  1136     {
       
  1137     iLockQueryParser->ParseEndL();
       
  1138     TInt err = iPropFindParserImpl->GetLastError();
       
  1139     if (err) 
       
  1140    	 	{
       
  1141     	User::Leave(err);
       
  1142     	}
       
  1143     }
       
  1144 
       
  1145 // ----------------------------------------------------------------------------
       
  1146 // CRsfwDavSession::CancelParsing
       
  1147 // ----------------------------------------------------------------------------
       
  1148 //
       
  1149 void CRsfwDavSession::CancelParsing(TWebDavOp aOp)
       
  1150     {
       
  1151     // Only will do something if this operation is PROPFIND,
       
  1152     // and we have started to parse the response.
       
  1153     // UI does not allow to cancel LOCK requests.
       
  1154     // If this would be possible this mechanism should be expanded
       
  1155     // to also cover LOCK parsing.
       
  1156     if ((aOp == EWebDavOpPropFindSingle) || 
       
  1157     (aOp == EWebDavOpPropFindMulti)) 
       
  1158         {
       
  1159         if (iPropfindParsingActive)   
       
  1160             {
       
  1161             // When XML parsing is cancelled when the request is cancelled, 
       
  1162             // there is some XML error (invalid token etc.), ignore the error
       
  1163             TRAP_IGNORE(iPropFindParser->ParseEndL());
       
  1164             iPropfindParsingActive = EFalse;
       
  1165             }
       
  1166         }
       
  1167     }
       
  1168     
       
  1169 
       
  1170 // ----------------------------------------------------------------------------
       
  1171 // CRsfwDavSession::HttpSession
       
  1172 // ----------------------------------------------------------------------------
       
  1173 //
       
  1174 RHTTPSession& CRsfwDavSession::HttpSession()
       
  1175     {
       
  1176     return iHttpSession;
       
  1177     }
       
  1178 
       
  1179 // ----------------------------------------------------------------------------
       
  1180 // CRsfwDavSession::StringPool
       
  1181 // ----------------------------------------------------------------------------
       
  1182 //
       
  1183 RStringPool CRsfwDavSession::StringPool()
       
  1184     {
       
  1185     return iHttpSession.StringPool();
       
  1186     }
       
  1187 
       
  1188 // ----------------------------------------------------------------------------
       
  1189 // CRsfwDavSession::Slashify
       
  1190 // ----------------------------------------------------------------------------
       
  1191 //
       
  1192 void CRsfwDavSession::Slashify(TDes& aStr)
       
  1193     {
       
  1194     if (aStr.Length() &&
       
  1195         (aStr[aStr.Length() - 1] != '/') &&
       
  1196         aStr.Length() < aStr.MaxLength())
       
  1197         {
       
  1198         aStr.Append('/');
       
  1199         }
       
  1200     }
       
  1201 
       
  1202 // ----------------------------------------------------------------------------
       
  1203 // CRsfwDavSession::BuildPathLC
       
  1204 // This function constructs a file path from davroot + path
       
  1205 // ----------------------------------------------------------------------------
       
  1206 //
       
  1207 HBufC* CRsfwDavSession::BuildPathLC(const TDesC& aRoot,
       
  1208                                    const TDesC& aPath,
       
  1209                                    TBool aEndSlash)
       
  1210     {
       
  1211     // 1 is for a possible slash added to the end of the uri...
       
  1212     HBufC* path = HBufC::NewLC(aRoot.Length() +
       
  1213                                aPath.Length() +
       
  1214                                1);
       
  1215     TPtr pathPtr = path->Des();
       
  1216     pathPtr.Append(aRoot);
       
  1217     pathPtr.Append(aPath);
       
  1218     if (aEndSlash)
       
  1219         {
       
  1220         Slashify(pathPtr);
       
  1221         }
       
  1222     return path;
       
  1223     }
       
  1224 
       
  1225 // ----------------------------------------------------------------------------
       
  1226 // CRsfwDavSession::BuildFullPathLC
       
  1227 // This function constructs a file path from davroot + path
       
  1228 // ----------------------------------------------------------------------------
       
  1229 //
       
  1230 HBufC* CRsfwDavSession::BuildFullPathLC(const TDesC& aPath,
       
  1231                                        TBool aEndSlash)
       
  1232     {
       
  1233     return BuildPathLC(iDavRoot, aPath, aEndSlash);
       
  1234     }
       
  1235 
       
  1236 // ----------------------------------------------------------------------------
       
  1237 // CRsfwDavSession::BuildUriLC
       
  1238 // This function constructs an URI from hostname + davroot + path
       
  1239 // The URI is first escape encoded and then UTF-8 encoded.
       
  1240 // Note that in addition to returning the uri string, this function
       
  1241 // will also "populate" aUriParser with the full URI
       
  1242 // ----------------------------------------------------------------------------
       
  1243 //
       
  1244 HBufC8* CRsfwDavSession::BuildUriLC(const TDesC& aPath,
       
  1245                                    TBool aEndSlash,
       
  1246                                    TUriParser8* aUriParser)
       
  1247     {
       
  1248     // 1 is for a possible slash added to the end of the uri...
       
  1249     HBufC* uri = BuildPathLC(iHostRoot, aPath, aEndSlash);
       
  1250     HBufC8* utf8Path = EncodeL(*uri);
       
  1251     CleanupStack::PopAndDestroy(uri);
       
  1252     CleanupStack::PushL(utf8Path);
       
  1253     TPtr8 utf8PathPtr = utf8Path->Des();
       
  1254     if (aUriParser)
       
  1255         {
       
  1256         if (aUriParser->Parse(utf8PathPtr) != KErrNone)
       
  1257             {
       
  1258             User::Leave(KErrBadName);
       
  1259             }
       
  1260         }
       
  1261     return utf8Path;
       
  1262     }
       
  1263 
       
  1264 // ----------------------------------------------------------------------------
       
  1265 // CRsfwDavSession::EncodeL
       
  1266 // First escape encode and then UTF-8 encode data.
       
  1267 // ----------------------------------------------------------------------------
       
  1268 //
       
  1269 HBufC8* CRsfwDavSession::EncodeL(const TDesC& aData)
       
  1270     {
       
  1271     HBufC8* utf8Data = EscapeUtils::ConvertFromUnicodeToUtf8L(aData);
       
  1272     CleanupStack::PushL(utf8Data);
       
  1273     HBufC8* escapedData = EscapeUtils::EscapeEncodeL(*utf8Data, KSpecials8);
       
  1274     CleanupStack::PopAndDestroy(utf8Data);
       
  1275     return escapedData;
       
  1276     }
       
  1277 
       
  1278 // ----------------------------------------------------------------------------
       
  1279 // CRsfwDavSession::IsConnected
       
  1280 // ----------------------------------------------------------------------------
       
  1281 //
       
  1282 TBool CRsfwDavSession::IsConnected()
       
  1283     {
       
  1284     return iConnected;
       
  1285     }
       
  1286 
       
  1287 // ----------------------------------------------------------------------------
       
  1288 // CRsfwDavSession::NextWebDavTransactionId
       
  1289 // ----------------------------------------------------------------------------
       
  1290 //
       
  1291 TUint CRsfwDavSession::NextWebDavTransactionId()
       
  1292     {
       
  1293     return ++iCurrentWebDavTransactionId;
       
  1294     }
       
  1295 
       
  1296 // ----------------------------------------------------------------------------
       
  1297 // CRsfwDavSession::SetupConnectionL
       
  1298 // ----------------------------------------------------------------------------
       
  1299 //
       
  1300 void CRsfwDavSession::SetupConnectionL()
       
  1301     {
       
  1302     RSocketServ* socketServ;
       
  1303     RConnection* connection;
       
  1304 
       
  1305     DEBUGSTRING(("SetupConnection - start"));
       
  1306     User::LeaveIfError(iRsfwConnectionManager->GetConnection(socketServ, 
       
  1307                                                              connection));
       
  1308     DEBUGSTRING(("iRsfwConnectionManager->GetConnection called"));                                                        
       
  1309     // Now bind the HTTP session with the socket server connection
       
  1310     RStringPool stringPool = iHttpSession.StringPool();
       
  1311     RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo();
       
  1312     connInfo.SetPropertyL(
       
  1313         stringPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()),
       
  1314         THTTPHdrVal(socketServ->Handle()));
       
  1315     connInfo.SetPropertyL(
       
  1316         stringPool.StringF(HTTP::EHttpSocketConnection,
       
  1317                            RHTTPSession::GetTable()), 
       
  1318         THTTPHdrVal(reinterpret_cast<TInt>(connection)));
       
  1319     DEBUGSTRING(("SetupConnection - done"));
       
  1320     }
       
  1321     
       
  1322 //  End of File