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