ucb/source/ucp/webdav-curl/CurlSession.cxx  |   24 ++++++++++++++++++++++++
 ucb/source/ucp/webdav-curl/DAVException.hxx |    1 +
 2 files changed, 25 insertions(+)

New commits:
commit 0d0f4411934dead0765930693072fe9582f50be9
Author:     László Németh <nem...@numbertext.org>
AuthorDate: Wed Jan 25 12:08:14 2023 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Fri Feb 3 10:11:42 2023 +0000

    tdf#152493 ucb WebDAV: fix upload using HTTP 1.0 fallback
    
    Fix broken libcurl upload to Vibe 4.0.6 WebDAV server
    using HTTP 1.0 fallback.
    
    Regression from commit 023ebf17898db4bca63129f079fd90b5cf76c1a9
    "ucb: remove --with-webdav=neon" (Neon had no such upload
    problem).
    
    HTTP 1.0 fallback found by Pál Zoltán Kochis.
    Fallback for CURLE_UNSUPPORTED_PROTOCOL
    suggested by Michael Stahl. Thanks for their and
    Attila Bakos' help.
    
    Michael Stahl's comment: "'HTTP/0.9' in the [curl] error
    message is very misleading: it simply means that a header
    was expected but there was no header, so what is received
    is interpreted as body.
    
    Note: the HTTP/1.0 works because it does not use the
    'Expect: 100-continue' so there should be no intermediate
    100 Continue response from the server at all - instead
    libcurl directly sends the XML document for the PROPFIND
    and the server sends the response, and the problem does
    not occur."
    
    Co-authored-by: Michael Stahl <michael.st...@allotropia.de>
    
    Change-Id: I8bd79154de14b6425e0324f4d8f6e64512c08264
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146067
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    (cherry picked from commit 30ca48f4dc0e65a3798e6b21574bc80f6d4953fa)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146315
    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 8e64608bfc8b..86eb265f55c6 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -955,6 +955,8 @@ auto CurlProcessor::ProcessRequestImpl(
                  "curl_easy_perform failed: " << GetErrorString(rc, 
rSession.m_ErrorBuffer));
         switch (rc)
         {
+            case CURLE_UNSUPPORTED_PROTOCOL:
+                throw DAVException(DAVException::DAV_UNSUPPORTED);
             case CURLE_COULDNT_RESOLVE_PROXY:
                 throw DAVException(
                     DAVException::DAV_HTTP_LOOKUP,
@@ -1241,6 +1243,7 @@ auto CurlProcessor::ProcessRequest(
         }
     }
     bool isRetry(false);
+    bool isFallbackHTTP10(false);
     int nAuthRequests(0);
     int nAuthRequestsProxy(0);
 
@@ -1464,6 +1467,27 @@ auto CurlProcessor::ProcessRequest(
                     }
                 }
             }
+            else if (rException.getError() == DAVException::DAV_UNSUPPORTED)
+            {
+                // tdf#152493 libcurl can't handle "Transfer-Encoding: chunked"
+                // in HTTP/1.1 100 Continue response.
+                // workaround: if HTTP/1.1 didn't work, try HTTP/1.0
+                // (but fallback only once - to prevent infinite loop)
+                if (isFallbackHTTP10)
+                {
+                    throw DAVException(DAVException::DAV_HTTP_ERROR);
+                }
+                isFallbackHTTP10 = true;
+                // note: this is not reset - future requests to this URI use 
it!
+                auto rc = curl_easy_setopt(rSession.m_pCurl.get(), 
CURLOPT_HTTP_VERSION,
+                                           CURL_HTTP_VERSION_1_0);
+                if (rc != CURLE_OK)
+                {
+                    throw DAVException(DAVException::DAV_HTTP_ERROR);
+                }
+                SAL_INFO("ucb.ucp.webdav.curl", "attempting fallback to 
HTTP/1.0");
+                isRetry = true;
+            }
             if (!isRetry)
             {
                 throw; // everything else: re-throw
diff --git a/ucb/source/ucp/webdav-curl/DAVException.hxx 
b/ucb/source/ucp/webdav-curl/DAVException.hxx
index 84dba895485c..759e43f25f8e 100644
--- a/ucb/source/ucp/webdav-curl/DAVException.hxx
+++ b/ucb/source/ucp/webdav-curl/DAVException.hxx
@@ -130,6 +130,7 @@ class DAVException : public std::exception
             DAV_SESSION_CREATE, // session creation error,
                                 // mData = server[:port]
             DAV_INVALID_ARG,    // invalid argument
+            DAV_UNSUPPORTED,    // internal to CurlSession
 
             DAV_LOCK_EXPIRED,   // DAV lock expired
 

Reply via email to