ucb/source/ucp/webdav-curl/CurlSession.cxx   |  248 +++++++++++++++------------
 ucb/source/ucp/webdav-curl/CurlSession.hxx   |    6 
 ucb/source/ucp/webdav-curl/CurlUri.cxx       |   41 ++++
 ucb/source/ucp/webdav-curl/CurlUri.hxx       |    5 
 ucb/source/ucp/webdav-curl/SerfLockStore.cxx |   22 +-
 ucb/source/ucp/webdav-curl/SerfLockStore.hxx |    6 
 6 files changed, 207 insertions(+), 121 deletions(-)

New commits:
commit cd3daf7f6e7842e96f60a85cb791b18bfcc0d7b3
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Oct 22 17:09:30 2021 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 1 18:56:07 2021 +0100

    ucb: webdav-curl: convert URI reference to URI as early as possible
    
    Ensure that LockStore uses the full URL as key, not just the path.
    
    Change-Id: I84caf0d22e8c0ba176c19d004ee8ffcd2fdd05c8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124077
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx 
b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index b0c1c4c7e2ac..7c5bd5fe5973 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -588,16 +588,17 @@ auto CurlSession::abort() -> void
 /// this is just a bunch of static member functions called from CurlSession
 struct CurlProcessor
 {
+    static auto URIReferenceToURI(CurlSession& rSession, OUString const& 
rURIReference) -> CurlUri;
+
     static auto ProcessRequestImpl(
-        CurlSession& rSession, ::std::u16string_view rURIReference,
-        DAVRequestEnvironment const* pEnv,
+        CurlSession& rSession, CurlUri const& rURI, DAVRequestEnvironment 
const* pEnv,
         ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
         uno::Reference<io::XOutputStream> const* pxOutStream,
         uno::Reference<io::XInputStream> const* pxInStream,
         ::std::pair<::std::vector<OUString> const&, DAVResource&> const* 
pRequestedHeaders) -> void;
 
     static auto ProcessRequest(
-        Guard& rGuard, CurlSession& rSession, OUString const& rURIReference,
+        Guard& rGuard, CurlSession& rSession, CurlUri const& rURI,
         DAVRequestEnvironment const* pEnv,
         ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
         uno::Reference<io::XOutputStream> const* pxOutStream,
@@ -605,7 +606,7 @@ struct CurlProcessor
         ::std::pair<::std::vector<OUString> const&, DAVResource&> const* 
pRequestedHeaders) -> void;
 
     static auto
-    PropFind(CurlSession& rSession, OUString const& rURIReference, Depth depth,
+    PropFind(CurlSession& rSession, CurlUri const& rURI, Depth depth,
              ::std::tuple<::std::vector<OUString> const&, 
::std::vector<DAVResource>* const,
                           ::std::vector<ucb::Lock>* const> const* 
o_pRequestedProperties,
              ::std::vector<DAVResourceInfo>* const o_pResourceInfos,
@@ -616,19 +617,35 @@ struct CurlProcessor
                            bool isOverwrite, char const* pMethod) -> void;
 
     static auto
-    Lock(CurlSession& rSession, OUString const& rURIReference, 
DAVRequestEnvironment const* pEnv,
+    Lock(CurlSession& rSession, CurlUri const& rURI, DAVRequestEnvironment 
const* pEnv,
          ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
          uno::Reference<io::XInputStream> const* pxInStream)
         -> ::std::vector<::std::pair<ucb::Lock, sal_Int32>>;
 
-    static auto Unlock(CurlSession& rSession, OUString const& rURIReference,
+    static auto Unlock(CurlSession& rSession, CurlUri const& rURI,
                        DAVRequestEnvironment const* pEnv) -> void;
 };
 
+auto CurlProcessor::URIReferenceToURI(CurlSession& rSession, OUString const& 
rURIReference)
+    -> CurlUri
+{
+    // No need to acquire rSession.m_Mutex because accessed members are const.
+    if (rSession.UsesProxy())
+    // very odd, but see DAVResourceAccess::getRequestURI() :-/
+    {
+        assert(rURIReference.startsWith("http://";) || 
rURIReference.startsWith("https://";));
+        return CurlUri(rURIReference);
+    }
+    else
+    {
+        assert(rURIReference.startsWith("/") && 
!rURIReference.startsWith("//"));
+        return rSession.m_URI.CloneWithRelativeRefPathAbsolute(rURIReference);
+    }
+}
+
 /// main function to initiate libcurl requests
 auto CurlProcessor::ProcessRequestImpl(
-    CurlSession& rSession, ::std::u16string_view const rURIReference,
-    DAVRequestEnvironment const* const pEnv,
+    CurlSession& rSession, CurlUri const& rURI, DAVRequestEnvironment const* 
const pEnv,
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
     uno::Reference<io::XOutputStream> const* const pxOutStream,
     uno::Reference<io::XInputStream> const* const pxInStream,
@@ -681,20 +698,7 @@ auto CurlProcessor::ProcessRequestImpl(
         (void)rc;
     }
 
-    ::std::unique_ptr<CURLU, deleter_from_fn<curl_url_cleanup>> const pUrl(
-        rSession.m_URI.CloneCURLU());
-    OString const utf8URIRef(OUStringToOString(rURIReference, 
RTL_TEXTENCODING_UTF8));
-    auto uc = curl_url_set(pUrl.get(),
-                           // very odd, but see 
DAVResourceAccess::getRequestURI() :-/
-                           rSession.UsesProxy() ? CURLUPART_URL : 
CURLUPART_PATH,
-                           utf8URIRef.getStr(), 0);
-    if (uc != CURLUE_OK)
-    {
-        SAL_WARN("ucb.ucp.webdav.curl", "curl_url_set failed: " << uc);
-        throw DAVException(DAVException::DAV_INVALID_ARG);
-    }
-
-    auto rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_CURLU, 
pUrl.get());
+    auto rc = curl_easy_setopt(rSession.m_pCurl.get(), CURLOPT_CURLU, 
rURI.GetCURLU());
     assert(rc == CURLE_OK); // can't fail since 7.63.0
 
     // authentication data may be in the URI, or requested via 
XInteractionHandler
@@ -730,16 +734,15 @@ auto CurlProcessor::ProcessRequestImpl(
     // TODO: why is there this m_aRequestURI and also rURIReference argument?
     // ... only caller is DAVResourceAccess - always identical except MOVE/COPY
     // which doesn't work if it's just a URI reference so let's just use
-    // rURIReference via pUrl instead
+    // rURIReference via rURI instead
 #if 0
         CurlUri const uri(pEnv->m_aRequestURI);
 #endif
-        CurlUri const uri(*pUrl);
         // note: due to parsing bug pwd didn't work in previous webdav ucps
         if (pEnv && !rSession.m_isAuthenticated
-            && (!uri.GetUser().isEmpty() || !uri.GetPassword().isEmpty()))
+            && (!rURI.GetUser().isEmpty() || !rURI.GetPassword().isEmpty()))
         {
-            oAuth.emplace(uri.GetUser(), uri.GetPassword(), CURLAUTH_ANY);
+            oAuth.emplace(rURI.GetUser(), rURI.GetPassword(), CURLAUTH_ANY);
         }
         if (pRequestedHeaders)
         {
@@ -748,7 +751,7 @@ auto CurlProcessor::ProcessRequestImpl(
             // But it looks like all consumers of this .uri are interested
             // only in the path, so it shouldn't make a difference to give
             // the entire URI when the caller extracts the path anyway.
-            pRequestedHeaders->second.uri = uri.GetURI();
+            pRequestedHeaders->second.uri = rURI.GetURI();
             pRequestedHeaders->second.properties.clear();
         }
     }
@@ -1007,7 +1010,7 @@ auto CurlProcessor::ProcessRequestImpl(
     }
 }
 
-static auto TryRemoveExpiredLockToken(CurlSession& rSession, OUString const& 
rURIReference,
+static auto TryRemoveExpiredLockToken(CurlSession& rSession, CurlUri const& 
rURI,
                                       DAVRequestEnvironment const* const pEnv) 
-> bool
 {
     if (!pEnv)
@@ -1015,7 +1018,7 @@ static auto TryRemoveExpiredLockToken(CurlSession& 
rSession, OUString const& rUR
         // caller was a NonInteractive_*LOCK function anyway, its caller is 
LockStore
         return false;
     }
-    OUString const* const 
pToken(g_Init.LockStore.getLockTokenForURI(rURIReference, nullptr));
+    OUString const* const 
pToken(g_Init.LockStore.getLockTokenForURI(rURI.GetURI(), nullptr));
     if (!pToken)
     {
         return false;
@@ -1028,7 +1031,7 @@ static auto TryRemoveExpiredLockToken(CurlSession& 
rSession, OUString const& rUR
         ::std::tuple<::std::vector<OUString> const&, 
::std::vector<DAVResource>* const,
                      ::std::vector<ucb::Lock>* const> const 
args(propertyNames, nullptr, &locks);
 
-        CurlProcessor::PropFind(rSession, rURIReference, DAVZERO, &args, 
nullptr, *pEnv);
+        CurlProcessor::PropFind(rSession, rURI, DAVZERO, &args, nullptr, 
*pEnv);
 
         // https://datatracker.ietf.org/doc/html/rfc4918#section-15.8
         // The response MAY not contain tokens, but hopefully it
@@ -1043,8 +1046,8 @@ static auto TryRemoveExpiredLockToken(CurlSession& 
rSession, OUString const& rUR
         }
 
         SAL_INFO("ucb.ucp.webdav.curl",
-                 "lock token expired, removing: " << rURIReference << " " << 
*pToken);
-        g_Init.LockStore.removeLock(rURIReference);
+                 "lock token expired, removing: " << rURI.GetURI() << " " << 
*pToken);
+        g_Init.LockStore.removeLock(rURI.GetURI());
         return true;
     }
     catch (DAVException const&)
@@ -1054,7 +1057,7 @@ static auto TryRemoveExpiredLockToken(CurlSession& 
rSession, OUString const& rUR
 }
 
 auto CurlProcessor::ProcessRequest(
-    Guard& rGuard, CurlSession& rSession, OUString const& rURIReference,
+    Guard& rGuard, CurlSession& rSession, CurlUri const& rURI,
     DAVRequestEnvironment const* const pEnv,
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
     uno::Reference<io::XOutputStream> const* const pxOutStream,
@@ -1064,8 +1067,8 @@ auto CurlProcessor::ProcessRequest(
 {
     try
     {
-        ProcessRequestImpl(rSession, rURIReference, pEnv, 
::std::move(pRequestHeaderList),
-                           pxOutStream, pxInStream, pRequestedHeaders);
+        ProcessRequestImpl(rSession, rURI, pEnv, 
::std::move(pRequestHeaderList), pxOutStream,
+                           pxInStream, pRequestedHeaders);
     }
     catch (DAVException const& rException)
     {
@@ -1077,7 +1080,7 @@ auto CurlProcessor::ProcessRequest(
                 case SC_LOCKED:
                 {
                     rGuard.unlock(); // release m_Mutex before accessing 
LockStore
-                    if (g_Init.LockStore.getLockTokenForURI(rURIReference, 
nullptr))
+                    if (g_Init.LockStore.getLockTokenForURI(rURI.GetURI(), 
nullptr))
                     {
                         throw DAVException(DAVException::DAV_LOCKED_SELF);
                     }
@@ -1095,7 +1098,7 @@ auto CurlProcessor::ProcessRequest(
                     // the expiration of a lock.
                     // Initiate a new request *outside* ProcessRequestImpl
                     // *after* rGuard.unlock() to avoid messing up m_pCurl 
state.
-                    if (TryRemoveExpiredLockToken(rSession, rURIReference, 
pEnv))
+                    if (TryRemoveExpiredLockToken(rSession, rURI, pEnv))
                     {
                         throw DAVException(DAVException::DAV_LOCK_EXPIRED);
                     }
@@ -1115,6 +1118,8 @@ auto CurlSession::OPTIONS(OUString const& rURIReference,
 
     rOptions.init();
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     ::std::vector<OUString> const headerNames{ "allow", "dav" };
     DAVResource result;
     ::std::pair<::std::vector<OUString> const&, DAVResource&> const 
headers(headerNames, result);
@@ -1140,8 +1145,7 @@ auto CurlSession::OPTIONS(OUString const& rURIReference,
                                ConnectionEndPointString(m_URI.GetHost(), 
m_URI.GetPort()));
         }
 
-        CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
nullptr, nullptr,
-                                      &headers);
+        CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, nullptr, 
nullptr, &headers);
     }
 
     for (auto const& it : result.properties)
@@ -1180,7 +1184,7 @@ auto CurlSession::OPTIONS(OUString const& rURIReference,
     }
     if (rOptions.isClass2() || rOptions.isClass3())
     {
-        if (g_Init.LockStore.getLockTokenForURI(rURIReference, nullptr))
+        if (g_Init.LockStore.getLockTokenForURI(uri.GetURI(), nullptr))
         {
             rOptions.setLocked();
         }
@@ -1188,7 +1192,7 @@ auto CurlSession::OPTIONS(OUString const& rURIReference,
 }
 
 auto CurlProcessor::PropFind(
-    CurlSession& rSession, OUString const& rURIReference, Depth const nDepth,
+    CurlSession& rSession, CurlUri const& rURI, Depth const nDepth,
     ::std::tuple<::std::vector<OUString> const&, ::std::vector<DAVResource>* 
const,
                  ::std::vector<ucb::Lock>* const> const* const 
o_pRequestedProperties,
     ::std::vector<DAVResourceInfo>* const o_pResourceInfos, 
DAVRequestEnvironment const& rEnv)
@@ -1294,8 +1298,8 @@ auto CurlProcessor::PropFind(
     assert(xResponseInStream.is());
     assert(xResponseOutStream.is());
 
-    CurlProcessor::ProcessRequest(g, rSession, rURIReference, &rEnv, 
::std::move(pList),
-                                  &xResponseOutStream, &xRequestInStream, 
nullptr);
+    CurlProcessor::ProcessRequest(g, rSession, rURI, &rEnv, 
::std::move(pList), &xResponseOutStream,
+                                  &xRequestInStream, nullptr);
 
     if (o_pResourceInfos)
     {
@@ -1322,10 +1326,13 @@ auto CurlSession::PROPFIND(OUString const& 
rURIReference, Depth const depth,
                            DAVRequestEnvironment const& rEnv) -> void
 {
     SAL_INFO("ucb.ucp.webdav.curl", "PROPFIND: " << rURIReference << " " << 
depth);
+
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     ::std::tuple<::std::vector<OUString> const&, ::std::vector<DAVResource>* 
const,
                  ::std::vector<ucb::Lock>* const> const args(rPropertyNames, 
&o_rResources,
                                                              nullptr);
-    return CurlProcessor::PropFind(*this, rURIReference, depth, &args, 
nullptr, rEnv);
+    return CurlProcessor::PropFind(*this, uri, depth, &args, nullptr, rEnv);
 }
 
 auto CurlSession::PROPFIND(OUString const& rURIReference, Depth const depth,
@@ -1333,7 +1340,10 @@ auto CurlSession::PROPFIND(OUString const& 
rURIReference, Depth const depth,
                            DAVRequestEnvironment const& rEnv) -> void
 {
     SAL_INFO("ucb.ucp.webdav.curl", "PROPFIND: " << rURIReference << " " << 
depth);
-    return CurlProcessor::PropFind(*this, rURIReference, depth, nullptr, 
&o_rResourceInfos, rEnv);
+
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
+    return CurlProcessor::PropFind(*this, uri, depth, nullptr, 
&o_rResourceInfos, rEnv);
 }
 
 auto CurlSession::PROPPATCH(OUString const& rURIReference,
@@ -1342,6 +1352,8 @@ auto CurlSession::PROPPATCH(OUString const& rURIReference,
 {
     SAL_INFO("ucb.ucp.webdav.curl", "PROPPATCH: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     //FIXME why does toXML encode stuff which parser ignores
     //isUCBDeadProperty case not handled
 
@@ -1416,7 +1428,7 @@ auto CurlSession::PROPPATCH(OUString const& rURIReference,
     xWriter->endDocument();
     xRequestOutStream->closeOutput();
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, 
::std::move(pList), nullptr,
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, ::std::move(pList), 
nullptr,
                                   &xRequestInStream, nullptr);
 }
 
@@ -1425,6 +1437,8 @@ auto CurlSession::HEAD(OUString const& rURIReference, 
::std::vector<OUString> co
 {
     SAL_INFO("ucb.ucp.webdav.curl", "HEAD: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_NOBODY, 0L);
         assert(rc == CURLE_OK);
@@ -1437,8 +1451,7 @@ auto CurlSession::HEAD(OUString const& rURIReference, 
::std::vector<OUString> co
     ::std::pair<::std::vector<OUString> const&, DAVResource&> const 
headers(rHeaderNames,
                                                                             
io_rResource);
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
nullptr, nullptr,
-                                  &headers);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, nullptr, 
nullptr, &headers);
 }
 
 auto CurlSession::GET(OUString const& rURIReference, DAVRequestEnvironment 
const& rEnv)
@@ -1446,6 +1459,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
DAVRequestEnvironment const
 {
     SAL_INFO("ucb.ucp.webdav.curl", "GET: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     // could use either com.sun.star.io.Pipe or 
com.sun.star.io.SequenceInputStream?
     // Pipe can just write into its XOuputStream, which is simpler.
     // Both resize exponentially, so performance should be fine.
@@ -1465,8 +1480,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
DAVRequestEnvironment const
     assert(rc == CURLE_OK);
     (void)rc;
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
&xResponseOutStream,
-                                  nullptr, nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, 
&xResponseOutStream, nullptr,
+                                  nullptr);
 
     uno::Reference<io::XInputStream> const xResponseInStream(
         io::SequenceInputStream::createStreamFromSequence(m_xContext,
@@ -1481,6 +1496,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
uno::Reference<io::XOutputS
 {
     SAL_INFO("ucb.ucp.webdav.curl", "GET: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HTTPGET, 0L);
         assert(rc == CURLE_OK);
@@ -1490,8 +1507,7 @@ auto CurlSession::GET(OUString const& rURIReference, 
uno::Reference<io::XOutputS
     assert(rc == CURLE_OK);
     (void)rc;
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
&rxOutStream, nullptr,
-                                  nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, &rxOutStream, 
nullptr, nullptr);
 }
 
 auto CurlSession::GET(OUString const& rURIReference, ::std::vector<OUString> 
const& rHeaderNames,
@@ -1500,6 +1516,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
::std::vector<OUString> con
 {
     SAL_INFO("ucb.ucp.webdav.curl", "GET: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HTTPGET, 0L);
         assert(rc == CURLE_OK);
@@ -1517,8 +1535,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
::std::vector<OUString> con
     ::std::pair<::std::vector<OUString> const&, DAVResource&> const 
headers(rHeaderNames,
                                                                             
io_rResource);
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
&xResponseOutStream,
-                                  nullptr, &headers);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, 
&xResponseOutStream, nullptr,
+                                  &headers);
 
     uno::Reference<io::XInputStream> const xResponseInStream(
         io::SequenceInputStream::createStreamFromSequence(m_xContext,
@@ -1534,6 +1552,8 @@ auto CurlSession::GET(OUString const& rURIReference, 
uno::Reference<io::XOutputS
 {
     SAL_INFO("ucb.ucp.webdav.curl", "GET: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HTTPGET, 0L);
         assert(rc == CURLE_OK);
@@ -1546,8 +1566,7 @@ auto CurlSession::GET(OUString const& rURIReference, 
uno::Reference<io::XOutputS
     ::std::pair<::std::vector<OUString> const&, DAVResource&> const 
headers(rHeaderNames,
                                                                             
io_rResource);
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
&rxOutStream, nullptr,
-                                  &headers);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, &rxOutStream, 
nullptr, &headers);
 }
 
 auto CurlSession::PUT(OUString const& rURIReference,
@@ -1556,6 +1575,8 @@ auto CurlSession::PUT(OUString const& rURIReference,
 {
     SAL_INFO("ucb.ucp.webdav.curl", "PUT: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     // TODO: either set CURLOPT_INFILESIZE_LARGE or chunked?
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> pList(
         curl_slist_append(nullptr, "Transfer-Encoding: chunked"));
@@ -1563,8 +1584,7 @@ auto CurlSession::PUT(OUString const& rURIReference,
     {
         throw uno::RuntimeException("curl_slist_append failed");
     }
-    // TODO: why is a *global* LockStore keyed by *path*?
-    OUString const token(g_Init.LockStore.getLockToken(rURIReference));
+    OUString const token(g_Init.LockStore.getLockToken(uri.GetURI()));
     if (!token.isEmpty())
     {
         OString const utf8If("If: <" + OUStringToOString(rURIReference, 
RTL_TEXTENCODING_ASCII_US)
@@ -1579,8 +1599,8 @@ auto CurlSession::PUT(OUString const& rURIReference,
     // lock m_Mutex after accessing global LockStore to avoid deadlock
     Guard g(m_Mutex);
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, 
::std::move(pList), nullptr,
-                                  &rxInStream, nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, ::std::move(pList), 
nullptr, &rxInStream,
+                                  nullptr);
 }
 
 auto CurlSession::POST(OUString const& rURIReference, OUString const& 
rContentType,
@@ -1589,6 +1609,8 @@ auto CurlSession::POST(OUString const& rURIReference, 
OUString const& rContentTy
 {
     SAL_INFO("ucb.ucp.webdav.curl", "POST: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     // TODO: either set CURLOPT_POSTFIELDSIZE_LARGE or chunked?
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> pList(
         curl_slist_append(nullptr, "Transfer-Encoding: chunked"));
@@ -1625,8 +1647,8 @@ auto CurlSession::POST(OUString const& rURIReference, 
OUString const& rContentTy
     uno::Reference<io::XOutputStream> const xResponseOutStream(xSeqOutStream);
     assert(xResponseOutStream.is());
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, 
::std::move(pList),
-                                  &xResponseOutStream, &rxInStream, nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, ::std::move(pList), 
&xResponseOutStream,
+                                  &rxInStream, nullptr);
 
     uno::Reference<io::XInputStream> const xResponseInStream(
         io::SequenceInputStream::createStreamFromSequence(m_xContext,
@@ -1643,6 +1665,8 @@ auto CurlSession::POST(OUString const& rURIReference, 
OUString const& rContentTy
 {
     SAL_INFO("ucb.ucp.webdav.curl", "POST: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     // TODO: either set CURLOPT_POSTFIELDSIZE_LARGE or chunked?
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> pList(
         curl_slist_append(nullptr, "Transfer-Encoding: chunked"));
@@ -1674,7 +1698,7 @@ auto CurlSession::POST(OUString const& rURIReference, 
OUString const& rContentTy
     assert(rc == CURLE_OK);
     (void)rc;
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, 
::std::move(pList), &rxOutStream,
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, ::std::move(pList), 
&rxOutStream,
                                   &rxInStream, nullptr);
 }
 
@@ -1682,6 +1706,8 @@ auto CurlSession::MKCOL(OUString const& rURIReference, 
DAVRequestEnvironment con
 {
     SAL_INFO("ucb.ucp.webdav.curl", "MKCOL: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_CUSTOMREQUEST, 
nullptr);
         assert(rc == CURLE_OK);
@@ -1695,8 +1721,7 @@ auto CurlSession::MKCOL(OUString const& rURIReference, 
DAVRequestEnvironment con
                            ConnectionEndPointString(m_URI.GetHost(), 
m_URI.GetPort()));
     }
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
nullptr, nullptr,
-                                  nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, nullptr, 
nullptr, nullptr);
 }
 
 auto CurlProcessor::MoveOrCopy(CurlSession& rSession, OUString const& 
rSourceURIReference,
@@ -1704,6 +1729,8 @@ auto CurlProcessor::MoveOrCopy(CurlSession& rSession, 
OUString const& rSourceURI
                                DAVRequestEnvironment const& rEnv, bool const 
isOverwrite,
                                char const* const pMethod) -> void
 {
+    CurlUri const uriSource(CurlProcessor::URIReferenceToURI(rSession, 
rSourceURIReference));
+
     OString const utf8Destination("Destination: "
                                   + OUStringToOString(rDestinationURI, 
RTL_TEXTENCODING_ASCII_US));
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> pList(
@@ -1729,8 +1756,8 @@ auto CurlProcessor::MoveOrCopy(CurlSession& rSession, 
OUString const& rSourceURI
     assert(rc == CURLE_OK);
     (void)rc;
 
-    CurlProcessor::ProcessRequest(g, rSession, rSourceURIReference, &rEnv, 
::std::move(pList),
-                                  nullptr, nullptr, nullptr);
+    CurlProcessor::ProcessRequest(g, rSession, uriSource, &rEnv, 
::std::move(pList), nullptr,
+                                  nullptr, nullptr);
 }
 
 auto CurlSession::COPY(OUString const& rSourceURIReference, OUString const& 
rDestinationURI,
@@ -1755,6 +1782,8 @@ auto CurlSession::DESTROY(OUString const& rURIReference, 
DAVRequestEnvironment c
 {
     SAL_INFO("ucb.ucp.webdav.curl", "DESTROY: " << rURIReference);
 
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
     Guard g(m_Mutex, [&]() {
         auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_CUSTOMREQUEST, 
nullptr);
         assert(rc == CURLE_OK);
@@ -1768,12 +1797,11 @@ auto CurlSession::DESTROY(OUString const& 
rURIReference, DAVRequestEnvironment c
                            ConnectionEndPointString(m_URI.GetHost(), 
m_URI.GetPort()));
     }
 
-    CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
nullptr, nullptr,
-                                  nullptr);
+    CurlProcessor::ProcessRequest(g, *this, uri, &rEnv, nullptr, nullptr, 
nullptr, nullptr);
 }
 
 auto CurlProcessor::Lock(
-    CurlSession& rSession, OUString const& rURIReference, 
DAVRequestEnvironment const* const pEnv,
+    CurlSession& rSession, CurlUri const& rURI, DAVRequestEnvironment const* 
const pEnv,
     ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pRequestHeaderList,
     uno::Reference<io::XInputStream> const* const pxRequestInStream)
     -> ::std::vector<::std::pair<ucb::Lock, sal_Int32>>
@@ -1801,12 +1829,12 @@ auto CurlProcessor::Lock(
     TimeValue startTime;
     osl_getSystemTime(&startTime);
 
-    CurlProcessor::ProcessRequest(g, rSession, rURIReference, pEnv, 
::std::move(pRequestHeaderList),
+    CurlProcessor::ProcessRequest(g, rSession, rURI, pEnv, 
::std::move(pRequestHeaderList),
                                   &xResponseOutStream, pxRequestInStream, 
nullptr);
 
     ::std::vector<ucb::Lock> const 
acquiredLocks(parseWebDAVLockResponse(xResponseInStream));
     SAL_WARN_IF(acquiredLocks.empty(), "ucb.ucp.webdav.curl",
-                "could not get LOCK for " << rURIReference);
+                "could not get LOCK for " << rURI.GetURI());
 
     TimeValue endTime;
     osl_getSystemTime(&endTime);
@@ -1826,7 +1854,7 @@ auto CurlProcessor::Lock(
         {
             SAL_WARN("ucb.ucp.webdav.curl",
                      "LOCK timeout already expired when receiving LOCK 
response for "
-                         << rURIReference);
+                         << rURI.GetURI());
             lockExpirationTimeSeconds = 0;
         }
         else
@@ -1844,8 +1872,9 @@ auto CurlSession::LOCK(OUString const& rURIReference, 
ucb::Lock /*const*/& rLock
 {
     SAL_INFO("ucb.ucp.webdav.curl", "LOCK: " << rURIReference);
 
-    // FIXME: why is a *global* LockStore keyed by *path*?
-    if (g_Init.LockStore.getLockTokenForURI(rURIReference, &rLock))
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
+
+    if (g_Init.LockStore.getLockTokenForURI(uri.GetURI(), &rLock))
     {
         // already have a lock that covers the requirement
         // TODO: maybe use DAV:lockdiscovery to ensure it's valid
@@ -1948,21 +1977,20 @@ auto CurlSession::LOCK(OUString const& rURIReference, 
ucb::Lock /*const*/& rLock
     }
 
     auto const acquiredLocks
-        = CurlProcessor::Lock(*this, rURIReference, &rEnv, ::std::move(pList), 
&xRequestInStream);
+        = CurlProcessor::Lock(*this, uri, &rEnv, ::std::move(pList), 
&xRequestInStream);
 
     for (auto const& rAcquiredLock : acquiredLocks)
     {
-        g_Init.LockStore.addLock(rURIReference, rAcquiredLock.first,
+        g_Init.LockStore.addLock(uri.GetURI(), rAcquiredLock.first,
                                  rAcquiredLock.first.LockTokens[0], this, 
rAcquiredLock.second);
         SAL_INFO("ucb.ucp.webdav.curl", "created LOCK for " << rURIReference);
     }
 }
 
-auto CurlProcessor::Unlock(CurlSession& rSession, OUString const& 
rURIReference,
+auto CurlProcessor::Unlock(CurlSession& rSession, CurlUri const& rURI,
                            DAVRequestEnvironment const* const pEnv) -> void
 {
-    // TODO: why is a *global* LockStore keyed by *path*?
-    OUString const token(g_Init.LockStore.getLockToken(rURIReference));
+    OUString const token(g_Init.LockStore.getLockToken(rURI.GetURI()));
     if (token.isEmpty())
     {
         SAL_WARN("ucb.ucp.webdav.curl", "attempt to unlock but not locked");
@@ -1992,8 +2020,8 @@ auto CurlProcessor::Unlock(CurlSession& rSession, 
OUString const& rURIReference,
             ConnectionEndPointString(rSession.m_URI.GetHost(), 
rSession.m_URI.GetPort()));
     }
 
-    CurlProcessor::ProcessRequest(g, rSession, rURIReference, pEnv, 
::std::move(pList), nullptr,
-                                  nullptr, nullptr);
+    CurlProcessor::ProcessRequest(g, rSession, rURI, pEnv, ::std::move(pList), 
nullptr, nullptr,
+                                  nullptr);
 }
 
 auto CurlSession::UNLOCK(OUString const& rURIReference, DAVRequestEnvironment 
const& rEnv) -> void
@@ -2002,68 +2030,72 @@ auto CurlSession::UNLOCK(OUString const& rURIReference, 
DAVRequestEnvironment co
 
     // note: no m_Mutex lock needed here, only in CurlProcessor::Unlock()
 
-    CurlProcessor::Unlock(*this, rURIReference, &rEnv);
+    CurlUri const uri(CurlProcessor::URIReferenceToURI(*this, rURIReference));
 
-    g_Init.LockStore.removeLock(rURIReference);
+    CurlProcessor::Unlock(*this, uri, &rEnv);
+
+    g_Init.LockStore.removeLock(uri.GetURI());
 }
 
-auto CurlSession::NonInteractive_LOCK(OUString const& rURIReference,
+auto CurlSession::NonInteractive_LOCK(OUString const& rURI,
                                       sal_Int32& 
o_rLastChanceToSendRefreshRequest) -> bool
 {
-    SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK: " << rURIReference);
+    SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK: " << rURI);
 
     // note: no m_Mutex lock needed here, only in CurlProcessor::Lock()
 
-    ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> pList(
-        curl_slist_append(nullptr, "Timeout: Second-180"));
-
-    // TODO: why is a *global* LockStore keyed by *path*?
-    OUString const token(g_Init.LockStore.getLockToken(rURIReference));
-    assert(!token.isEmpty()); // LockStore is the caller
-    OString const utf8If("If: (<" + OUStringToOString(token, 
RTL_TEXTENCODING_ASCII_US) + ">)");
-    pList.reset(curl_slist_append(pList.release(), utf8If.getStr()));
-    if (!pList)
-    {
-        throw uno::RuntimeException("curl_slist_append failed");
-    }
-
     try
     {
+        CurlUri const uri(rURI);
+        ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist_free_all>> 
pList(
+            curl_slist_append(nullptr, "Timeout: Second-180"));
+
+        OUString const token(g_Init.LockStore.getLockToken(rURI));
+        assert(!token.isEmpty()); // LockStore is the caller
+        OString const utf8If("If: (<" + OUStringToOString(token, 
RTL_TEXTENCODING_ASCII_US) + ">)");
+        pList.reset(curl_slist_append(pList.release(), utf8If.getStr()));
+        if (!pList)
+        {
+            throw uno::RuntimeException("curl_slist_append failed");
+        }
+
         auto const acquiredLocks
-            = CurlProcessor::Lock(*this, rURIReference, nullptr, 
::std::move(pList), nullptr);
+            = CurlProcessor::Lock(*this, uri, nullptr, ::std::move(pList), 
nullptr);
 
         SAL_WARN_IF(1 < acquiredLocks.size(), "ucb.ucp.webdav.curl",
-                    "multiple locks acquired on refresh for " << 
rURIReference);
+                    "multiple locks acquired on refresh for " << rURI);
         if (!acquiredLocks.empty())
         {
             o_rLastChanceToSendRefreshRequest = acquiredLocks.begin()->second;
         }
-        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK succeeded on " << 
rURIReference);
+        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK succeeded on " << 
rURI);
         return true;
     }
     catch (...)
     {
-        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK failed on " << 
rURIReference);
+        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_LOCK failed on " << 
rURI);
         return false;
     }
 }
 
-auto CurlSession::NonInteractive_UNLOCK(OUString const& rURIReference) -> void
+auto CurlSession::NonInteractive_UNLOCK(OUString const& rURI) -> void
 {
-    SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK: " << 
rURIReference);
+    SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK: " << rURI);
 
     // note: no m_Mutex lock needed here, only in CurlProcessor::Unlock()
 
     try
     {
-        CurlProcessor::Unlock(*this, rURIReference, nullptr);
+        CurlUri const uri(rURI);
+
+        CurlProcessor::Unlock(*this, uri, nullptr);
 
         // the only caller is the dtor of the LockStore, don't call remove!
-        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK succeeded on " 
<< rURIReference);
+        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK succeeded on " 
<< rURI);
     }
     catch (...)
     {
-        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK failed on " << 
rURIReference);
+        SAL_INFO("ucb.ucp.webdav.curl", "NonInteractive_UNLOCK failed on " << 
rURI);
     }
 }
 
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.hxx 
b/ucb/source/ucp/webdav-curl/CurlSession.hxx
index 58a828b29f14..88496308a947 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.hxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.hxx
@@ -127,9 +127,9 @@ public:
 
     virtual auto abort() -> void override;
 
-    auto NonInteractive_LOCK(OUString const& rURIReference,
-                             sal_Int32& o_rLastChanceToSendRefreshRequest) -> 
bool;
-    auto NonInteractive_UNLOCK(OUString const& rURIReference) -> void;
+    auto NonInteractive_LOCK(OUString const& rURI, sal_Int32& 
o_rLastChanceToSendRefreshRequest)
+        -> bool;
+    auto NonInteractive_UNLOCK(OUString const& rURI) -> void;
 };
 
 } // namespace http_dav_ucp
diff --git a/ucb/source/ucp/webdav-curl/CurlUri.cxx 
b/ucb/source/ucp/webdav-curl/CurlUri.cxx
index 5ab41db8d756..1c596dfcd299 100644
--- a/ucb/source/ucp/webdav-curl/CurlUri.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlUri.cxx
@@ -245,6 +245,47 @@ void CurlUri::AppendPath(::std::u16string_view const rPath)
     m_Path = *oPath;
 }
 
+CurlUri CurlUri::CloneWithRelativeRefPathAbsolute(OUString const& 
rRelativeRef) const
+{
+    ::std::unique_ptr<CURLU, deleter_from_fn<curl_url_cleanup>> 
pUrl(curl_url_dup(m_pUrl.get()));
+    sal_Int32 indexEnd(rRelativeRef.getLength());
+    auto const indexQuery(rRelativeRef.indexOf('?'));
+    auto const indexFragment(rRelativeRef.indexOf('#'));
+    if (indexFragment != -1)
+    {
+        OUString const fragment(rRelativeRef.copy(indexFragment));
+        indexEnd = indexFragment;
+        OString const utf8Fragment(OUStringToOString(fragment, 
RTL_TEXTENCODING_UTF8));
+        auto const uc = curl_url_set(pUrl.get(), CURLUPART_QUERY, 
utf8Fragment.getStr(), 0);
+        if (uc != CURLUE_OK)
+        {
+            SAL_WARN("ucb.ucp.webdav.curl", "curl_url_set failed: " << uc);
+            throw DAVException(DAVException::DAV_INVALID_ARG);
+        }
+    }
+    if (indexQuery != -1 && (indexFragment == -1 || indexQuery < 
indexFragment))
+    {
+        OUString const query(rRelativeRef.copy(indexQuery, indexEnd - 
indexQuery));
+        indexEnd = indexQuery;
+        OString const utf8Query(OUStringToOString(query, 
RTL_TEXTENCODING_UTF8));
+        auto const uc = curl_url_set(pUrl.get(), CURLUPART_QUERY, 
utf8Query.getStr(), 0);
+        if (uc != CURLUE_OK)
+        {
+            SAL_WARN("ucb.ucp.webdav.curl", "curl_url_set failed: " << uc);
+            throw DAVException(DAVException::DAV_INVALID_ARG);
+        }
+    }
+    OUString const path(rRelativeRef.copy(0, indexEnd));
+    OString const utf8Path(OUStringToOString(path, RTL_TEXTENCODING_UTF8));
+    auto const uc = curl_url_set(pUrl.get(), CURLUPART_PATH, 
utf8Path.getStr(), 0);
+    if (uc != CURLUE_OK)
+    {
+        SAL_WARN("ucb.ucp.webdav.curl", "curl_url_set failed: " << uc);
+        throw DAVException(DAVException::DAV_INVALID_ARG);
+    }
+    return CurlUri(*pUrl.release());
+}
+
 OUString EncodeSegment(OUString const& rSegment)
 {
     return rtl::Uri::encode(rSegment, rtl_UriCharClassPchar, 
rtl_UriEncodeIgnoreEscapes,
diff --git a/ucb/source/ucp/webdav-curl/CurlUri.hxx 
b/ucb/source/ucp/webdav-curl/CurlUri.hxx
index 13859666bc79..4071991c904e 100644
--- a/ucb/source/ucp/webdav-curl/CurlUri.hxx
+++ b/ucb/source/ucp/webdav-curl/CurlUri.hxx
@@ -59,7 +59,7 @@ public:
 
     bool operator==(CurlUri const& rOther) const;
 
-    CURLU* CloneCURLU() const { return curl_url_dup(m_pUrl.get()); }
+    CURLU const* GetCURLU() const { return m_pUrl.get(); }
     OUString const& GetURI() const { return m_URI; }
     OUString const& GetScheme() const { return m_Scheme; }
     OUString const& GetUser() const { return m_User; }
@@ -76,6 +76,9 @@ public:
     void SetScheme(::std::u16string_view rScheme);
     /// @throws DAVException
     void AppendPath(::std::u16string_view rPath);
+    /// @param matches: relative-ref = path-absolute [ "?" query ] [ "#" 
fragment ]
+    /// @throws DAVException
+    CurlUri CloneWithRelativeRefPathAbsolute(OUString const& rRelativeRef) 
const;
 };
 
 OUString EncodeSegment(OUString const& rSegment);
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
index 62526bd873fc..93cca865eb1b 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.cxx
@@ -139,11 +139,13 @@ void SerfLockStore::stopTicker(osl::ClearableMutexGuard & 
rGuard)
         pTickerThread->join(); // without m_aMutex locked (to prevent deadlock)
 }
 
-OUString SerfLockStore::getLockToken( const OUString& rLock )
+OUString SerfLockStore::getLockToken(const OUString& rURI)
 {
+    assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
+
     osl::MutexGuard aGuard( m_aMutex );
 
-    LockInfoMap::const_iterator it( m_aLockInfoMap.find( rLock ) );
+    LockInfoMap::const_iterator const it( m_aLockInfoMap.find(rURI) );
     if ( it != m_aLockInfoMap.end() )
         return (*it).second.m_sToken;
 
@@ -154,6 +156,8 @@ OUString SerfLockStore::getLockToken( const OUString& rLock 
)
 OUString const*
 SerfLockStore::getLockTokenForURI(OUString const& rURI, css::ucb::Lock 
const*const pLock)
 {
+    assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
+
     osl::MutexGuard aGuard( m_aMutex );
 
     auto const it(m_aLockInfoMap.find(rURI));
@@ -187,6 +191,8 @@ void SerfLockStore::addLock( const OUString& rURI,
                              rtl::Reference<CurlSession> const & xSession,
                              sal_Int32 nLastChanceToSendRefreshRequest )
 {
+    assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
+
     osl::MutexGuard aGuard( m_aMutex );
 
     m_aLockInfoMap[ rURI ]
@@ -196,12 +202,14 @@ void SerfLockStore::addLock( const OUString& rURI,
 }
 
 
-void SerfLockStore::updateLock( const OUString& rLock,
+void SerfLockStore::updateLock( const OUString& rURI,
                                 sal_Int32 nLastChanceToSendRefreshRequest )
 {
+    assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
+
     osl::MutexGuard aGuard( m_aMutex );
 
-    LockInfoMap::iterator it( m_aLockInfoMap.find( rLock ) );
+    LockInfoMap::iterator const it(m_aLockInfoMap.find(rURI));
     SAL_WARN_IF( it == m_aLockInfoMap.end(), "ucb.ucp.webdav",
                 "SerfLockStore::updateLock: lock not found!" );
 
@@ -213,11 +221,13 @@ void SerfLockStore::updateLock( const OUString& rLock,
 }
 
 
-void SerfLockStore::removeLock( const OUString& rLock )
+void SerfLockStore::removeLock(const OUString& rURI)
 {
+    assert(rURI.startsWith("http://";) || rURI.startsWith("https://";));
+
     osl::ClearableMutexGuard aGuard( m_aMutex );
 
-    m_aLockInfoMap.erase( rLock );
+    m_aLockInfoMap.erase(rURI);
 
     if ( m_aLockInfoMap.empty() )
         stopTicker(aGuard);
diff --git a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx 
b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
index 4aeb3a020dbc..7a420187813c 100644
--- a/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
+++ b/ucb/source/ucp/webdav-curl/SerfLockStore.hxx
@@ -68,7 +68,7 @@ public:
     ~SerfLockStore();
 
     bool finishing() const;
-    OUString getLockToken( const OUString& rLock );
+    OUString getLockToken(const OUString& rURI);
 
     OUString const* getLockTokenForURI(OUString const& rURI, css::ucb::Lock 
const* pLock);
 
@@ -80,10 +80,10 @@ public:
                   // -1: infinite lock, no refresh
                   sal_Int32 nLastChanceToSendRefreshRequest );
 
-    void updateLock( const OUString& rLock,
+    void updateLock( const OUString& rURI,
                      sal_Int32 nLastChanceToSendRefreshRequest );
 
-    void removeLock( const OUString& rLock );
+    void removeLock(const OUString& rURI);
 
     void refreshLocks();
 

Reply via email to