1 | #include "cpr/curlholder.h" |
---|---|
2 | #include <cassert> |
3 | |
4 | namespace cpr { |
5 | CurlHolder::CurlHolder() { |
6 | /** |
7 | * Allow multithreaded access to CPR by locking curl_easy_init(). |
8 | * curl_easy_init() is not thread safe. |
9 | * References: |
10 | * https://curl.haxx.se/libcurl/c/curl_easy_init.html |
11 | * https://curl.haxx.se/libcurl/c/threadsafe.html |
12 | **/ |
13 | curl_easy_init_mutex_().lock(); |
14 | // NOLINTNEXTLINE (cppcoreguidelines-prefer-member-initializer) since we need it to happen inside the lock |
15 | handle = curl_easy_init(); |
16 | curl_easy_init_mutex_().unlock(); |
17 | |
18 | assert(handle); |
19 | } // namespace cpr |
20 | |
21 | CurlHolder::~CurlHolder() { |
22 | curl_slist_free_all(list: chunk); |
23 | curl_slist_free_all(list: resolveCurlList); |
24 | curl_mime_free(mime: multipart); |
25 | curl_easy_cleanup(curl: handle); |
26 | } |
27 | |
28 | std::string CurlHolder::urlEncode(const std::string& s) const { |
29 | assert(handle); |
30 | char* output = curl_easy_escape(handle, string: s.c_str(), length: static_cast<int>(s.length())); |
31 | if (output) { |
32 | std::string result = output; |
33 | curl_free(p: output); |
34 | return result; |
35 | } |
36 | return ""; |
37 | } |
38 | |
39 | std::string CurlHolder::urlDecode(const std::string& s) const { |
40 | assert(handle); |
41 | char* output = curl_easy_unescape(handle, string: s.c_str(), length: static_cast<int>(s.length()), outlength: nullptr); |
42 | if (output) { |
43 | std::string result = output; |
44 | curl_free(p: output); |
45 | return result; |
46 | } |
47 | return ""; |
48 | } |
49 | } // namespace cpr |
50 |