summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-05-04 18:04:14 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2022-05-09 10:47:57 +0200
commit2930cdcc11a191c2c4f328ac123c7d651f5360dd (patch)
tree186f3610bb52e8ee3b4cd3fce3a90d92b4bb67c8
parentcf1fa4900840b94380ae29c8f296356b995b6482 (diff)
ucb: webdav-curl: if LOCK fails, display error message
Sharepoint may reject LOCK with HTTP/1.1 403 FORBIDDEN and then a dialog pops up via UUIInteractionHelper that says "Server error message: ." Let's actually put some error message in the dialog, why not the HTTP status line, plus a little prefix to see which method failed. Change-Id: Ied895787f813c5cddcb18eb4f693d5bfc8c62076 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133835 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> (cherry picked from commit cb64a52afc92891ab853b9bb1294610bb9ca98d0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133856 Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de> (cherry picked from commit 061fbad1e33f68726ee5605c7903f4ae219d8539)
-rw-r--r--ucb/source/ucp/webdav-curl/CurlSession.cxx79
1 files changed, 47 insertions, 32 deletions
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index 1c0201cd7680..4fe05ab97e72 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -19,6 +19,7 @@
#include <comphelper/string.hxx>
#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
#include <officecfg/Inet.hxx>
@@ -752,15 +753,15 @@ struct CurlProcessor
static auto URIReferenceToURI(CurlSession& rSession, OUString const& rURIReference) -> CurlUri;
static auto ProcessRequestImpl(
- CurlSession& rSession, CurlUri const& rURI, curl_slist* pRequestHeaderList,
- uno::Reference<io::XOutputStream> const* pxOutStream,
+ CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod,
+ curl_slist* pRequestHeaderList, uno::Reference<io::XOutputStream> const* pxOutStream,
uno::Sequence<sal_Int8> const* pInData,
::std::pair<::std::vector<OUString> const&, DAVResource&> const* pRequestedHeaders,
ResponseHeaders& rHeaders) -> void;
static auto ProcessRequest(
- CurlSession& rSession, CurlUri const& rURI, ::std::vector<CurlOption> const& rOptions,
- DAVRequestEnvironment const* pEnv,
+ CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod,
+ ::std::vector<CurlOption> const& rOptions, DAVRequestEnvironment const* pEnv,
::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist, curl_slist_free_all>>
pRequestHeaderList,
uno::Reference<io::XOutputStream> const* pxOutStream,
@@ -807,7 +808,8 @@ auto CurlProcessor::URIReferenceToURI(CurlSession& rSession, OUString const& rUR
/// main function to initiate libcurl requests
auto CurlProcessor::ProcessRequestImpl(
- CurlSession& rSession, CurlUri const& rURI, curl_slist* const pRequestHeaderList,
+ CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod,
+ curl_slist* const pRequestHeaderList,
uno::Reference<io::XOutputStream> const* const pxOutStream,
uno::Sequence<sal_Int8> const* const pInData,
::std::pair<::std::vector<OUString> const&, DAVResource&> const* const pRequestedHeaders,
@@ -1007,6 +1009,14 @@ auto CurlProcessor::ProcessRequestImpl(
}
else
{
+ // create message containing the HTTP method and response status line
+ OUString statusLine("\n" + rMethod + "\n=>\n");
+ if (!rHeaders.HeaderFields.empty() && !rHeaders.HeaderFields.back().first.empty()
+ && rHeaders.HeaderFields.back().first.front().startsWith("HTTP"))
+ {
+ statusLine += ::rtl::OStringToOUString(
+ rHeaders.HeaderFields.back().first.front().trim(), RTL_TEXTENCODING_ASCII_US);
+ }
switch (statusCode)
{
case SC_REQUEST_TIMEOUT:
@@ -1041,7 +1051,7 @@ auto CurlProcessor::ProcessRequestImpl(
[[fallthrough]];
}
default:
- throw DAVException(DAVException::DAV_HTTP_ERROR, "", statusCode);
+ throw DAVException(DAVException::DAV_HTTP_ERROR, statusLine, statusCode);
}
}
@@ -1098,8 +1108,8 @@ static auto TryRemoveExpiredLockToken(CurlSession& rSession, CurlUri const& rURI
}
auto CurlProcessor::ProcessRequest(
- CurlSession& rSession, CurlUri const& rURI, ::std::vector<CurlOption> const& rOptions,
- DAVRequestEnvironment const* const pEnv,
+ CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod,
+ ::std::vector<CurlOption> const& rOptions, DAVRequestEnvironment const* const pEnv,
::std::unique_ptr<curl_slist, deleter_from_fn<curl_slist, curl_slist_free_all>>
pRequestHeaderList,
uno::Reference<io::XOutputStream> const* const pxOutStream,
@@ -1293,7 +1303,7 @@ auto CurlProcessor::ProcessRequest(
try
{
- ProcessRequestImpl(rSession, rURI, pRequestHeaderList.get(), &xTempOutStream,
+ ProcessRequestImpl(rSession, rURI, rMethod, pRequestHeaderList.get(), &xTempOutStream,
pxInStream ? &data : nullptr, pRequestedHeaders, headers);
if (pxOutStream)
{ // only copy to result stream if transfer was successful
@@ -1482,7 +1492,8 @@ auto CurlSession::OPTIONS(OUString const& rURIReference,
g_NoBody, { CURLOPT_CUSTOMREQUEST, "OPTIONS", "CURLOPT_CUSTOMREQUEST" }
};
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, nullptr, nullptr, &headers);
+ CurlProcessor::ProcessRequest(*this, uri, "OPTIONS", options, &rEnv, nullptr, nullptr, nullptr,
+ &headers);
for (auto const& it : result.properties)
{
@@ -1626,7 +1637,7 @@ auto CurlProcessor::PropFind(
assert(xResponseInStream.is());
assert(xResponseOutStream.is());
- CurlProcessor::ProcessRequest(rSession, rURI, options, &rEnv, ::std::move(pList),
+ CurlProcessor::ProcessRequest(rSession, rURI, "PROPFIND", options, &rEnv, ::std::move(pList),
&xResponseOutStream, &xRequestInStream, nullptr);
if (o_pResourceInfos)
@@ -1774,8 +1785,8 @@ auto CurlSession::PROPPATCH(OUString const& rURIReference,
{ CURLOPT_INFILESIZE_LARGE, len, nullptr, CurlOption::Type::CurlOffT }
};
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, ::std::move(pList), nullptr,
- &xRequestInStream, nullptr);
+ CurlProcessor::ProcessRequest(*this, uri, "PROPPATCH", options, &rEnv, ::std::move(pList),
+ nullptr, &xRequestInStream, nullptr);
}
auto CurlSession::HEAD(OUString const& rURIReference, ::std::vector<OUString> const& rHeaderNames,
@@ -1790,7 +1801,8 @@ auto CurlSession::HEAD(OUString const& rURIReference, ::std::vector<OUString> co
::std::pair<::std::vector<OUString> const&, DAVResource&> const headers(rHeaderNames,
io_rResource);
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, nullptr, nullptr, &headers);
+ CurlProcessor::ProcessRequest(*this, uri, "HEAD", options, &rEnv, nullptr, nullptr, nullptr,
+ &headers);
}
auto CurlSession::GET(OUString const& rURIReference, DAVRequestEnvironment const& rEnv)
@@ -1812,8 +1824,8 @@ auto CurlSession::GET(OUString const& rURIReference, DAVRequestEnvironment const
::std::vector<CurlOption> const options{ { CURLOPT_HTTPGET, 1L, nullptr } };
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, &xResponseOutStream, nullptr,
- nullptr);
+ CurlProcessor::ProcessRequest(*this, uri, "GET", options, &rEnv, nullptr, &xResponseOutStream,
+ nullptr, nullptr);
uno::Reference<io::XInputStream> const xResponseInStream(
io::SequenceInputStream::createStreamFromSequence(m_xContext,
@@ -1832,7 +1844,7 @@ auto CurlSession::GET(OUString const& rURIReference, uno::Reference<io::XOutputS
::std::vector<CurlOption> const options{ { CURLOPT_HTTPGET, 1L, nullptr } };
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, &rxOutStream, nullptr,
+ CurlProcessor::ProcessRequest(*this, uri, "GET", options, &rEnv, nullptr, &rxOutStream, nullptr,
nullptr);
}
@@ -1854,8 +1866,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(*this, uri, options, &rEnv, nullptr, &xResponseOutStream, nullptr,
- &headers);
+ CurlProcessor::ProcessRequest(*this, uri, "GET", options, &rEnv, nullptr, &xResponseOutStream,
+ nullptr, &headers);
uno::Reference<io::XInputStream> const xResponseInStream(
io::SequenceInputStream::createStreamFromSequence(m_xContext,
@@ -1878,7 +1890,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(*this, uri, options, &rEnv, nullptr, &rxOutStream, nullptr,
+ CurlProcessor::ProcessRequest(*this, uri, "GET", options, &rEnv, nullptr, &rxOutStream, nullptr,
&headers);
}
@@ -1924,7 +1936,7 @@ auto CurlSession::PUT(OUString const& rURIReference,
::std::vector<CurlOption> const options{ { CURLOPT_INFILESIZE_LARGE, len, nullptr,
CurlOption::Type::CurlOffT } };
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, ::std::move(pList), nullptr,
+ CurlProcessor::ProcessRequest(*this, uri, "PUT", options, &rEnv, ::std::move(pList), nullptr,
&rxInStream, nullptr);
}
@@ -1964,7 +1976,7 @@ auto CurlSession::POST(OUString const& rURIReference, OUString const& rContentTy
uno::Reference<io::XOutputStream> const xResponseOutStream(xSeqOutStream);
assert(xResponseOutStream.is());
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, ::std::move(pList),
+ CurlProcessor::ProcessRequest(*this, uri, "POST", options, &rEnv, ::std::move(pList),
&xResponseOutStream, &rxInStream, nullptr);
uno::Reference<io::XInputStream> const xResponseInStream(
@@ -2007,8 +2019,8 @@ auto CurlSession::POST(OUString const& rURIReference, OUString const& rContentTy
::std::vector<CurlOption> const options{ { CURLOPT_POST, 1L, nullptr } };
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, ::std::move(pList), &rxOutStream,
- &rxInStream, nullptr);
+ CurlProcessor::ProcessRequest(*this, uri, "POST", options, &rEnv, ::std::move(pList),
+ &rxOutStream, &rxInStream, nullptr);
}
auto CurlSession::MKCOL(OUString const& rURIReference, DAVRequestEnvironment const& rEnv) -> void
@@ -2021,7 +2033,8 @@ auto CurlSession::MKCOL(OUString const& rURIReference, DAVRequestEnvironment con
g_NoBody, { CURLOPT_CUSTOMREQUEST, "MKCOL", "CURLOPT_CUSTOMREQUEST" }
};
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, nullptr, nullptr, nullptr);
+ CurlProcessor::ProcessRequest(*this, uri, "MKCOL", options, &rEnv, nullptr, nullptr, nullptr,
+ nullptr);
}
auto CurlProcessor::MoveOrCopy(CurlSession& rSession, OUString const& rSourceURIReference,
@@ -2050,8 +2063,8 @@ auto CurlProcessor::MoveOrCopy(CurlSession& rSession, OUString const& rSourceURI
g_NoBody, { CURLOPT_CUSTOMREQUEST, pMethod, "CURLOPT_CUSTOMREQUEST" }
};
- CurlProcessor::ProcessRequest(rSession, uriSource, options, &rEnv, ::std::move(pList), nullptr,
- nullptr, nullptr);
+ CurlProcessor::ProcessRequest(rSession, uriSource, OUString::createFromAscii(pMethod), options,
+ &rEnv, ::std::move(pList), nullptr, nullptr, nullptr);
}
auto CurlSession::COPY(OUString const& rSourceURIReference, OUString const& rDestinationURI,
@@ -2082,7 +2095,8 @@ auto CurlSession::DESTROY(OUString const& rURIReference, DAVRequestEnvironment c
g_NoBody, { CURLOPT_CUSTOMREQUEST, "DELETE", "CURLOPT_CUSTOMREQUEST" }
};
- CurlProcessor::ProcessRequest(*this, uri, options, &rEnv, nullptr, nullptr, nullptr, nullptr);
+ CurlProcessor::ProcessRequest(*this, uri, "DESTROY", options, &rEnv, nullptr, nullptr, nullptr,
+ nullptr);
}
auto CurlProcessor::Lock(
@@ -2115,8 +2129,9 @@ auto CurlProcessor::Lock(
TimeValue startTime;
osl_getSystemTime(&startTime);
- CurlProcessor::ProcessRequest(rSession, rURI, options, pEnv, ::std::move(pRequestHeaderList),
- &xResponseOutStream, pxRequestInStream, nullptr);
+ CurlProcessor::ProcessRequest(rSession, rURI, "LOCK", options, pEnv,
+ ::std::move(pRequestHeaderList), &xResponseOutStream,
+ pxRequestInStream, nullptr);
::std::vector<ucb::Lock> const acquiredLocks(parseWebDAVLockResponse(xResponseInStream));
SAL_WARN_IF(acquiredLocks.empty(), "ucb.ucp.webdav.curl",
@@ -2292,8 +2307,8 @@ auto CurlProcessor::Unlock(CurlSession& rSession, CurlUri const& rURI,
::std::vector<CurlOption> const options{ { CURLOPT_CUSTOMREQUEST, "UNLOCK",
"CURLOPT_CUSTOMREQUEST" } };
- CurlProcessor::ProcessRequest(rSession, rURI, options, pEnv, ::std::move(pList), nullptr,
- nullptr, nullptr);
+ CurlProcessor::ProcessRequest(rSession, rURI, "UNLOCK", options, pEnv, ::std::move(pList),
+ nullptr, nullptr, nullptr);
}
auto CurlSession::UNLOCK(OUString const& rURIReference, DAVRequestEnvironment const& rEnv) -> void