--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/remotestoragefw/webdavaccessplugin/src/rsfwdavaccess.cpp Wed Sep 01 12:15:08 2010 +0100
@@ -0,0 +1,1179 @@
+/*
+* 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: Implements remote access plugin API using WebDAV protocol
+ *
+*/
+
+
+// INCLUDE FILES
+#include "rsfwdavaccess.h"
+#include "rsfwdavfileinfo.h"
+#include "rsfwdavaccesscontext.h"
+#include "rsfwdavtransaction.h"
+#include "mdebug.h"
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+void CRsfwDavAccess::ConstructL()
+ {
+ }
+
+CRsfwDavAccess* CRsfwDavAccess::NewL()
+ {
+ CRsfwDavAccess* self = new (ELeave) CRsfwDavAccess;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CRsfwDavAccess::~CRsfwDavAccess()
+ {
+ delete iWebDavSession;
+ iDavFileInfos.ResetAndDestroy();
+ iDavAccessContexts.ResetAndDestroy();
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::DavFileInfoL
+// Find the file info for the given file name.
+// ----------------------------------------------------------------------------
+//
+CRsfwDavFileInfo* CRsfwDavAccess::DavFileInfoL(const TDesC& aName)
+ {
+ TInt index = DavFileInfoIndexL(aName);
+ if (index != KErrNotFound)
+ {
+ return iDavFileInfos[index];
+ }
+ return NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::AddDavFileInfo
+// Add a new file info entry.
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::AddDavFileInfo(CRsfwDavFileInfo* aDavFileInfo)
+ {
+#ifdef _DEBUG
+ TPtrC namePtr;
+ if (aDavFileInfo->Name())
+ {
+ namePtr.Set(*aDavFileInfo->Name());
+ }
+ TPtrC8 lockPtr;
+ if (aDavFileInfo->LockToken())
+ {
+ lockPtr.Set(*aDavFileInfo->LockToken());
+ }
+ DEBUGSTRING16(("Add file info: name='%S'", &namePtr));
+ DEBUGSTRING8((" lock='%S', time=%d",
+ &lockPtr,
+ aDavFileInfo->Timeout()));
+
+#endif // DEBUG
+ iDavFileInfos.Append(aDavFileInfo);
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::RemoveDavFileInfoL
+// Remove a file info entry.
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::RemoveDavFileInfoL(const TDesC& aPath)
+ {
+ TInt index = DavFileInfoIndexL(aPath);
+ if (index != KErrNotFound)
+ {
+ CRsfwDavFileInfo* davFileInfo = iDavFileInfos[index];
+#ifdef _DEBUG
+ TPtrC namePtr;
+ if (davFileInfo->Name())
+ {
+ namePtr.Set(*davFileInfo->Name());
+ }
+ DEBUGSTRING16(("Remove file info: name='%S'", &namePtr));
+#endif // DEBUG
+ iDavFileInfos.Remove(index);
+ delete davFileInfo;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::SetupL
+// Setup - should be immediately followed by NewL() call.
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::SetupL(MRsfwRemoteAccessObserver* aRsfwRemoteAccessObserver)
+ {
+ DEBUGSTRING(("DAV: SetupL"));
+ MRsfwConnectionObserver* rsfwConnectionObserver = NULL;
+ if (aRsfwRemoteAccessObserver)
+ {
+ // Cascade remote access observers
+ iRsfwRemoteAccessObserver = aRsfwRemoteAccessObserver;
+ rsfwConnectionObserver = this;
+ }
+ iWebDavSession = CRsfwDavSession::NewL(this, rsfwConnectionObserver);
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::OpenL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::OpenL(const TUriC& aUri,
+ const TDesC& /*aFriendlyName*/,
+ const TDesC& aUserName,
+ const TDesC& aPassword,
+ const TDesC& aAuxData,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ HBufC* url = HBufC::NewLC(KHttpsScheme().Length() +
+ KMaxServerNameLen +
+ 1 +
+ KMaxPath);
+ TPtr urlPtr = url->Des();
+
+ TInt portNumber = 0;
+ if (aUri.IsPresent(EUriPort))
+ {
+ TLex portx(aUri.Extract(EUriPort));
+ if (portx.Val(portNumber) != KErrNone)
+ {
+ portNumber = 0;
+ }
+ }
+
+ // Check scheme and map it to port number or vice versa
+ TPtrC scheme;
+ if (aUri.IsPresent(EUriScheme))
+ {
+ scheme.Set(aUri.Extract(EUriScheme));
+ }
+ if (scheme.Length())
+ {
+ if (portNumber == 0)
+ {
+ if (scheme.CompareF(KHttpsScheme) == 0)
+ {
+ portNumber = KHttpsPortNumber;
+ }
+ else
+ {
+ portNumber = KHttpPortNumber;
+ }
+ }
+ }
+ else
+ {
+ if (portNumber == 0)
+ {
+ portNumber = KHttpPortNumber;
+ }
+ if (portNumber == KHttpPortNumber)
+ {
+ scheme.Set(KHttpScheme);
+ }
+ else if (portNumber == KHttpsPortNumber)
+ {
+ scheme.Set(KHttpsScheme);
+ }
+ else
+ {
+ User::Leave(KErrBadName);
+ }
+ }
+
+ TPtrC rootDirectory;
+ if (aUri.IsPresent(EUriPath))
+ {
+ rootDirectory.Set(aUri.Extract(EUriPath));
+ }
+ iRootDirectory.Copy(rootDirectory);
+ if (!iRootDirectory.Length() ||
+ iRootDirectory[iRootDirectory.Length() - 1] != '/')
+ {
+ // Append trailing '/'
+ iRootDirectory.Append('/');
+ }
+
+ urlPtr.Copy(scheme);
+ urlPtr.Append(':');
+ urlPtr.Append('/');
+ urlPtr.Append('/');
+ urlPtr.Append(aUri.Extract(EUriHost));
+ // There needs to be a slash between server name and the root dir
+ // (we assume that there cannot be an excess of slash characters)
+ if (urlPtr[urlPtr.Length() - 1] != '/')
+ {
+ if (!iRootDirectory.Length() || (iRootDirectory[0] != '/'))
+ {
+ urlPtr.Append('/');
+ }
+ }
+ urlPtr.Append(iRootDirectory);
+
+ DEBUGSTRING16(("DAV: OpenL to URL '%S'", &urlPtr));
+
+ iWebDavSession->OpenL(urlPtr,
+ portNumber,
+ aUserName,
+ aPassword,
+ aAuxData);
+ CleanupStack::PopAndDestroy(url);
+ return OptionsL(aResponseHandler);
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::GetDirectoryL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::GetDirectoryL(const TDesC& aPathName,
+ RPointerArray<CRsfwDirEnt>& aDirEnts,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ // Get the contents of the directory
+ DEBUGSTRING16(("DAV: GetDirectory '%S'", &aPathName));
+
+ // check that arguments are sensible
+ // aPathName might here be null (mounted root directory)
+ if (aPathName.Length() > KMaxPath)
+ {
+ User::Leave(KErrBadName);
+ }
+
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ CRsfwDavAccessContextPropFindDir* davAccessContextPropFindDir =
+ CRsfwDavAccessContextPropFindDir::NewL(this,
+ aResponseHandler,
+ aPathName,
+ 1,
+ NULL,
+ &aDirEnts);
+ TUint id = AddAccessContext(davAccessContextPropFindDir);
+ davAccessContextPropFindDir->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::GetFileL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::GetFileL(const TDesC& aRemotePathName,
+ const TDesC& aLocalPathName,
+ TInt aOffset,
+ TInt* aLength,
+ TUint aFlags,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+
+#ifdef _DEBUG
+ {
+ TInt length;
+ if (aLength)
+ {
+ length = *aLength;
+ }
+ else
+ {
+ length = 0;
+ }
+ DEBUGSTRING16(("DAV: GetFile rn='%S', ln='%S' (off=%d, len=%d)",
+ &aRemotePathName,
+ &aLocalPathName,
+ aOffset,
+ length));
+ }
+#endif // DEBUG
+
+ // check that arguments are sensible
+ if (aOffset < 0 ||
+ (aLength && *aLength < 0) ||
+ (!aResponseHandler))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aLocalPathName.Length() == 0) ||
+ (aLocalPathName.Length() > KMaxPath) ||
+ (aRemotePathName.Length() == 0) ||
+ (aRemotePathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextGet* davAccessContextGet =
+ CRsfwDavAccessContextGet::NewL(this,
+ aResponseHandler,
+ aRemotePathName,
+ aLocalPathName,
+ aOffset,
+ aLength,
+ aFlags);
+ TUint id = AddAccessContext(davAccessContextGet);
+ davAccessContextGet->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::PutFileL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::PutFileL(const TDesC& aLocalPathName,
+ const TDesC& aRemotePathName,
+ const TDesC8& aMimeType,
+ TInt aOffset,
+ TInt aLength,
+ TInt aTotalLength,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ // Copy file to server using PUT,
+ // might require lock token, if the destination file is locked...
+#ifdef _DEBUG
+ {
+ TInt length;
+ if (aLength)
+ {
+ length = aLength;
+ }
+ else
+ {
+ length = 0;
+ }
+ DEBUGSTRING16(("DAV: PutFile ln='%S', rn='%S' (off=%d, len=%d)",
+ &aLocalPathName,
+ &aRemotePathName,
+ aOffset,
+ length));
+ }
+#endif // DEBUG
+
+ // check that arguments are sensible
+ if (aOffset < 0 ||
+ (aLength < 0) ||
+ (((aOffset + aLength) > aTotalLength) && aTotalLength > 0) ||
+ (!aResponseHandler))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // note that aLocalPathName can be undefined
+ // (CreateFile calls with null-ptr)
+ if ((aLocalPathName.Length() > KMaxPath) ||
+ (aRemotePathName.Length() == 0) ||
+ (aRemotePathName.Length() > KMaxPath) ||
+ (aMimeType.Length() > KMaxMimeTypeLength))
+ {
+ User::Leave(KErrBadName);
+ }
+
+
+ const HBufC8* lockToken = NULL;
+ CRsfwDavFileInfo *davFileInfo = DavFileInfoL(aRemotePathName);
+ if (davFileInfo)
+ {
+ lockToken = davFileInfo->LockToken();
+ }
+ CRsfwDavAccessContextPut* davAccessContextPut =
+ CRsfwDavAccessContextPut::NewL(this,
+ aResponseHandler,
+ aLocalPathName,
+ aRemotePathName,
+ aMimeType,
+ aOffset,
+ aLength,
+ aTotalLength,
+ lockToken);
+ TUint id = AddAccessContext(davAccessContextPut);
+ davAccessContextPut->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::PutFileL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::PutFileL(const TDesC& aLocalPathName,
+ const TDesC& aRemotePathName,
+ const TDesC8& aMimeType,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ return PutFileL(aLocalPathName,
+ aRemotePathName,
+ aMimeType,
+ 0,
+ NULL,
+ 0,
+ aResponseHandler);
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::CreateFileL
+// overwriting info not needed in HTTP PUT
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::CreateFileL(const TDesC& aPathName,
+ TBool /*aOverWriting*/,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: CreateFile '%S'", &aPathName));
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ // Could create the file only from LOCK,
+ // but that seems to cause 500 Internal Error with several
+ // Apache servers...
+ TPtrC null;
+ return PutFileL(null, aPathName, KTextPlain, 0, NULL, 0, aResponseHandler);
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::MakeDirectoryL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::MakeDirectoryL(
+ const TDesC& aPathName,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: MakeDirectory", &aPathName));
+
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextMkDir* davAccessContextMkDir =
+ CRsfwDavAccessContextMkDir::NewL(this,
+ aResponseHandler,
+ aPathName);
+ TUint id = AddAccessContext(davAccessContextMkDir);
+ davAccessContextMkDir->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::DeleteDirectoryL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::DeleteDirectoryL(
+ const TDesC& aPathName,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: DeleteDirectory '%S'", &aPathName));
+
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextDelete* davAccessContextDelete =
+ CRsfwDavAccessContextDelete::NewL(this,
+ aResponseHandler,
+ aPathName,
+ ETrue,
+ NULL);
+ TUint id = AddAccessContext(davAccessContextDelete);
+ davAccessContextDelete->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::DeleteFileL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::DeleteFileL(const TDesC& aPathName,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: DeleteFile '%S'", &aPathName));
+
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ const HBufC8* lockToken = NULL;
+ CRsfwDavFileInfo *davFileInfo = DavFileInfoL(aPathName);
+ if (davFileInfo)
+ {
+ lockToken = davFileInfo->LockToken();
+ }
+ CRsfwDavAccessContextDelete* davAccessContextDelete =
+ CRsfwDavAccessContextDelete::NewL(this,
+ aResponseHandler,
+ aPathName,
+ EFalse,
+ lockToken);
+ TUint id = AddAccessContext(davAccessContextDelete);
+ davAccessContextDelete->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::RenameL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::RenameL(const TDesC& aSrcPathName,
+ const TDesC& aDstPathName,
+ TBool aOverwrite,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: Rename '%S' to '%S'", &aSrcPathName, &aDstPathName));
+
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aSrcPathName.Length() == 0) ||
+ (aSrcPathName.Length() > KMaxPath) ||
+ (aDstPathName.Length() == 0) ||
+ (aDstPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ // lock token for the source file, if the source is locked...
+ const HBufC8* lockToken = NULL;
+ CRsfwDavFileInfo* davFileInfo = DavFileInfoL(aSrcPathName);
+ if (davFileInfo)
+ {
+ lockToken = davFileInfo->LockToken();
+ }
+
+
+ // lock token for the destination file, if the destination is locked
+ const HBufC8* destLockToken = NULL;
+ CRsfwDavFileInfo* destDavFileInfo = DavFileInfoL(aDstPathName);
+ if (destDavFileInfo)
+ {
+ destLockToken = destDavFileInfo->LockToken();
+ }
+
+
+ CRsfwDavAccessContextMove* davAccessContextMove =
+ CRsfwDavAccessContextMove::NewL(this,
+ aResponseHandler,
+ aSrcPathName,
+ aDstPathName,
+ aOverwrite,
+ lockToken,
+ destLockToken);
+ TUint id = AddAccessContext(davAccessContextMove);
+ davAccessContextMove->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::GetDirectoryAttributesL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::GetDirectoryAttributesL(
+ const TDesC& aPathName,
+ CRsfwDirEntAttr*& aAttr,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: GetDirectoryAttributes of '%S'",
+ &aPathName));
+
+ // check that arguments are sensible
+ // aPathName might here be null (mounted root directory)
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if (aPathName.Length() > KMaxPath)
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextPropFindDir* davAccessContextPropFindDir =
+ CRsfwDavAccessContextPropFindDir::NewL(this,
+ aResponseHandler,
+ aPathName,
+ 0,
+ &aAttr,
+ NULL);
+ TUint id = AddAccessContext(davAccessContextPropFindDir);
+ davAccessContextPropFindDir->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::GetFileAttributesL
+// ----------------------------------------------------------------------------
+//
+TUint
+CRsfwDavAccess::GetFileAttributesL(const TDesC& aPathName,
+ CRsfwDirEntAttr*& aAttr,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ DEBUGSTRING16(("DAV: GetFileAttributes of '%S'",
+ &aPathName));
+
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextPropFindFile* davAccessContextPropFindFile =
+ CRsfwDavAccessContextPropFindFile::NewL(this,
+ aResponseHandler,
+ aPathName,
+ &aAttr);
+ TUint id = AddAccessContext(davAccessContextPropFindFile);
+ davAccessContextPropFindFile->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::SetAttributesL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::SetAttributesL(
+ const TDesC& /* aPathName */,
+ CRsfwDirEntAttr& /* aAttr */,
+ MRsfwRemoteAccessResponseHandler* /* aResponseHandler */)
+ {
+ DEBUGSTRING(("DAV: SetAttributes"));
+ User::Leave(KErrNotSupported);
+ // Not reached
+ return 0;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::ObtainLockL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::ObtainLockL(const TDesC& aPathName,
+ TUint aLockFlags,
+ TUint& aTimeout,
+ TDesC8*& aLockToken,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ // check that arguments are sensible
+ if ((!aResponseHandler) ||
+ (aTimeout == 0))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // CRsfwDavAccess is the place to know about webdab locks
+ // We only try to obtain a lock if the file was opened for writing
+ if ((!(aLockFlags & EFileWrite)) ||
+ (iWebDavSession->WebDavSupportClass() < KDavVersionTwo))
+ {
+ // WebDAV doesn't have read locks
+ aResponseHandler->HandleRemoteAccessResponse(0, KErrNotSupported);
+ return 0;
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ CRsfwDavAccessContextLock* davAccessContextLock =
+ CRsfwDavAccessContextLock::NewL(this,
+ aResponseHandler,
+ aPathName,
+ aLockFlags,
+ aTimeout,
+ &aLockToken);
+ TUint id = AddAccessContext(davAccessContextLock);
+ davAccessContextLock->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::ReleaseLockL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::ReleaseLockL(const TDesC& aPathName,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ /*
+ Precondition:
+ - File has been at least locked so there must be fileInfo and
+ locktoken for it
+ */
+ // check that arguments are sensible
+ if (!aResponseHandler)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+ // Must send the Lock Token
+ CRsfwDavFileInfo* davFileInfo = DavFileInfoL(aPathName);
+ if (!davFileInfo)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ const HBufC8* lockToken = davFileInfo->LockToken();
+ if (!lockToken)
+ {
+ User::Leave(KErrNotFound);
+ }
+ // Prevent further access to lock token
+ davFileInfo->SetFlag(TRsfwDavFileInfoFlags::EUnlockPending);
+
+ CRsfwDavAccessContextUnlock* davAccessContextUnlock =
+ CRsfwDavAccessContextUnlock::NewL(this,
+ aResponseHandler,
+ aPathName,
+ lockToken);
+ TUint id = AddAccessContext(davAccessContextUnlock);
+ davAccessContextUnlock->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::RefreshLockL
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::RefreshLockL(const TDesC& aPathName,
+ TUint& aTimeout,
+ MRsfwRemoteAccessResponseHandler* aResponseHandler)
+
+ {
+ /*
+ Precondition:
+ - File has been at least locked
+ so there must be fileInfo and locktoken for it
+ */
+ // check that arguments are sensible
+ if ((!aResponseHandler) ||
+ (aTimeout == 0))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ if ((aPathName.Length() == 0) ||
+ (aPathName.Length() > KMaxPath))
+ {
+ User::Leave(KErrBadName);
+ }
+
+
+ // Must send the Lock Token
+ CRsfwDavFileInfo* davFileInfo = DavFileInfoL(aPathName);
+ if (!davFileInfo)
+ {
+ User::Leave(KErrNotFound);
+ }
+ const HBufC8* lockToken = davFileInfo->LockToken();
+ if (!lockToken)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ CRsfwDavAccessContextRefreshLock* davAccessContextRefreshLock =
+ CRsfwDavAccessContextRefreshLock::NewL(this,
+ aResponseHandler,
+ aPathName,
+ lockToken,
+ aTimeout);
+ TUint id = AddAccessContext(davAccessContextRefreshLock);
+ davAccessContextRefreshLock->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::CancelL by ID
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::Cancel(TUint aId)
+ {
+ TInt i;
+ if (aId)
+ {
+ i = LookupAccessContextByContextId(aId);
+ if (i != KErrNotFound)
+ {
+ CRsfwDavAccessContext* context = iDavAccessContexts[i];
+ // sometimes it may happen that transaction has not been created for
+ // some context (e.g. if a leave has occured)
+ if (context->WebDavTransaction())
+ {
+ context->WebDavTransaction()->Cancel();
+ }
+ else
+ {
+ iDavAccessContexts.Remove(i);
+ delete context;
+ }
+ }
+ }
+ else
+ {
+ // Cancel all pending transactions.
+ // Note that cancelling one transaction may result in creating the other
+ // e.g. if you cancel PUT, then RELEASE LOCK is generated.
+ // Anyway the purpose here is to 'kill' all of them, even those generated later
+ DEBUGSTRING(("Cancelling all pending transactions..."));
+ while (iDavAccessContexts.Count() > 0)
+ {
+ CRsfwDavAccessContext* context = iDavAccessContexts[0];
+ TUint id = context->Id();
+ Cancel(id);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::CancelL by path
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::Cancel(TDesC& aTargetPath)
+ {
+ DEBUGSTRING16(("CRsfwDavAccess::Cancel '%S'", &aTargetPath));
+ TInt i;
+ i = LookupAccessContextByPath(aTargetPath);
+ if (i != KErrNotFound)
+ {
+ DEBUGSTRING16(("found transaction....cancelling webdavop %d",
+ iDavAccessContexts[i]->WebDavTransaction()->iWebDavOp));
+ iDavAccessContexts[i]->WebDavTransaction()->Cancel();
+ }
+ }
+
+
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::SetLockToken
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwDavAccess::SetLockToken(const TDesC& aPathName,
+ const TDesC8& aLockToken)
+ {
+ TRAPD(err, SetLockTokenL(aPathName, aLockToken));
+ return err;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::SetLockTokenL
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::SetLockTokenL(const TDesC& aPathName,
+ const TDesC8& aLockToken)
+ {
+ HBufC* path = HBufC::NewLC(iRootDirectory.Length() + KMaxPath + 1);
+ TPtr pathPtr = path->Des();
+ pathPtr.Copy(iRootDirectory);
+ pathPtr.Append(aPathName);
+
+ DEBUGSTRING16(("DAV: setting lock token: path = '%S'", &pathPtr));
+ DEBUGSTRING8((" token = '%S'", &aLockToken));
+
+ if (aLockToken.Length())
+ {
+ CRsfwDavFileInfo* fileInfo = DavFileInfoL(pathPtr);
+ if (fileInfo)
+ {
+ fileInfo->SetLockTokenL(aLockToken);
+ }
+ else
+ {
+ // new file
+ fileInfo = CRsfwDavFileInfo::NewL();
+ CleanupStack::PushL(fileInfo);
+ fileInfo->SetNameL(pathPtr);
+ fileInfo->SetLockTokenL(aLockToken);
+ CleanupStack::Pop(fileInfo);
+ // Ownership transferred to file info array
+ AddDavFileInfo(fileInfo);
+ }
+ }
+ else
+ {
+ // Remove lock token
+ RemoveDavFileInfoL(pathPtr);
+ }
+
+ CleanupStack::PopAndDestroy(path);
+ }
+
+// ----------------------------------------------------------------------------
+// From MRsfwDavResponseObserver
+// ----------------------------------------------------------------------------
+
+void CRsfwDavAccess::RequestCompleteL(TUint aWebDavTransactionId)
+ {
+ TInt i = LookupAccessContextByTransactionId(aWebDavTransactionId);
+ if (i != KErrNotFound)
+ {
+ CRsfwDavAccessContext* context = iDavAccessContexts[i];
+ DEBUGSTRING(("DAV: Request %d complete", aWebDavTransactionId));
+ context->TransactionCompleteL();
+ if (context->Done())
+ {
+ MRsfwRemoteAccessResponseHandler* responseHandler =
+ context->ResponseHandler();
+ TUint id = context->Id();
+ TInt status = context->Status();
+ iDavAccessContexts.Remove(i);
+ delete context;
+ responseHandler->HandleRemoteAccessResponse(id, status);
+ }
+ }
+ else
+ {
+ DEBUGSTRING(("DAV: Stray request (id=%d) complete",
+ aWebDavTransactionId));
+ }
+ }
+
+void CRsfwDavAccess::RequestError(TUint aWebDavTransactionId, TInt aStatus)
+ {
+ TInt i = LookupAccessContextByTransactionId(aWebDavTransactionId);
+ if (i != KErrNotFound)
+ {
+ CRsfwDavAccessContext* context = iDavAccessContexts[i];
+ DEBUGSTRING(("DAV: Request %d error %d",
+ aWebDavTransactionId,
+ aStatus));
+ context->TransactionError(aStatus);
+ if (context->Done())
+ {
+ MRsfwRemoteAccessResponseHandler* responseHandler =
+ context->ResponseHandler();
+ TUint id = context->Id();
+ TInt status = context->Status();
+ iDavAccessContexts.Remove(i);
+ delete context;
+ responseHandler->HandleRemoteAccessResponse(id, status);
+ }
+ }
+ else
+ {
+ DEBUGSTRING(("DAV: Stray request (id=%d) error",
+ aWebDavTransactionId));
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::AddAccessContext
+// Add a context entry in the table of currently active contexts.
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::AddAccessContext(CRsfwDavAccessContext* aDavAccessContext)
+ {
+ TUint id = GetNextAccessContextId();
+ DEBUGSTRING(("DAV: Added transaction %d", id));
+ aDavAccessContext->SetId(id);
+ iDavAccessContexts.Append(aDavAccessContext);
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::LookupAccessContextByTransactionId
+// Find an access context for the given WebDAV transaction id.
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwDavAccess::LookupAccessContextByTransactionId(TUint aWebDavTransactionId)
+ {
+ TInt i;
+ for (i = 0; i < iDavAccessContexts.Count(); i++)
+ {
+ if (iDavAccessContexts[i]->WebDavTransactionId() ==
+ aWebDavTransactionId)
+ {
+ return i;
+ }
+ }
+ DEBUGSTRING(("Access context for id %d is missing !!!",
+ aWebDavTransactionId));
+ return KErrNotFound;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::LookupAccessContext
+// Find an access context having the given id.
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwDavAccess::LookupAccessContextByContextId(TUint aId)
+ {
+ TInt i;
+ for (i = 0; i < iDavAccessContexts.Count(); i++)
+ {
+ if (iDavAccessContexts[i]->Id() == aId)
+ {
+ return i;
+ }
+ }
+ DEBUGSTRING(("Access context for id %d is missing !!!", aId));
+ return KErrNotFound;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::LookupAccessContextByPath
+// Find an access context based on the path of the targer file/directory.
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwDavAccess::LookupAccessContextByPath(TDesC& aTargetPath)
+ {
+ TInt i;
+ for (i = 0; i < iDavAccessContexts.Count(); i++)
+ {
+ if (iDavAccessContexts[i]->TargetPath() == aTargetPath)
+ {
+ return i;
+ }
+ }
+ return KErrNotFound;
+ }
+
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::DavFileInfoIndexL
+// Find the index to file info array for the given file name.
+// ----------------------------------------------------------------------------
+//
+TInt CRsfwDavAccess::DavFileInfoIndexL(const TDesC& aName)
+ {
+ HBufC* path = HBufC::NewLC(iRootDirectory.Length() + KMaxPath + 1);
+ TPtr pathPtr = path->Des();
+ pathPtr.Copy(iRootDirectory);
+ pathPtr.Append(aName);
+
+ DEBUGSTRING16(("Finding file info for '%S'", &pathPtr));
+ TInt index;
+ for (index = 0; index < iDavFileInfos.Count(); index++)
+ {
+ const HBufC* name = iDavFileInfos[index]->Name();
+ if (name)
+ {
+ if (pathPtr.Compare(*name) == 0)
+ {
+ DEBUGSTRING(("info found"));
+ CleanupStack::PopAndDestroy(path);
+ return index;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(path);
+ return KErrNotFound;
+ }
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::OptionsL
+// Perform an Options query
+// ----------------------------------------------------------------------------
+//
+TUint CRsfwDavAccess::OptionsL(MRsfwRemoteAccessResponseHandler* aResponseHandler)
+ {
+ CRsfwDavAccessContextOptions* davAccessContextOptions =
+ CRsfwDavAccessContextOptions::NewL(this, aResponseHandler);
+ TUint id = AddAccessContext(davAccessContextOptions);
+ davAccessContextOptions->StartL();
+ return id;
+ }
+
+// ----------------------------------------------------------------------------
+// From MRsfwConnectionObserver
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// CRsfwDavAccess::HandleConnectionEventL
+// Perform an Options query
+// ----------------------------------------------------------------------------
+//
+void CRsfwDavAccess::HandleConnectionEventL(TInt aConnectionEvent,
+ TAny* /*aArg*/)
+
+ {
+ switch (aConnectionEvent)
+ {
+ case ERsfwConnectionObserverEventConnectionDisconnected:
+ if (iRsfwRemoteAccessObserver)
+ {
+ iRsfwRemoteAccessObserver->
+ HandleRemoteAccessEventL(
+ ERsfwRemoteAccessObserverEventConnection,
+ ERsfwRemoteAccessObserverEventConnectionDisconnected,
+ NULL);
+ }
+ break;
+
+ case ERsfwConnectionObserverEventConnectionWeaklyConnected:
+ // If we were reacting to link up events, we would do OptionsL(this);
+ break;
+
+ case ERsfwConnectionObserverEventConnectionStronglyConnected:
+ // If we were reacting to link up events, we would do OptionsL(this);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+// End of File