--- a/remotestoragefw/webdavaccessplugin/src/rsfwdavsession.cpp Wed Jun 09 10:37:35 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1322 +0,0 @@
-/*
-* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: API for WebDAV operations
- *
-*/
-
-
-// INCLUDE FILES
-#include <httpstringconstants.h>
-#include <http/rhttpheaders.h>
-#include <escapeutils.h>
-#include <xml/matchdata.h>
-
-#include "rsfwdavsession.h"
-#include "rsfwdavtransaction.h"
-#include "rsfwconnectionmanager.h"
-#include "rsfwpropfindparser.h"
-#include "rsfwlockqueryparser.h"
-#include "mdebug.h"
-
-// CONSTANTS
-// characters that will be encoded in the url
-_LIT8(KSpecials8, " \"<>#%{}|\\^~[]`");
-
-// ============================ MEMBER FUNCTIONS ==============================
-CRsfwDavSession* CRsfwDavSession::NewL(
- MRsfwDavResponseObserver* aWebDavResponseObserver,
- MRsfwConnectionObserver* aRsfwConnectionObserver)
- {
- CRsfwDavSession* self = new (ELeave) CRsfwDavSession;
- CleanupStack::PushL(self);
- self->ConstructL(aWebDavResponseObserver, aRsfwConnectionObserver);
- CleanupStack::Pop(self);
- return self;
- }
-
-void CRsfwDavSession::ConstructL(
- MRsfwDavResponseObserver* aWebDavResponseObserver,
- MRsfwConnectionObserver* aRsfwConnectionObserver)
- {
- DEBUGSTRING(("DavSess: ConstructL: enter"));
- User::LeaveIfError(iFs.Connect());
- iWebDavResponseObserver = aWebDavResponseObserver;
- iRsfwConnectionObserver = aRsfwConnectionObserver;
-
- // Create classes needed for parsing PropFind and Lock request replies
- // Creating these later seems to cause emulator hang-ups.
- // If the problem does not exist in the real device we may want to
- // delay especially Lock parser creation as locking may not be used at all.
- Xml::CMatchData* matchData = Xml::CMatchData::NewLC();
- matchData->SetMimeTypeL(KTextXml);
- // Select libxml2 parsesr
- matchData->SetVariantL(_L8("libxml2"));
- // Select Symbian XML Parser (=Expat)
-// matchData->SetVariantL(_L8("Symbian"));
- iPropFindParserImpl = CRsfwPropFindParser::NewL();
- iPropFindParser = Xml::CParser::NewL(*matchData, *iPropFindParserImpl);
- iLockQueryParserImpl = CRsfwLockQueryParser::NewL();
- iLockQueryParser = Xml::CParser::NewL(*matchData, *iLockQueryParserImpl);
- CleanupStack::PopAndDestroy(matchData);
-
- // Open the RHTTPSession
- iHttpSession.OpenL();
- iHttpSession.FilterCollection().RemoveFilter(
- iHttpSession.StringPool().StringF( HTTP::EAuthentication, RHTTPSession::GetTable() ));
- // Install this class as the callback for authentication requests:
- // it will take care of basic/digest auth, SSL
- InstallAuthenticationL(iHttpSession);
- DEBUGSTRING(("auth filter installed"));
- }
-
-CRsfwDavSession::~CRsfwDavSession()
- {
- DEBUGSTRING(("CRsfwDavSession::~CRsfwDavSession"));
- delete iPropFindParser;
- delete iPropFindParserImpl;
- delete iLockQueryParser;
- delete iLockQueryParserImpl;
- delete iEncodedHost;
- if (iUserName)
- {
- delete iUserName;
- }
- if (iPassword)
- {
- delete iPassword;
- }
- iHttpSession.Close();
- delete iRsfwConnectionManager;
- iFs.Close();
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetConnected
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetConnected(TBool aConnected)
- {
- iConnected = aConnected;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetWebDavSupportClass
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetWebDavSupportClass(TInt aWebDavSupportClass)
- {
- iWebDavSupportClass = aWebDavSupportClass;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::WebDavSupportClass
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwDavSession::WebDavSupportClass()
- {
- return iWebDavSupportClass;
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::OpenL
-// After calling this function, use options query
-// to trigger TCP level connection.
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::OpenL(const TDesC& aUri,
- TInt aPort,
- const TDesC& aUserName,
- const TDesC& aPassword,
- const TDesC& aAuxData)
- {
- // Store connection parameters
- iHost.Zero();
- iDavRoot.Zero();
-
- // Here we add the port using a simple approach:
- // it needs to go after http://name/
- TInt slashCnt = 0;
- TInt cnt = 0;
- while (cnt < aUri.Length())
- {
- TChar ch = aUri[cnt++];
- if (ch == '/')
- {
- slashCnt++;
- if (slashCnt == 3)
- {
- iHost.Append(':');
- iHost.AppendNum(aPort);
- // At this point we know that
- // the remainder of the uri is the root directory
- }
- }
-
- if (slashCnt > 2)
- {
- iDavRoot.Append(ch);
- }
- else
- {
- iHost.Append(ch);
- }
- }
- // We elso need an encoded form of the host part
- iEncodedHost = EncodeL(iHost.Right(iHost.Length() - KProtocolPrefix));
-
- // iDavRoot must be a directory, and thus should end with a slash
- Slashify(iDavRoot);
-
- // Make the pair
- iHostRoot.Copy(iHost);
- iHostRoot.Append(iDavRoot);
-
- // Assume that the parameters are constant and stable across the session
- iUserName = EncodeL(aUserName);
- iPassword = EncodeL(aPassword);
- iAuxData.Copy(aAuxData);
-
- DEBUGSTRING16(("connecting to host='%S', port=%d, root='%S', data=%S",
- &iHost,
- aPort,
- &iDavRoot,
- &iAuxData));
-
- if (iAuxData.Length() == 0)
- {
- // in case of empty access point info, set it to '?' (ask user)
- _LIT(KAskUser, "?");
- iAuxData.Copy(KAskUser);
- }
-
- if (!iRsfwConnectionManager)
- {
- iRsfwConnectionManager =
- CRsfwConnectionManager::NewL(iRsfwConnectionObserver);
- iRsfwConnectionManager->UseIapL(aAuxData);
- }
-
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::OptionsL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::OptionsL()
- {
- TPtrC null;
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(null, EFalse, &uriParser);
-
- DEBUGSTRING8(("OPTIONS '%S'", &uriParser.UriDes()));
-
- // Establish a link-layer connection
- if (iRsfwConnectionManager)
- {
- SetupConnectionL();
- }
-
- RStringPool stringPool = StringPool();
-
- // Introducing the webdav headers for the propfind
- RStringF mOptions = stringPool.OpenFStringL(KWebDavOptions);
- CleanupClosePushL(mOptions);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpOptions,
- uriParser,
- mOptions,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mOptions
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr = webDavTransaction->
- HttpTransaction().Request().GetHeaderCollection();
-
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- CleanupStack::Pop(2); //webDavTransaction, uri
- delete uri;
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::PropFindL
-// Implements WebDAV PROPFIND method.
-// Parameters: Name of the directory or file
-// CRsfwDirEnt pointer array to be filled with directory metadata
-// PROPFIND depth
-// aIsDir, is this directory or file,
-// some extra checks are made based on this...
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::PropFindL(const TDesC &aPath,
- TInt aDepth,
- TBool aIsDir,
- RPointerArray<CRsfwDirEnt>& aDirEnts)
- {
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, aIsDir, &uriParser);
-
- DEBUGSTRING8(("PROPFIND '%S'", &uriParser.UriDes()));
-
- // This function is used from several places
- TWebDavOp op;
- if (aDepth == 1)
- {
- op = EWebDavOpPropFindMulti;
- }
- else // (aDepth == 0)
- {
- op = EWebDavOpPropFindSingle;
- }
-
- RStringPool stringPool = StringPool();
- RStringF mPropFind = stringPool.OpenFStringL(KWebDavPropFind);
- CleanupClosePushL(mPropFind);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- op,
- uriParser,
- mPropFind,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mPropFind
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr = webDavTransaction->
- HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- SetHeaderL(hdr, HTTP::EContentType, KTextXml);
-
- // Assumes that the target uri has been cached in an earlier connect
- SetDepthHeaderL(hdr, aDepth);
-
- // XML body
- HBufC8* requestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize);
- TPtr8 requestBodyBufferPtr = requestBodyBuffer->Des();
-
- // To make things at least little bit faster,
- // let's try to get "minimal" set
- // Maybe useful one day:
- // - <D:getcontentlanguage/>
- // - <D:creationdate/>
- // Apache mod_dav 1.0.3 doesn't support:
- // - <D:displayname/>
- _LIT8(KPropFindRequestBody, "\
-<?xml version=\"1.0\"?>\
-<propfind xmlns=\"DAV:\">\
-<prop>\
-<getcontenttype/>\
-<getlastmodified/>\
-<getcontentlength/>\
-<resourcetype/>\
-<getetag/>\
-</prop>\
-</propfind>\
-");
- requestBodyBufferPtr.Append(KPropFindRequestBody);
- webDavTransaction->SetBodyData(requestBodyBuffer);
-
- webDavTransaction->SetPropFindDirEntryArray(aDirEnts);
- // We must remember the work directory,
- // as we don't want to list that when building directory listing.
- HBufC* propFindPath = HBufC::NewL(iHostRoot.Length() +
- KMaxPath +
- 1);
- TPtr propFindPathPtr = propFindPath->Des();
- propFindPathPtr.Copy(iDavRoot);
- propFindPathPtr.Append(aPath);
- // The whole path must end with a slash
- Slashify(propFindPathPtr);
- // Before comparing the path from the server is decoded,
- // so we can compare against the original 16-bit string.
- webDavTransaction->SetPropFindPath(propFindPath);
- CleanupStack::Pop(2); // webdavtransaction, uri
- delete uri;
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::GetL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::GetL(const TDesC& aSrcPath,
- const TDesC& aDstPath,
- TInt aOffset,
- TInt* aLength,
- TUint aFlags)
- {
- // Basically just a HTTP get with some local processing
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aSrcPath, EFalse, &uriParser);
-
-#ifdef _DEBUG
- {
- TInt length;
- if (aLength)
- {
- length = *aLength;
- }
- else
- {
- length = 0;
- }
- DEBUGSTRING8(("GET '%S' (off=%d, len=%d)",
- &uriParser.UriDes(),
- aOffset,
- length));
- }
-#endif // DEBUG
-
- // Introducing the webdav headers for GET
- RStringPool stringPool = StringPool();
- RStringF mGet = stringPool.StringF(HTTP::EGET,
- RHTTPSession::GetTable());
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpGet,
- uriParser,
- mGet,
- NextWebDavTransactionId());
- CleanupStack::PushL(webDavTransaction);
-
- // Not sure if this is needed: we are setting conditions
- // which mod_dav never gets, cos this is a GET..
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- if (aLength && (*aLength > 0)) // partial get
- {
- TBuf8<KMaxFieldValueLength> rangeHeader;
- _LIT8(KBytesEquals, "bytes=");
- rangeHeader.Append(KBytesEquals);
- rangeHeader.AppendNum(aOffset);
- rangeHeader.Append('-');
- rangeHeader.AppendNum(aOffset + *aLength - 1);
- SetHeaderL(hdr, HTTP::ERange, rangeHeader);
- }
-
- webDavTransaction->SetBodyFileL(aDstPath, aOffset, aLength, aFlags);
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(uri);
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::PutL
-// This amounts to a PUT sending the src data to the destination.
-// Expects that the aSrcPath param is relative to iDavRoot.
-// If aSrcPath is empty, an empty file will be created.
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::PutL(const TDesC& aSrcPath,
- const TDesC& aDstPath,
- const TDesC8& aMimeType,
- TInt aOffset,
- TInt aLength,
- TInt aTotalLength,
- TBool aUseContentRange,
- const TDesC8* aLockToken)
- {
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aDstPath, EFalse, &uriParser);
-
- DEBUGSTRING8(("PUT '%S'", &uriParser.UriDes()));
-
- RStringPool stringPool = StringPool();
- RStringF mPut = stringPool.OpenFStringL(KWebDavPut);
- CleanupClosePushL(mPut);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpPut,
- uriParser,
- mPut,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mPut
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
- SetHeaderL(hdr, HTTP::EContentType, aMimeType);
-
- if (aLength > 0) // partial put
- {
- if (aUseContentRange)
- {
- TBuf8<KMaxFieldValueLength> rangeHeader;
- _LIT8(KBytes, "bytes ");
- rangeHeader.Append(KBytes);
- rangeHeader.AppendNum(aOffset);
- rangeHeader.Append('-');
- rangeHeader.AppendNum(aOffset + aLength - 1);
- rangeHeader.Append('/');
- if (aTotalLength == 0)
- {
- // The asterisk "*" character means that
- // the instance-length is unknown at the time when
- // the message was generated.
- rangeHeader.Append('*');
- }
- else
- {
- rangeHeader.AppendNum(aTotalLength);
- }
- SetHeaderL(hdr, HTTP::EContentRange, rangeHeader);
- }
- else
- {
- // server doesn't support Content-Range
- // Leave with KrrNotSupported
- // *aLength = aTotalLength;
- }
- }
-
- if (aLockToken)
- {
- SetLockTokenHeaderL(hdr, uri, aLockToken, ETrue);
- }
-
- webDavTransaction->SetBodyFileL(aSrcPath, aOffset, &aLength, 0);
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(uri);
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::DeleteL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::DeleteL(const TDesC& aPath,
- TBool aIsDir,
- const TDesC8* aLockToken)
- {
- // Needs to take locking into account
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, aIsDir, &uriParser);
-
- DEBUGSTRING8(("DELETE '%S'", &uriParser.UriDes()));
-
- RStringPool stringPool = StringPool();
- RStringF mDelete = stringPool.OpenFStringL(KWebDavDelete);
- CleanupClosePushL(mDelete);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpDelete,
- uriParser,
- mDelete,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mDelete
- CleanupStack::PushL(webDavTransaction);
-
- // need to add a special dir on the i
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- if (aLockToken)
- {
- SetLockTokenHeaderL(hdr, uri, aLockToken, ETrue);
- }
-
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(uri);
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::MkDirL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::MkDirL(const TDesC& aPath)
- {
- // Executes a MKCOL with the specified name
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, ETrue, &uriParser);
-
- DEBUGSTRING8(("MKCOL '%S'", &uriParser.UriDes()));
-
- RStringPool stringPool = StringPool();
- RStringF mMkCol = stringPool.OpenFStringL(KWebDavMkCol);
- CleanupClosePushL(mMkCol);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpMkCol,
- uriParser,
- mMkCol,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(1); // mMkCol
- CleanupStack::PushL(webDavTransaction);
-
- // Neeed to add a special dir on the i
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- CleanupStack::Pop(2); // webDavTransaction, uri
- delete uri;
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::MoveL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::MoveL(const TDesC& aOldPath,
- const TDesC& aNewPath,
- TBool aOverwrite,
- const TDesC8* aSrcLockToken,
- const TDesC8* aDstLockToken)
- {
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParserNew;
- HBufC8* uriNew = BuildUriLC(aNewPath, EFalse, &uriParserNew);
- TUriParser8 uriParserOld;
- HBufC8* uriOld = BuildUriLC(aOldPath, EFalse, &uriParserOld);
-
- DEBUGSTRING8(("MOVE '%S' to '%S'",
- &uriParserOld.UriDes(),
- &uriParserNew.UriDes()));
-
- RStringPool stringPool = StringPool();
- RStringF mMove = stringPool.OpenFStringL(KWebDavMove);
- CleanupClosePushL(mMove);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpMove,
- uriParserOld,
- mMove,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mMove
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParserOld, ETrue);
-
- if (aSrcLockToken)
- {
- SetLockTokenHeaderL(hdr, uriOld, aSrcLockToken, ETrue);
- }
-
-
- if (aDstLockToken)
- {
- SetLockTokenHeaderL(hdr, uriNew, aDstLockToken, ETrue);
- }
-
- SetHeaderL(hdr, KWebDavDest, *uriNew);
- if (aOverwrite)
- {
- SetHeaderL(hdr, KWebDavOverwrite, KWebDavOverwriteY);
- }
- else
- {
- SetHeaderL(hdr, KWebDavOverwrite, KWebDavOverwriteN);
- }
-
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(2, uriNew); // uriOld, uriNew
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::LockL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::LockL(const TDesC& aPath,
- TUint aFlags,
- TUint aTimeout,
- CRsfwDavFileInfo** aDavFileInfo)
- {
- // Opens LOCK transaction
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
-
- DEBUGSTRING8(("LOCK '%S' (%d seconds)", &uriParser.UriDes(), aTimeout));
-
- RStringPool stringPool = StringPool();
- RStringF mLock = stringPool.OpenFStringL(KWebDavLock);
- CleanupClosePushL(mLock);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpLock,
- uriParser,
- mLock,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(&mLock);
- CleanupStack::PushL(webDavTransaction);
-
- // headers
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- SetHeaderL(hdr, HTTP::EContentType, KTextXml);
-
- HBufC8* timeoutBuffer = HBufC8::NewLC(KMaxFieldValueLength);
- TPtr8 timeoutBufferPtr = timeoutBuffer->Des();
- timeoutBufferPtr.Append(KSecondDash);
- if (aTimeout != 0)
- {
- timeoutBufferPtr.AppendNum(aTimeout);
- }
- SetHeaderL(hdr, KWebDavTimeout, timeoutBufferPtr);
- CleanupStack::PopAndDestroy(timeoutBuffer);
-
- // XML body
- HBufC8* requestBodyBuffer = HBufC8::NewL(KDefaultSubmitSize);
- TPtr8 requestBodyBufferPtr = requestBodyBuffer->Des();
-
- // Note: locktype "write" is currently the only legal value
- _LIT8(KLockHeaderFormat, "\
-<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
-<D:lockinfo xmlns:D=\"DAV:\">\
-<D:lockscope><D:%S/></D:lockscope>\
-<D:locktype><D:write/></D:locktype>\
-<D:owner xmlns:x=\"http://www.webdav.org/\">\
-<x:lock-user>%S</x:lock-user>\
-<x:created-by>%S</x:created-by>\
-</D:owner>\
-</D:lockinfo>");
-
- _LIT8(KLockScopeShared, "shared");
- _LIT8(KLockScopeExclusive, "exclusive");
- TPtrC8 lockScope;
- if (aFlags & EFileShareAny)
- {
- lockScope.Set(KLockScopeShared);
- }
- else
- {
- lockScope.Set(KLockScopeExclusive);
- }
-
- requestBodyBufferPtr.Format(KLockHeaderFormat, &lockScope, iUserName, iUserName);
- webDavTransaction->SetBodyData(requestBodyBuffer);
-
- HBufC* fileInfoPath = BuildFullPathLC(aPath, EFalse);
- webDavTransaction->SetDavFileInfoL(aDavFileInfo, *fileInfoPath);
- CleanupStack::PopAndDestroy(fileInfoPath);
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(uri);
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::UnlockL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::UnlockL(const TDesC& aPath,
- const TDesC8* aLockToken)
- {
- // Opens LOCK transaction
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- if (iWebDavSupportClass < KDavVersionTwo)
- {
- User::Leave(KErrNotSupported);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
-
- DEBUGSTRING8(("UNLOCK '%S'", &uriParser.UriDes()));
-
- RStringPool stringPool = StringPool();
- RStringF mUnlock = stringPool.OpenFStringL(KWebDavUnlock);
- CleanupClosePushL(mUnlock);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpUnlock,
- uriParser,
- mUnlock,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(); // mUnlock
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- HBufC8* lockToken = HBufC8::NewLC(aLockToken->Length() +
- KLockTokenOverhead);
- TPtr8 lockTokenPtr = lockToken->Des();
- lockTokenPtr.Append('<');
- lockTokenPtr.Append(*aLockToken);
- lockTokenPtr.Append('>');
- SetHeaderL(hdr, KWedDavLockToken, lockTokenPtr);
- CleanupStack::PopAndDestroy(lockToken);
-
- CleanupStack::Pop(2); // webdavtransaction , uri
- delete uri;
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::RefreshLockL
-// ----------------------------------------------------------------------------
-//
-CRsfwDavTransaction* CRsfwDavSession::RefreshLockL(const TDesC& aPath,
- TUint aTimeout,
- const TDesC8* aLockToken,
- CRsfwDavFileInfo** aDavFileInfo)
- {
- // Opens LOCK transaction
- if (!IsConnected())
- {
- User::Leave(KErrNotReady);
- }
-
- if (iWebDavSupportClass < KDavVersionTwo)
- {
- User::Leave(KErrNotSupported);
- }
-
- TUriParser8 uriParser;
- HBufC8* uri = BuildUriLC(aPath, EFalse, &uriParser);
-
- DEBUGSTRING8(("LOCK (refresh) '%S' (%d seconds)",
- &uriParser.UriDes(),
- aTimeout));
-
- RStringPool stringPool = StringPool();
- RStringF mLock = stringPool.OpenFStringL(KWebDavLock);
- CleanupClosePushL(mLock);
- CRsfwDavTransaction* webDavTransaction =
- CRsfwDavTransaction::NewL(this,
- EWebDavOpRefreshLock,
- uriParser,
- mLock,
- NextWebDavTransactionId());
- CleanupStack::PopAndDestroy(&mLock);
- CleanupStack::PushL(webDavTransaction);
-
- RHTTPHeaders hdr =
- webDavTransaction->HttpTransaction().Request().GetHeaderCollection();
-
- // Add headers appropriate to all methods
- SetBasicHeadersL(hdr, uriParser, ETrue);
-
- // do not use tagged lock token, as refresh 'If' header
- // should always contain only a single lock token
- // (only one lock may be refreshed at a time).
- SetLockTokenHeaderL(hdr, uri, aLockToken, EFalse);
-
- HBufC8* timeoutBuffer = HBufC8::NewLC(KMaxFieldValueLength);
- TPtr8 timeoutBufferPtr = timeoutBuffer->Des();
- timeoutBufferPtr.Append(KSecondDash);
- if (aTimeout != 0)
- {
- timeoutBufferPtr.AppendNum(aTimeout);
- }
- SetHeaderL(hdr, KWebDavTimeout, timeoutBufferPtr);
- CleanupStack::PopAndDestroy(timeoutBuffer);
-
- HBufC* fileInfoPath = BuildFullPathLC(aPath, EFalse);
- webDavTransaction->SetDavFileInfoL(aDavFileInfo, *fileInfoPath);
- CleanupStack::PopAndDestroy(fileInfoPath);
- CleanupStack::Pop(webDavTransaction);
- CleanupStack::PopAndDestroy(uri);
- return webDavTransaction;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::GetCredentialsL
-// From MHTTPAuthenticationCallback
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwDavSession::GetCredentialsL(const TUriC8& /* aURI */,
- RString aRealm,
- RStringF /*aAuthenticationType*/,
- RString& aUserName,
- RString& aPassword)
- {
- // if we have not tried to send the current credentials once,
- // and we have at least username proceed, othwise return KErrAccessDenied
- if (iCredentialRequestCount || (!iUserName))
- {
- iCredentialRequestCount = 0;
- User::Leave(KErrAccessDenied);
- }
- iCredentialRequestCount++;
-
- TRAPD(err, aUserName = aRealm.Pool().OpenStringL(*iUserName));
- if (!err)
- {
- TRAP(err, aPassword = aRealm.Pool().OpenStringL(*iPassword));
- if (!err)
- {
- return ETrue;
- }
- }
- return EFalse;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetHeaderL
-// Convenience method for setting up the header.
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetHeaderL(RHTTPHeaders aHeaders,
- TInt aHdrField,
- const TDesC8& aHdrValue)
- {
- RStringF valStr = StringPool().OpenFStringL(aHdrValue);
- CleanupClosePushL(valStr);
- THTTPHdrVal val(valStr);
- aHeaders.SetFieldL(
- StringPool().StringF(aHdrField, RHTTPSession::GetTable()), val);
- CleanupStack::PopAndDestroy(&valStr);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetHeaderL
-// Convenience method for setting up the header.
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetHeaderL(RHTTPHeaders aHeaders,
- const TDesC8& aHdrName,
- const TDesC8& aHdrValue)
- {
- RStringF nameStr = StringPool().OpenFStringL(aHdrName);
- CleanupClosePushL(nameStr);
- RStringF valueStr = StringPool().OpenFStringL(aHdrValue);
- CleanupClosePushL(valueStr);
- THTTPHdrVal value(valueStr);
- aHeaders.SetFieldL(nameStr, value);
- CleanupStack::PopAndDestroy(2); // valueStr, nameStr
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetBasicHeadersL
-// Convenience method for setting up the header.
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetBasicHeadersL(RHTTPHeaders aHeaders,
- const TUriC8& aUri,
- TBool aNoProxy)
- {
- // Add headers appropriate to all methods
- SetHeaderL(aHeaders, HTTP::EUserAgent, KUserAgent);
- SetHeaderL(aHeaders, HTTP::EAccept, KAccept);
- // do not send host header if using SSL (not supported currently)
- TPtrC8 scheme;
- if (aUri.IsPresent(EUriScheme))
- {
- scheme.Set(aUri.Extract(EUriScheme));
- }
- if (scheme.CompareF(KHttpsScheme8) != 0)
- {
- SetHeaderL(aHeaders, HTTP::EHost, *iEncodedHost);
- }
- SetHeaderL(aHeaders, HTTP::EConnection, KKeepAlive);
- if (aNoProxy)
- {
- // see RFC 2518 10.4.5 If Header and Non-DAV Aware Proxies
- // "As in general clients may not be able to reliably detect
- // non-DAV aware intermediates, they are advised to always
- // prevent caching using the request directives mentioned above."
- SetHeaderL(aHeaders, HTTP::EPragma, KWebDavNoProxy);
- SetHeaderL(aHeaders, HTTP::ECacheControl, KWebDavNoProxy);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetDepthHeaderL
-// Some DAV requests require this for specifying depth of copies etc.
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetDepthHeaderL(RHTTPHeaders aHeaders, TInt aDepth)
- {
- RStringF depthStr = StringPool().OpenFStringL(KWebDavDepth);
- CleanupClosePushL(depthStr);
- THTTPHdrVal depth(aDepth);
- aHeaders.SetFieldL(depthStr, depth);
- CleanupStack::PopAndDestroy(&depthStr);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetLockTokenHeaderL
-// The lock token header can be tagged with the resource (file) URI
-// This is especially important for DELETE and MOVE of a file,
-// as they will also affect the container (directory), which is not locked
-// (in which case supplying a lock token is an error).
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetLockTokenHeaderL(RHTTPHeaders aHeaders,
- const TDesC8* aUri,
- const TDesC8* aLockToken,
- TBool aUseTaggedLockToken)
- {
- DEBUGSTRING(("using a tagged lock token"));
- // KLockTokenOverhead for 'tagged' lock token is 2 chars around the uri,
- // one space, and 4 chars around the locktoken
- // i.e. <target-url> (<target-token>)
- TInt tagoverhead;
- if (aUseTaggedLockToken)
- {
- tagoverhead = KTaggedLockTokenOverhead;
- }
- else
- {
- tagoverhead = KLockTokenOverhead;
- }
- HBufC8* lockToken = HBufC8::NewLC(aUri->Length()+ aLockToken->Length() +
- tagoverhead);
- TPtr8 lockTokenPtr = lockToken->Des();
- if (aUseTaggedLockToken)
- {
- lockTokenPtr.Format(KTaggedParenthAngleFormat, aUri, aLockToken);
- }
- else
- {
- lockTokenPtr.Format(KParenthAngleFormat, aLockToken);
- }
-
- DEBUGSTRING8(("lt='%S'", &lockTokenPtr));
- SetHeaderL(aHeaders, KWebDavIf, lockTokenPtr);
- CleanupStack::PopAndDestroy(lockToken);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::WebDavTransactionCompleteL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::WebDavTransactionCompleteL(
- CRsfwDavTransaction* aWebDavTransaction)
- {
- TUint webDavTransactionId = aWebDavTransaction->Id();
- delete aWebDavTransaction;
- iWebDavResponseObserver->RequestCompleteL(webDavTransactionId);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::WebDavTransactionError
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::WebDavTransactionError(
- CRsfwDavTransaction* aWebDavTransaction)
- {
- TUint webDavTransactionId = aWebDavTransaction->Id();
- TInt status = aWebDavTransaction->Status();
- delete aWebDavTransaction;
- iWebDavResponseObserver->RequestError(webDavTransactionId, status);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetPropFindParameters
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetPropFindParametersL(
- RPointerArray<CRsfwDirEnt>* aDirEntArray,
- const TDesC& aPropFindPath,
- TInt aDepth)
- {
- iPropFindParserImpl->SetDirEntArray(aDirEntArray);
- iPropFindParserImpl->SetTargetDirectory(aPropFindPath, aDepth);
- iPropFindParser->ParseBeginL();
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetLockQueryParameters
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetLockQueryParameters(CRsfwDavFileInfo* aDavFileInfo)
- {
- iLockQueryParserImpl->SetDavFileInfo(aDavFileInfo);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::ParsePropFindResponseL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::ParsePropFindResponseL(const TDesC8& aResponse)
- {
- // only first call to this function really initiates data structures in the XML parser
- iPropfindParsingActive = ETrue;
- iPropFindParser->ParseL(aResponse);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::ParseLockResponseL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::ParseLockResponseL(const TDesC8& aResponse)
- {
- iLockQueryParser->ParseL(aResponse);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::PropFindResponseEndL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::PropFindResponseEndL()
- {
- iPropFindParser->ParseEndL();
- iPropfindParsingActive = EFalse;
- TInt err = iPropFindParserImpl->GetLastError();
- if (err)
- {
- User::Leave(err);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::LockResponseEndL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::LockResponseEndL()
- {
- iLockQueryParser->ParseEndL();
- TInt err = iPropFindParserImpl->GetLastError();
- if (err)
- {
- User::Leave(err);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::CancelParsing
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::CancelParsing(TWebDavOp aOp)
- {
- // Only will do something if this operation is PROPFIND,
- // and we have started to parse the response.
- // UI does not allow to cancel LOCK requests.
- // If this would be possible this mechanism should be expanded
- // to also cover LOCK parsing.
- if ((aOp == EWebDavOpPropFindSingle) ||
- (aOp == EWebDavOpPropFindMulti))
- {
- if (iPropfindParsingActive)
- {
- // When XML parsing is cancelled when the request is cancelled,
- // there is some XML error (invalid token etc.), ignore the error
- TRAP_IGNORE(iPropFindParser->ParseEndL());
- iPropfindParsingActive = EFalse;
- }
- }
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::HttpSession
-// ----------------------------------------------------------------------------
-//
-RHTTPSession& CRsfwDavSession::HttpSession()
- {
- return iHttpSession;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::StringPool
-// ----------------------------------------------------------------------------
-//
-RStringPool CRsfwDavSession::StringPool()
- {
- return iHttpSession.StringPool();
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::Slashify
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::Slashify(TDes& aStr)
- {
- if (aStr.Length() &&
- (aStr[aStr.Length() - 1] != '/') &&
- aStr.Length() < aStr.MaxLength())
- {
- aStr.Append('/');
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::BuildPathLC
-// This function constructs a file path from davroot + path
-// ----------------------------------------------------------------------------
-//
-HBufC* CRsfwDavSession::BuildPathLC(const TDesC& aRoot,
- const TDesC& aPath,
- TBool aEndSlash)
- {
- // 1 is for a possible slash added to the end of the uri...
- HBufC* path = HBufC::NewLC(aRoot.Length() +
- aPath.Length() +
- 1);
- TPtr pathPtr = path->Des();
- pathPtr.Append(aRoot);
- pathPtr.Append(aPath);
- if (aEndSlash)
- {
- Slashify(pathPtr);
- }
- return path;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::BuildFullPathLC
-// This function constructs a file path from davroot + path
-// ----------------------------------------------------------------------------
-//
-HBufC* CRsfwDavSession::BuildFullPathLC(const TDesC& aPath,
- TBool aEndSlash)
- {
- return BuildPathLC(iDavRoot, aPath, aEndSlash);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::BuildUriLC
-// This function constructs an URI from hostname + davroot + path
-// The URI is first escape encoded and then UTF-8 encoded.
-// Note that in addition to returning the uri string, this function
-// will also "populate" aUriParser with the full URI
-// ----------------------------------------------------------------------------
-//
-HBufC8* CRsfwDavSession::BuildUriLC(const TDesC& aPath,
- TBool aEndSlash,
- TUriParser8* aUriParser)
- {
- // 1 is for a possible slash added to the end of the uri...
- HBufC* uri = BuildPathLC(iHostRoot, aPath, aEndSlash);
- HBufC8* utf8Path = EncodeL(*uri);
- CleanupStack::PopAndDestroy(uri);
- CleanupStack::PushL(utf8Path);
- TPtr8 utf8PathPtr = utf8Path->Des();
- if (aUriParser)
- {
- if (aUriParser->Parse(utf8PathPtr) != KErrNone)
- {
- User::Leave(KErrBadName);
- }
- }
- return utf8Path;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::EncodeL
-// First escape encode and then UTF-8 encode data.
-// ----------------------------------------------------------------------------
-//
-HBufC8* CRsfwDavSession::EncodeL(const TDesC& aData)
- {
- HBufC8* utf8Data = EscapeUtils::ConvertFromUnicodeToUtf8L(aData);
- CleanupStack::PushL(utf8Data);
- HBufC8* escapedData = EscapeUtils::EscapeEncodeL(*utf8Data, KSpecials8);
- CleanupStack::PopAndDestroy(utf8Data);
- return escapedData;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::IsConnected
-// ----------------------------------------------------------------------------
-//
-TBool CRsfwDavSession::IsConnected()
- {
- return iConnected;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::NextWebDavTransactionId
-// ----------------------------------------------------------------------------
-//
-TUint CRsfwDavSession::NextWebDavTransactionId()
- {
- return ++iCurrentWebDavTransactionId;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwDavSession::SetupConnectionL
-// ----------------------------------------------------------------------------
-//
-void CRsfwDavSession::SetupConnectionL()
- {
- RSocketServ* socketServ;
- RConnection* connection;
-
- DEBUGSTRING(("SetupConnection - start"));
- User::LeaveIfError(iRsfwConnectionManager->GetConnection(socketServ,
- connection));
- DEBUGSTRING(("iRsfwConnectionManager->GetConnection called"));
- // Now bind the HTTP session with the socket server connection
- RStringPool stringPool = iHttpSession.StringPool();
- RHTTPConnectionInfo connInfo = iHttpSession.ConnectionInfo();
- connInfo.SetPropertyL(
- stringPool.StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()),
- THTTPHdrVal(socketServ->Handle()));
- connInfo.SetPropertyL(
- stringPool.StringF(HTTP::EHttpSocketConnection,
- RHTTPSession::GetTable()),
- THTTPHdrVal(reinterpret_cast<TInt>(connection)));
- DEBUGSTRING(("SetupConnection - done"));
- }
-
-// End of File