ucb/source/ucp/webdav-curl/CurlSession.cxx |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

New commits:
commit 8e34fe50412fd58a600ba1b8238b80444aec02e5
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Nov 19 18:22:59 2021 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Nov 22 11:26:28 2021 +0100

    ucb: webdav-curl: don't use chunked encoding for PUT
    
    What happens with Nextcloud:
    
     CURLINFO_HEADER_OUT: 0xa028408: PUT .../testB.odt HTTP/1.1
    User-Agent: LibreOffice 7.3.0.0 curl/7.79.1 NSS/3.71
    Accept: */*
    Accept-Encoding: deflate, gzip
    Transfer-Encoding: chunked
    Expect: 100-continue
     debug log: 0xa028408: STATE: DO => DID handle 0xa028408; line 2077 
(connection #0)
     debug log: 0xa028408: STATE: DID => PERFORMING handle 0xa028408; line 2196 
(connection #0)
     debug log: 0xa028408: HTTP 1.1 or later with persistent connection
     CURLINFO_HEADER_IN: 0xa028408: HTTP/1.1 100 Continue
     debug log: 0xa028408: CURLINFO_DATA_OUT 8357
     debug log: 0xa028408: Signaling end of chunked upload via terminating 
chunk.
     debug log: 0xa028408: CURLINFO_DATA_OUT 5
     debug log: 0xa028408: Mark bundle as not supporting multiuse
     debug log: 0xa028408: HTTP 1.1 or later with persistent connection
     CURLINFO_HEADER_IN: 0xa028408: HTTP/1.1 201 Created
     CURLINFO_HEADER_IN: 0xa028408: Date: Fri, 19 Nov 2021 16:27:47 GMT
     CURLINFO_HEADER_IN: 0xa028408: Server: Apache
     CURLINFO_HEADER_IN: 0xa028408: Content-Length: 0
    
    ... yes, "201 Created" a 0 byte file.
    
    https://github.com/nextcloud/server/issues/7995
    
    Apparently this doesn't happen with header Content-Length: 8347
    
    Change-Id: I3f38d50530a8b6430b27de2525370e1d95705da6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125579
    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 5e5568a44773..e3c5fdc19191 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -1800,13 +1800,15 @@ auto CurlSession::PUT(OUString const& 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, 
curl_slist_free_all>> pList(
-        curl_slist_append(nullptr, "Transfer-Encoding: chunked"));
-    if (!pList)
+    // NextCloud silently fails with chunked encoding
+    uno::Reference<io::XSeekable> const xSeekable(rxInStream, uno::UNO_QUERY);
+    if (!xSeekable.is())
     {
-        throw uno::RuntimeException("curl_slist_append failed");
+        throw uno::RuntimeException("TODO: not seekable");
     }
+    curl_off_t const len(xSeekable->getLength() - xSeekable->getPosition());
+
+    ::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist, 
curl_slist_free_all>> pList;
     OUString const* const 
pToken(g_Init.LockStore.getLockTokenForURI(uri.GetURI(), nullptr));
     if (pToken)
     {
@@ -1828,7 +1830,7 @@ auto CurlSession::PUT(OUString const& rURIReference,
 
     // lock m_Mutex after accessing global LockStore to avoid deadlock
 
-    ::std::vector<CurlOption> const options{};
+    ::std::vector<CurlOption> const options{ { CURLOPT_INFILESIZE_LARGE, len, 
nullptr } };
 
     CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, 
::std::move(pList), nullptr,
                                   &rxInStream, nullptr);

Reply via email to