88namespace TgBot {
99
1010CurlHttpClient::CurlHttpClient () : _httpParser() {
11- curlSettings = curl_easy_init ();
12-
13- curl_easy_setopt (curlSettings, CURLOPT_CONNECTTIMEOUT, 20 );
14- curl_easy_setopt (curlSettings, CURLOPT_TIMEOUT, _timeout);
1511}
1612
1713CurlHttpClient::~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 ;
1938}
2039
2140static 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
2443}
2544
2645std::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 );
3047
3148 std::string u = url.protocol + " ://" + url.host + url.path ;
3249 if (args.empty ()) {
3350 u += " ?" + url.query ;
3451 }
3552 curl_easy_setopt (curl, CURLOPT_URL, u.c_str ());
3653
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-
4254 curl_mime* mime;
4355 curl_mimepart* part;
4456 mime = curl_mime_init (curl);
@@ -64,8 +76,6 @@ std::string CurlHttpClient::makeRequest(const Url& url, const std::vector<HttpRe
6476 curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, errbuf);
6577
6678 auto res = curl_easy_perform (curl);
67- curl_slist_free_all (headers);
68- curl_easy_cleanup (curl);
6979 curl_mime_free (mime);
7080
7181 // If the request did not complete correctly, show the error
0 commit comments