91 lines
3.2 KiB
C++
91 lines
3.2 KiB
C++
#include "HttpClient.hpp"
|
|
#include <curl/curl.h>
|
|
#include <cstring>
|
|
|
|
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<std::string*>(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<std::string, std::string>& 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<std::string, std::string>& 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<long>(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;
|
|
}
|