#include "HttpClient.hpp" #include #include void HttpClient::globalInit() { curl_global_init(CURL_GLOBAL_DEFAULT); } void HttpClient::globalCleanup() { curl_global_cleanup(); } namespace { size_t writeCallback(char* ptr, size_t size, size_t nmemb, void* userdata) { auto* out = static_cast(userdata); out->append(ptr, size * nmemb); return size * nmemb; } struct CurlHandle { CURL* h; CurlHandle() : h(curl_easy_init()) {} ~CurlHandle() { if (h) curl_easy_cleanup(h); } }; struct CurlSlist { curl_slist* list = nullptr; void append(const std::string& header) { list = curl_slist_append(list, header.c_str()); } ~CurlSlist() { if (list) curl_slist_free_all(list); } }; } // namespace HttpResponse HttpClient::get(const std::string& url, const std::map& headers, long timeout_seconds) { HttpResponse resp; CurlHandle curl; if (!curl.h) { resp.status = -1; return resp; } CurlSlist slist; for (const auto& [k, v] : headers) slist.append(k + ": " + v); curl_easy_setopt(curl.h, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl.h, CURLOPT_HTTPHEADER, slist.list); curl_easy_setopt(curl.h, CURLOPT_WRITEFUNCTION, writeCallback); curl_easy_setopt(curl.h, CURLOPT_WRITEDATA, &resp.body); curl_easy_setopt(curl.h, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl.h, CURLOPT_TIMEOUT, timeout_seconds); curl_easy_setopt(curl.h, CURLOPT_SSL_VERIFYPEER, 1L); curl_easy_setopt(curl.h, CURLOPT_ACCEPT_ENCODING, ""); // accept gzip/deflate CURLcode rc = curl_easy_perform(curl.h); if (rc != CURLE_OK) { resp.status = -1; resp.body = curl_easy_strerror(rc); return resp; } long code = 0; curl_easy_getinfo(curl.h, CURLINFO_RESPONSE_CODE, &code); resp.status = code; return resp; } HttpResponse HttpClient::postJson(const std::string& url, const std::string& json_body, const std::map& headers, long timeout_seconds) { HttpResponse resp; CurlHandle curl; if (!curl.h) { resp.status = -1; return resp; } CurlSlist slist; slist.append("Content-Type: application/json"); for (const auto& [k, v] : headers) slist.append(k + ": " + v); curl_easy_setopt(curl.h, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl.h, CURLOPT_HTTPHEADER, slist.list); curl_easy_setopt(curl.h, CURLOPT_POSTFIELDS, json_body.c_str()); curl_easy_setopt(curl.h, CURLOPT_POSTFIELDSIZE, static_cast(json_body.size())); curl_easy_setopt(curl.h, CURLOPT_WRITEFUNCTION, writeCallback); curl_easy_setopt(curl.h, CURLOPT_WRITEDATA, &resp.body); curl_easy_setopt(curl.h, CURLOPT_TIMEOUT, timeout_seconds); curl_easy_setopt(curl.h, CURLOPT_SSL_VERIFYPEER, 1L); CURLcode rc = curl_easy_perform(curl.h); if (rc != CURLE_OK) { resp.status = -1; resp.body = curl_easy_strerror(rc); return resp; } long code = 0; curl_easy_getinfo(curl.h, CURLINFO_RESPONSE_CODE, &code); resp.status = code; return resp; }