From 6ce7419495521e31b20d6800be831ce40fd4de65 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sat, 18 May 2019 23:18:33 +0200 Subject: [PATCH] minicurl enhancements * support for adding headers to POST requests * don't truncate POST data at the first NUL byte * better error reporting for POST failures (like GET already has) --- pdns/minicurl.cc | 34 ++++++++++++++++++++++++++++++++-- pdns/minicurl.hh | 7 ++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/pdns/minicurl.cc b/pdns/minicurl.cc index 740940a57..5c846d09b 100644 --- a/pdns/minicurl.cc +++ b/pdns/minicurl.cc @@ -113,6 +113,7 @@ void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const C curl_easy_setopt(d_curl, CURLOPT_WRITEDATA, this); curl_easy_setopt(d_curl, CURLOPT_TIMEOUT, 2L); + clearHeaders(); d_data.clear(); } @@ -131,17 +132,46 @@ std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, co return ret; } -std::string MiniCurl::postURL(const std::string& str, const std::string& postdata) +std::string MiniCurl::postURL(const std::string& str, const std::string& postdata, MiniCurlHeaders& headers) { setupURL(str); + setHeaders(headers); + curl_easy_setopt(d_curl, CURLOPT_POSTFIELDSIZE, postdata.size()); curl_easy_setopt(d_curl, CURLOPT_POSTFIELDS, postdata.c_str()); auto res = curl_easy_perform(d_curl); + + long http_code = 0; + curl_easy_getinfo(d_curl, CURLINFO_RESPONSE_CODE, &http_code); + if(res != CURLE_OK) - throw std::runtime_error("Unable to post URL"); + throw std::runtime_error("Unable to post URL ("+std::to_string(http_code)+"): "+string(curl_easy_strerror(res))); std::string ret=d_data; d_data.clear(); return ret; } + +void MiniCurl::clearHeaders() +{ + if (d_curl) { + curl_easy_setopt(d_curl, CURLOPT_HTTPHEADER, NULL); + if (d_header_list != nullptr) { + curl_slist_free_all(d_header_list); + d_header_list = nullptr; + } + } +} + +void MiniCurl::setHeaders(const MiniCurlHeaders& headers) +{ + if (d_curl) { + for (auto& header : headers) { + std::stringstream header_ss; + header_ss << header.first << ": " << header.second; + d_header_list = curl_slist_append(d_header_list, header_ss.str().c_str()); + } + curl_easy_setopt(d_curl, CURLOPT_HTTPHEADER, d_header_list); + } +} diff --git a/pdns/minicurl.hh b/pdns/minicurl.hh index 80ee3d04f..a4a366398 100644 --- a/pdns/minicurl.hh +++ b/pdns/minicurl.hh @@ -31,16 +31,21 @@ class MiniCurl { public: + using MiniCurlHeaders = std::map; + static void init(); MiniCurl(const string& useragent="MiniCurl/0.0"); ~MiniCurl(); MiniCurl& operator=(const MiniCurl&) = delete; std::string getURL(const std::string& str, const ComboAddress* rem=0, const ComboAddress* src=0); - std::string postURL(const std::string& str, const std::string& postdata); + std::string postURL(const std::string& str, const std::string& postdata, MiniCurlHeaders& headers); private: CURL *d_curl; static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata); std::string d_data; + struct curl_slist* d_header_list = nullptr; void setupURL(const std::string& str, const ComboAddress* rem=0, const ComboAddress* src=0); + void setHeaders(const MiniCurlHeaders& headers); + void clearHeaders(); }; -- 2.40.0