1#include "cpr/curlholder.h"
2#include <cassert>
3
4namespace cpr {
5CurlHolder::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
21CurlHolder::~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
28std::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
39std::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