8
8
namespace TgBot {
9
9
10
10
CurlHttpClient::CurlHttpClient () : _httpParser() {
11
- curlSettings = curl_easy_init ();
12
-
13
- curl_easy_setopt (curlSettings, CURLOPT_CONNECTTIMEOUT, 20 );
14
- curl_easy_setopt (curlSettings, CURLOPT_TIMEOUT, _timeout);
15
11
}
16
12
17
13
CurlHttpClient::~CurlHttpClient () {
18
- curl_easy_cleanup (curlSettings);
14
+ std::lock_guard<std::mutex> lock (curlHandlesMutex);
15
+ for (auto & c : curlHandles) {
16
+ curl_easy_cleanup (c.second );
17
+ }
18
+ }
19
+
20
+ static CURL* getCurlHandle (const CurlHttpClient *c_) {
21
+ CurlHttpClient *c = const_cast <CurlHttpClient *>(c_);
22
+
23
+ std::lock_guard<std::mutex> lock (c->curlHandlesMutex );
24
+ auto id = std::this_thread::get_id ();
25
+ auto it = c->curlHandles .find (id);
26
+ if (it == c->curlHandles .end ()) {
27
+ CURL* curl = curl_easy_init ();
28
+ if (!curl) {
29
+ throw std::runtime_error (" curl_easy_init() failed" );
30
+ }
31
+ curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, 20 );
32
+ curl_easy_setopt (curl, CURLOPT_TIMEOUT, c->_timeout );
33
+ c->curlHandles [id] = curl;
34
+ return curl;
35
+ }
36
+
37
+ return it->second ;
19
38
}
20
39
21
40
static std::size_t curlWriteString (char * ptr, std::size_t size, std::size_t nmemb, void * userdata) {
@@ -24,21 +43,14 @@ static std::size_t curlWriteString(char* ptr, std::size_t size, std::size_t nmem
24
43
}
25
44
26
45
std::string CurlHttpClient::makeRequest (const Url& url, const std::vector<HttpReqArg>& args) const {
27
- // Copy settings for each call because we change CURLOPT_URL and other stuff.
28
- // This also protects multithreaded case.
29
- auto curl = curl_easy_duphandle (curlSettings);
46
+ CURL* curl = getCurlHandle (this );
30
47
31
48
std::string u = url.protocol + " ://" + url.host + url.path ;
32
49
if (args.empty ()) {
33
50
u += " ?" + url.query ;
34
51
}
35
52
curl_easy_setopt (curl, CURLOPT_URL, u.c_str ());
36
53
37
- // disable keep-alive
38
- struct curl_slist * headers = nullptr ;
39
- headers = curl_slist_append (headers, " Connection: close" );
40
- curl_easy_setopt (curl, CURLOPT_HTTPHEADER, headers);
41
-
42
54
curl_mime* mime;
43
55
curl_mimepart* part;
44
56
mime = curl_mime_init (curl);
@@ -64,8 +76,6 @@ std::string CurlHttpClient::makeRequest(const Url& url, const std::vector<HttpRe
64
76
curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errbuf);
65
77
66
78
auto res = curl_easy_perform (curl);
67
- curl_slist_free_all (headers);
68
- curl_easy_cleanup (curl);
69
79
curl_mime_free (mime);
70
80
71
81
// If the request did not complete correctly, show the error
0 commit comments