ucb/source/ucp/webdav-curl/CurlSession.cxx |   75 +++++++++++++++++++++++++++++
 ucb/source/ucp/webdav-curl/CurlSession.hxx |    3 +
 ucb/source/ucp/webdav-curl/DAVSession.hxx  |    9 ---
 3 files changed, 80 insertions(+), 7 deletions(-)

New commits:
commit 1a7c877f51f3f6325b67d5250253efc36c3d4549
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Oct 8 18:27:38 2021 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 1 18:31:58 2021 +0100

    ucb: webdav-curl: implement OPTIONS()
    
    Change-Id: I601a161c3e6c4b7e741a79bfd15510bb40b5d81c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123283
    Tested-by: Michael Stahl <michael.st...@allotropia.de>
    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 8ac493ce3afb..29ddf3671de6 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -15,6 +15,7 @@
 
 #include <comphelper/attributelist.hxx>
 #include <comphelper/scopeguard.hxx>
+#include <comphelper/string.hxx>
 
 #include <officecfg/Inet.hxx>
 
@@ -1106,6 +1107,80 @@ auto CurlProcessor::ProcessRequest(
     }
 }
 
+auto CurlSession::OPTIONS(OUString const& rURIReference,
+
+                          DAVOptions& rOptions, DAVRequestEnvironment const& 
rEnv) -> void
+{
+    SAL_INFO("ucb.ucp.webdav.curl", "OPTIONS: " << rURIReference);
+
+    rOptions.reset();
+
+    ::std::vector<OUString> const headerNames{ "allow", "dav" };
+    DAVResource result;
+    ::std::pair<::std::vector<OUString> const&, DAVResource&> const 
headers(headerNames, result);
+
+    {
+        // scope to release m_Mutex before accessing LockStore
+        Guard g(m_Mutex, [&]() {
+            auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_NOBODY, 0L);
+            assert(rc == CURLE_OK);
+            (void)rc;
+            rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_CUSTOMREQUEST, 
nullptr);
+            assert(rc == CURLE_OK);
+        });
+
+        // need this to prevent calling write_callback
+        auto rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_NOBODY, 1L);
+        assert(rc == CURLE_OK);
+        rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_CUSTOMREQUEST, "OPTIONS");
+        if (rc != CURLE_OK)
+        {
+            SAL_WARN("ucb.ucp.webdav.curl", "CURLOPT_CUSTOMREQUEST failed: " 
<< GetErrorString(rc));
+            throw DAVException(DAVException::DAV_SESSION_CREATE,
+                               ConnectionEndPointString(m_URI.GetHost(), 
m_URI.GetPort()));
+        }
+
+        CurlProcessor::ProcessRequest(g, *this, rURIReference, &rEnv, nullptr, 
nullptr, nullptr,
+                                      &headers);
+    }
+
+    for (auto const& it : result.properties)
+    {
+        OUString value;
+        it.Value >>= value;
+        SAL_INFO("ucb.ucp.webdav.curl", "OPTIONS: header: " << it.Name << ": " 
<< value);
+        if (it.Name.equalsIgnoreAsciiCase("allow"))
+        {
+            rOptions.setAllowedMethods(value);
+        }
+        else if (it.Name.equalsIgnoreAsciiCase("dav"))
+        {
+            // see <http://tools.ietf.org/html/rfc4918#section-10.1>,
+            // <http://tools.ietf.org/html/rfc4918#section-18>,
+            // and <http://tools.ietf.org/html/rfc7230#section-3.2>
+            // we detect the class (1, 2 and 3), other elements (token, URL)
+            // are not used for now
+            auto const 
list(::comphelper::string::convertCommaSeparated(value));
+            for (OUString const& v : list)
+            {
+                if (v == "1")
+                {
+                    rOptions.setClass1();
+                }
+                else if (v == "2")
+                {
+                    rOptions.setClass2();
+                }
+                else if (v == "3")
+                {
+                    rOptions.setClass3();
+                }
+            }
+        }
+    }
+    rOptions.setResourceFound();
+}
+
 auto CurlProcessor::PropFind(
     CurlSession& rSession, OUString const& rURIReference, Depth const nDepth,
     ::std::tuple<::std::vector<OUString> const&, ::std::vector<DAVResource>* 
const,
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.hxx 
b/ucb/source/ucp/webdav-curl/CurlSession.hxx
index 6316a2ab47cc..58a828b29f14 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.hxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.hxx
@@ -55,6 +55,9 @@ public:
     virtual auto UsesProxy() -> bool override;
 
     // DAV methods
+    virtual auto OPTIONS(OUString const& rURIReference, DAVOptions& rOptions,
+                         DAVRequestEnvironment const& rEnv) -> void override;
+
     virtual auto PROPFIND(OUString const& rURIReference, Depth depth,
                           ::std::vector<OUString> const& rPropertyNames,
                           ::std::vector<DAVResource>& o_rResources,
diff --git a/ucb/source/ucp/webdav-curl/DAVSession.hxx 
b/ucb/source/ucp/webdav-curl/DAVSession.hxx
index c3caea7be6f2..cb298783161b 100644
--- a/ucb/source/ucp/webdav-curl/DAVSession.hxx
+++ b/ucb/source/ucp/webdav-curl/DAVSession.hxx
@@ -66,14 +66,9 @@ public:
 
     // DAV methods
 
-
-    // NOT USED
-    /*
     virtual void OPTIONS( const OUString & inPath,
-                          DAVCapabilities & outCapabilities,
-                          const DAVRequestEnvironment & rEnv )
-        throw( DAVException ) = 0;
-    */
+                          DAVOptions & rOptions,
+                          const DAVRequestEnvironment & rEnv ) = 0;
 
     // allprop & named
     /// @throws DAVException

Reply via email to