summaryrefslogtreecommitdiff
path: root/ucb
diff options
context:
space:
mode:
authorMichael Stahl <michael.stahl@allotropia.de>2022-10-19 14:27:04 +0200
committerMichael Stahl <michael.stahl@allotropia.de>2024-03-08 16:24:36 +0100
commit27fb4efea57881d49e9598e84b4a1df6a6e8719a (patch)
tree0ce120e8de863f6c7c32cf6e4c3ae5dab48232e0 /ucb
parent1d00bd9b570b2b58a6742469f7671978a845cd68 (diff)
ucb: webdav-curl: add a shared cookie store
Change-Id: I8796aa7de6335c57818aa570a55fdc64d85bd9f9 (cherry picked from commit 7e8b26560020ae2819cfd621b5790e51083b7e92) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164552 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Diffstat (limited to 'ucb')
-rw-r--r--ucb/source/ucp/webdav-curl/CurlSession.cxx57
1 files changed, 57 insertions, 0 deletions
diff --git a/ucb/source/ucp/webdav-curl/CurlSession.cxx b/ucb/source/ucp/webdav-curl/CurlSession.cxx
index 342ba3669699..61c54cba2df8 100644
--- a/ucb/source/ucp/webdav-curl/CurlSession.cxx
+++ b/ucb/source/ucp/webdav-curl/CurlSession.cxx
@@ -49,6 +49,9 @@ using namespace ::com::sun::star;
namespace
{
+void lock_cb(CURL*, curl_lock_data, curl_lock_access, void*);
+void unlock_cb(CURL*, curl_lock_data, curl_lock_access, void*);
+
/// globals container
struct Init
{
@@ -56,17 +59,69 @@ struct Init
/// so don't call LockStore with m_Mutex held to prevent deadlock.
::http_dav_ucp::SerfLockStore LockStore;
+ /// libcurl shared data - to store cookies beyond one connection
+ ::std::mutex ShareLock[CURL_LOCK_DATA_LAST];
+ ::std::unique_ptr<CURLSH, http_dav_ucp::deleter_from_fn<CURLSH, curl_share_cleanup>> pShare;
+
Init()
{
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
{
assert(!"curl_global_init failed");
+ ::std::abort(); // can't handle error here
+ }
+ pShare.reset(curl_share_init());
+ if (!pShare)
+ {
+ assert(!"curl_share_init failed");
+ ::std::abort(); // can't handle error here
+ }
+ CURLSHcode sh = curl_share_setopt(pShare.get(), CURLSHOPT_LOCKFUNC, lock_cb);
+ if (sh != CURLSHE_OK)
+ {
+ assert(!"curl_share_setopt failed");
+ ::std::abort(); // can't handle error here
+ }
+ sh = curl_share_setopt(pShare.get(), CURLSHOPT_UNLOCKFUNC, unlock_cb);
+ if (sh != CURLSHE_OK)
+ {
+ assert(!"curl_share_setopt failed");
+ ::std::abort(); // can't handle error here
+ }
+ sh = curl_share_setopt(pShare.get(), CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
+ if (sh != CURLSHE_OK)
+ {
+ assert(!"curl_share_setopt failed");
+ ::std::abort(); // can't handle error here
}
}
// do not call curl_global_cleanup() - this is not the only client of curl
};
Init g_Init;
+// global callbacks
+
+void lock_cb(CURL* /*handle*/, curl_lock_data const data, curl_lock_access /*access*/,
+ void* /*userptr*/)
+{
+ assert(0 <= data && data < CURL_LOCK_DATA_LAST);
+ try
+ {
+ g_Init.ShareLock[data].lock();
+ }
+ catch (std::exception const&)
+ {
+ ::std::abort();
+ }
+}
+
+void unlock_cb(CURL* /*handle*/, curl_lock_data const data, curl_lock_access /*access*/,
+ void* /*userptr*/)
+{
+ assert(0 <= data && data < CURL_LOCK_DATA_LAST);
+ g_Init.ShareLock[data].unlock();
+}
+
struct ResponseHeaders
{
::std::vector<::std::pair<::std::vector<OString>, ::std::optional<long>>> HeaderFields;
@@ -673,6 +728,8 @@ CurlSession::CurlSession(uno::Reference<uno::XComponentContext> xContext,
assert(rc == CURLE_OK);
#endif
}
+ rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_SHARE, g_Init.pShare.get());
+ assert(rc == CURLE_OK);
// set this initially, may be overwritten during authentication
rc = curl_easy_setopt(m_pCurl.get(), CURLOPT_HTTPAUTH, CURLAUTH_ANY);
assert(rc == CURLE_OK); // ANY is always available