From 061fbad1e33f68726ee5605c7903f4ae219d8539 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Wed, 4 May 2022 18:04:14 +0200 Subject: 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 (cherry picked from commit cb64a52afc92891ab853b9bb1294610bb9ca98d0) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133856 Reviewed-by: Thorsten Behrens --- ucb/source/ucp/webdav-curl/CurlSession.cxx | 79 ++++++++++++++++++------------ 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx index 66232a73a15f..ef3241f1c3dc 100644 --- a/ucb/source/ucp/webdav-curl/CurlSession.cxx +++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx @@ -19,6 +19,7 @@ #include #include +#include #include @@ -754,15 +755,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 const* pxOutStream, + CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod, + curl_slist* pRequestHeaderList, uno::Reference const* pxOutStream, uno::Sequence const* pInData, ::std::pair<::std::vector const&, DAVResource&> const* pRequestedHeaders, ResponseHeaders& rHeaders) -> void; static auto ProcessRequest( - CurlSession& rSession, CurlUri const& rURI, ::std::vector const& rOptions, - DAVRequestEnvironment const* pEnv, + CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod, + ::std::vector const& rOptions, DAVRequestEnvironment const* pEnv, ::std::unique_ptr> pRequestHeaderList, uno::Reference const* pxOutStream, @@ -809,7 +810,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 const* const pxOutStream, uno::Sequence const* const pInData, ::std::pair<::std::vector const&, DAVResource&> const* const pRequestedHeaders, @@ -1009,6 +1011,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: @@ -1043,7 +1053,7 @@ auto CurlProcessor::ProcessRequestImpl( [[fallthrough]]; } default: - throw DAVException(DAVException::DAV_HTTP_ERROR, "", statusCode); + throw DAVException(DAVException::DAV_HTTP_ERROR, statusLine, statusCode); } } @@ -1100,8 +1110,8 @@ static auto TryRemoveExpiredLockToken(CurlSession& rSession, CurlUri const& rURI } auto CurlProcessor::ProcessRequest( - CurlSession& rSession, CurlUri const& rURI, ::std::vector const& rOptions, - DAVRequestEnvironment const* const pEnv, + CurlSession& rSession, CurlUri const& rURI, OUString const& rMethod, + ::std::vector const& rOptions, DAVRequestEnvironment const* const pEnv, ::std::unique_ptr> pRequestHeaderList, uno::Reference const* const pxOutStream, @@ -1295,7 +1305,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 @@ -1484,7 +1494,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) { @@ -1628,7 +1639,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) @@ -1776,8 +1787,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 const& rHeaderNames, @@ -1792,7 +1803,8 @@ auto CurlSession::HEAD(OUString const& rURIReference, ::std::vector co ::std::pair<::std::vector 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) @@ -1814,8 +1826,8 @@ auto CurlSession::GET(OUString const& rURIReference, DAVRequestEnvironment const ::std::vector 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 const xResponseInStream( io::SequenceInputStream::createStreamFromSequence(m_xContext, @@ -1834,7 +1846,7 @@ auto CurlSession::GET(OUString const& rURIReference, uno::Reference 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); } @@ -1856,8 +1868,8 @@ auto CurlSession::GET(OUString const& rURIReference, ::std::vector con ::std::pair<::std::vector 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 const xResponseInStream( io::SequenceInputStream::createStreamFromSequence(m_xContext, @@ -1880,7 +1892,7 @@ auto CurlSession::GET(OUString const& rURIReference, uno::Reference 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); } @@ -1926,7 +1938,7 @@ auto CurlSession::PUT(OUString const& rURIReference, ::std::vector 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); } @@ -1966,7 +1978,7 @@ auto CurlSession::POST(OUString const& rURIReference, OUString const& rContentTy uno::Reference 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 const xResponseInStream( @@ -2009,8 +2021,8 @@ auto CurlSession::POST(OUString const& rURIReference, OUString const& rContentTy ::std::vector 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 @@ -2023,7 +2035,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, @@ -2052,8 +2065,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, @@ -2084,7 +2097,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( @@ -2117,8 +2131,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 const acquiredLocks(parseWebDAVLockResponse(xResponseInStream)); SAL_WARN_IF(acquiredLocks.empty(), "ucb.ucp.webdav.curl", @@ -2294,8 +2309,8 @@ auto CurlProcessor::Unlock(CurlSession& rSession, CurlUri const& rURI, ::std::vector 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 -- cgit