summaryrefslogtreecommitdiff
path: root/libcurl/curl_wrap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libcurl/curl_wrap.cpp')
-rw-r--r--libcurl/curl_wrap.cpp88
1 files changed, 44 insertions, 44 deletions
diff --git a/libcurl/curl_wrap.cpp b/libcurl/curl_wrap.cpp
index 1d72dcac..5f2a7f9d 100644
--- a/libcurl/curl_wrap.cpp
+++ b/libcurl/curl_wrap.cpp
@@ -28,13 +28,13 @@ void zen::libcurlInit()
if (++curlInitLevel != 1) //non-atomic => require call from main thread
return;
-
openSslInit();
- [[maybe_unused]] const CURLcode rc2 = ::curl_global_init(CURL_GLOBAL_NOTHING /*CURL_GLOBAL_DEFAULT = CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32*/);
- assert(rc2 == CURLE_OK);
-
- warn_static("log on error")
+ try
+ {
+ ASSERT_SYSERROR(::curl_global_init(CURL_GLOBAL_NOTHING /*CURL_GLOBAL_DEFAULT = CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32*/) == CURLE_OK);
+ }
+ catch (const SysError& e) { logExtraError(_("Error during process initialization.") + L"\n\n" + e.toString()); }
}
@@ -78,28 +78,35 @@ HttpSession::Result HttpSession::perform(const std::string& serverRelPath,
else
::curl_easy_reset(easyHandle_);
-
- std::vector<CurlOption> options;
+ auto setCurlOption = [easyHandle = easyHandle_](const CurlOption& curlOpt) //throw SysError
+ {
+ if (const CURLcode rc = ::curl_easy_setopt(easyHandle, curlOpt.option, curlOpt.value);
+ rc != CURLE_OK)
+ throw SysError(formatSystemError("curl_easy_setopt(" + numberTo<std::string>(static_cast<int>(curlOpt.option)) + ")",
+ formatCurlStatusCode(rc), utfTo<std::wstring>(::curl_easy_strerror(rc))));
+ };
char curlErrorBuf[CURL_ERROR_SIZE] = {};
- options.emplace_back(CURLOPT_ERRORBUFFER, curlErrorBuf);
+ setCurlOption({CURLOPT_ERRORBUFFER, curlErrorBuf}); //throw SysError
- options.emplace_back(CURLOPT_USERAGENT, "FreeFileSync"); //default value; may be overwritten by caller
+ setCurlOption({CURLOPT_USERAGENT, "FreeFileSync"}); //throw SysError
+ //default value; may be overwritten by caller
- //lifetime: keep alive until after curl_easy_setopt() below
- const std::string curlPath = serverPrefix_ + serverRelPath;
- options.emplace_back(CURLOPT_URL, curlPath.c_str());
+ setCurlOption({CURLOPT_URL, (serverPrefix_ + serverRelPath).c_str()}); //throw SysError
- options.emplace_back(CURLOPT_ACCEPT_ENCODING, ""); //libcurl: generate Accept-Encoding header containing all built-in supported encodings
+ setCurlOption({CURLOPT_ACCEPT_ENCODING, ""}); //throw SysError
+ //libcurl: generate Accept-Encoding header containing all built-in supported encodings
//=> usually generates "Accept-Encoding: deflate, gzip" - note: "gzip" used by Google Drive
- options.emplace_back(CURLOPT_NOSIGNAL, 1); //thread-safety: https://curl.haxx.se/libcurl/c/threadsafe.html
+ setCurlOption({CURLOPT_NOSIGNAL, 1}); //throw SysError
+ //thread-safety: https://curl.haxx.se/libcurl/c/threadsafe.html
- options.emplace_back(CURLOPT_CONNECTTIMEOUT, timeoutSec);
+ setCurlOption({CURLOPT_CONNECTTIMEOUT, timeoutSec}); //throw SysError
//CURLOPT_TIMEOUT: "Since this puts a hard limit for how long time a request is allowed to take, it has limited use in dynamic use cases with varying transfer times."
- options.emplace_back(CURLOPT_LOW_SPEED_TIME, timeoutSec);
- options.emplace_back(CURLOPT_LOW_SPEED_LIMIT, 1); //[bytes], can't use "0" which means "inactive", so use some low number
+ setCurlOption({CURLOPT_LOW_SPEED_TIME, timeoutSec}); //throw SysError
+ setCurlOption({CURLOPT_LOW_SPEED_LIMIT, 1}); //throw SysError
+ //[bytes], can't use "0" which means "inactive", so use some low number
std::exception_ptr userCallbackException;
@@ -123,18 +130,20 @@ HttpSession::Result HttpSession::perform(const std::string& serverRelPath,
return (*clientp)(curlfd, purpose); //free this poor little C-API from its shackles and redirect to a proper lambda
};
- options.emplace_back(CURLOPT_SOCKOPTFUNCTION, onSocketCreateWrapper);
- options.emplace_back(CURLOPT_SOCKOPTDATA, &onSocketCreate);
+ setCurlOption({CURLOPT_SOCKOPTFUNCTION, onSocketCreateWrapper}); //throw SysError
+ setCurlOption({CURLOPT_SOCKOPTDATA, &onSocketCreate}); //throw SysError
//libcurl forwards this char-string to OpenSSL as is, which - thank god - accepts UTF8
if (caCertFilePath_.empty())
{
- options.emplace_back(CURLOPT_CAINFO, 0); //see remarks in ftp.cpp
- options.emplace_back(CURLOPT_SSL_VERIFYPEER, 0);
- options.emplace_back(CURLOPT_SSL_VERIFYHOST, 0);
+ setCurlOption({CURLOPT_CAINFO, 0}); //throw SysError
+ setCurlOption({CURLOPT_SSL_VERIFYPEER, 0}); //throw SysError
+ setCurlOption({CURLOPT_SSL_VERIFYHOST, 0}); //throw SysError
+ //see remarks in ftp.cpp
}
else
- options.emplace_back(CURLOPT_CAINFO, caCertFilePath_.c_str()); //hopefully latest version from https://curl.haxx.se/docs/caextract.html
+ setCurlOption({CURLOPT_CAINFO, caCertFilePath_.c_str()}); //throw SysError
+ //hopefully latest version from https://curl.haxx.se/docs/caextract.html
//CURLOPT_SSL_VERIFYPEER => already active by default
//CURLOPT_SSL_VERIFYHOST =>
@@ -203,22 +212,24 @@ HttpSession::Result HttpSession::perform(const std::string& serverRelPath,
//---------------------------------------------------
if (receiveHeader)
{
- options.emplace_back(CURLOPT_HEADERDATA, &onHeaderReceived);
- options.emplace_back(CURLOPT_HEADERFUNCTION, onHeaderReceivedWrapper);
+ setCurlOption({CURLOPT_HEADERDATA, &onHeaderReceived}); //throw SysError
+ setCurlOption({CURLOPT_HEADERFUNCTION, onHeaderReceivedWrapper}); //throw SysError
}
if (writeResponse)
{
- options.emplace_back(CURLOPT_WRITEDATA, &onBytesReceived);
- options.emplace_back(CURLOPT_WRITEFUNCTION, onBytesReceivedWrapper);
+ setCurlOption({CURLOPT_WRITEDATA, &onBytesReceived}); //throw SysError
+ setCurlOption({CURLOPT_WRITEFUNCTION, onBytesReceivedWrapper}); //throw SysError
//{CURLOPT_BUFFERSIZE, 256 * 1024} -> defaults is 16 kB which seems to correspond to SSL packet size
//=> setting larget buffers size does nothing (recv still returns only 16 kB)
}
if (readRequest)
{
if (std::all_of(extraOptions.begin(), extraOptions.end(), [](const CurlOption& o) { return o.option != CURLOPT_POST; }))
- /**/options.emplace_back(CURLOPT_UPLOAD, 1); //issues HTTP PUT
- options.emplace_back(CURLOPT_READDATA, &getBytesToSend);
- options.emplace_back(CURLOPT_READFUNCTION, getBytesToSendWrapper);
+ /**/setCurlOption({CURLOPT_UPLOAD, 1}); //throw SysError
+ //issues HTTP PUT
+
+ setCurlOption({CURLOPT_READDATA, &getBytesToSend}); //throw SysError
+ setCurlOption({CURLOPT_READFUNCTION, getBytesToSendWrapper}); //throw SysError
//{CURLOPT_UPLOAD_BUFFERSIZE, 256 * 1024} -> default is 64 kB. apparently no performance improvement for larger buffers like 256 kB
//Contradicting options: CURLOPT_READFUNCTION, CURLOPT_POSTFIELDS:
@@ -240,12 +251,11 @@ HttpSession::Result HttpSession::perform(const std::string& serverRelPath,
headers = ::curl_slist_append(headers, "Expect:"); //guess, what: www.googleapis.com doesn't support it! e.g. gdriveUploadFile()
if (headers)
- options.emplace_back(CURLOPT_HTTPHEADER, headers);
+ setCurlOption({CURLOPT_HTTPHEADER, headers}); //throw SysError
//---------------------------------------------------
- append(options, extraOptions);
-
- applyCurlOptions(easyHandle_, options); //throw SysError
+ for (const CurlOption& option : extraOptions)
+ setCurlOption(option); //throw SysError
//=======================================================================================================
const CURLcode rcPerf = ::curl_easy_perform(easyHandle_);
@@ -394,13 +404,3 @@ std::wstring zen::formatCurlStatusCode(CURLcode sc)
return replaceCpy<std::wstring>(L"Curl status %x", L"%x", numberTo<std::wstring>(static_cast<int>(sc)));
}
-
-
-void zen::applyCurlOptions(CURL* easyHandle, const std::vector<CurlOption>& options) //throw SysError
-{
- for (const CurlOption& opt : options)
- if (const CURLcode rc = ::curl_easy_setopt(easyHandle, opt.option, opt.value);
- rc != CURLE_OK)
- throw SysError(formatSystemError("curl_easy_setopt(" + numberTo<std::string>(static_cast<int>(opt.option)) + ")",
- formatCurlStatusCode(rc), utfTo<std::wstring>(::curl_easy_strerror(rc))));
-}
bgstack15