11 #include "LibCyberRadio/Common/HttpsSession.h" 12 #include "LibCyberRadio/Common/Debuggable.h" 13 #include "LibCyberRadio/Common/Pythonesque.h" 14 #include <curl/curl.h> 25 class CurlGlobalInitializer :
public Debuggable
28 CurlGlobalInitializer(CurlGlobalInitializer
const&) =
delete;
29 CurlGlobalInitializer&
operator=(CurlGlobalInitializer
const&) =
delete;
31 static std::shared_ptr<CurlGlobalInitializer> instance()
33 static std::shared_ptr<CurlGlobalInitializer> s{
new CurlGlobalInitializer};
38 CurlGlobalInitializer() :
41 this->
debug(
"Initializing CURL\n");
42 curl_global_init(CURL_GLOBAL_ALL);
51 _session(curl_easy_init()),
57 CurlGlobalInitializer::instance();
58 this->
debug(
"CONSTRUCTED\n");
66 curl_easy_cleanup(_session);
67 this->
debug(
"DESTROYED\n");
71 const std::string& url,
75 this->
debug(
"[get] Called; URL=%s, verify=%s\n",
81 this->
debug(
"[get] Setting request options\n");
82 curl_easy_setopt(_session, CURLOPT_URL, url.c_str());
83 curl_easy_setopt(_session, CURLOPT_SSL_VERIFYPEER, verify ? 1L : 0L);
84 curl_easy_setopt(_session, CURLOPT_SSL_VERIFYHOST, verify ? 1L : 0L);
85 curl_easy_setopt(_session, CURLOPT_HTTPGET, 1L);
87 this->
debug(
"[get] Executing request\n");
88 res = curl_easy_perform(_session);
89 this->
debug(
"[get] Request status: %d (%s)\n", res, this->
debugCurl(res));
91 bool ret = (res == CURLE_OK);
94 curl_easy_getinfo(_session, CURLINFO_RESPONSE_CODE, &_responseCode);
100 if (_responseCode >= 400)
104 _lastReqErrInfo = vec[0];
112 const std::string& url,
115 const char* contentType,
119 this->
debug(
"[post] Called; URL=%s, verify=%s\n",
125 this->
debug(
"[post] Setting request options\n");
126 curl_easy_setopt(_session, CURLOPT_VERBOSE, 0L);
127 curl_easy_setopt(_session, CURLOPT_URL, url.c_str());
128 curl_easy_setopt(_session, CURLOPT_SSL_VERIFYPEER, verify ? 1L : 0L);
129 curl_easy_setopt(_session, CURLOPT_SSL_VERIFYHOST, verify ? 1L : 0L);
130 struct curl_slist* headers = NULL;
132 memset(ctheader, 0,
sizeof(ctheader));
133 strcpy(ctheader,
"Content-type: ");
134 strcat(ctheader, contentType);
135 headers = curl_slist_append(headers, ctheader);
136 curl_easy_setopt(_session, CURLOPT_HTTPHEADER, headers);
137 curl_easy_setopt(_session, CURLOPT_POSTFIELDS, data);
138 curl_easy_setopt(_session, CURLOPT_POSTFIELDSIZE, (
long)length);
139 curl_easy_setopt(_session, CURLOPT_POST, 1L);
141 this->
debug(
"[post] Executing request\n");
142 res = curl_easy_perform(_session);
143 this->
debug(
"[post] Request status: %d (%s)\n", res, this->
debugCurl(res));
145 bool ret = (res == CURLE_OK);
148 curl_easy_getinfo(_session, CURLINFO_RESPONSE_CODE, &_responseCode);
154 if (_responseCode >= 400)
158 _lastReqErrInfo = vec[0];
161 curl_slist_free_all(headers);
168 return _responseCode;
173 return _header.str();
178 return _response.str();
183 return _lastReqErrInfo;
192 _header.write(ptr, size);
203 _response.write(ptr, size);
210 this->
debug(
"[initializeRequest] Called\n");
218 curl_easy_reset(_session);
224 res = curl_easy_setopt(_session, CURLOPT_HEADERFUNCTION,
226 if ( res == CURLE_OK )
228 res = curl_easy_setopt(_session, CURLOPT_HEADERDATA,
this);
235 if ( res == CURLE_OK )
237 res = curl_easy_setopt(_session, CURLOPT_WRITEFUNCTION,
240 if ( res == CURLE_OK )
242 res = curl_easy_setopt(_session, CURLOPT_WRITEDATA,
this);
244 this->
debug(
"[initializeRequest] Returning %d (%s)\n", res, this->
debugCurl(res));
252 return curl_easy_strerror(x);
264 size_t bytes = size * nitems;
277 size_t bytes = size * nmemb;
virtual CURLcode initializeRequest()
Initializes the session object to handle a new request.
virtual long getResponseCode() const
Gets the HTTPS response code from the last request.
static size_t writeDataCallback(char *ptr, size_t size, size_t nmemb, void *userdata)
Callback function that libcurl "writes" data to when retrieving an HTTPS response body...
Debuggable & operator=(const Debuggable &other)
Assignment operator for Debuggable objects.
virtual size_t writeResponseData(char *ptr, size_t size)
Write data into the response buffer.
virtual std::string getResponseHeader() const
Gets the HTTPS header from the last request.
virtual ~HttpsSession()
Destroys an HttpsSession object.
Class that supports debug output.
static BasicStringList Split(const std::string &str, const std::string &sep, int maxsplit=INT_MAX)
Splits the given string into a list of string tokens.
virtual int debug(const char *format,...)
Outputs debug information.
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
virtual std::string getResponseBody() const
Gets the HTTPS response body from the last request.
static size_t headerCallback(char *buffer, size_t size, size_t nitems, void *userdata)
Callback function that libcurl "writes" data to when retrieving an HTTPS response header...
Defines functionality for LibCyberRadio applications.
virtual bool get(const std::string &url, bool verify=true)
Gets data from a given URL over HTTPS.
Debuggable(bool debug=false, const std::string &debug_name="", FILE *debug_fp=DEBUG_FP, const std::string &debug_timefmt=DEBUG_TIME_FMT)
Constructs a Debuggable object.
virtual const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
virtual size_t writeHeader(char *ptr, size_t size)
Write data into the header buffer.
HttpsSession(bool debug=false)
Constructs an HttpsSession object.
virtual bool post(const std::string &url, void *data, size_t length, const char *contentType="text/plain", bool verify=true)
Posts data to a given URL over HTTPS.
Class that encapsulates an HTTPS session.
virtual const char * debugCurl(CURLcode x)
Returns a string corresponding to a libcurl error code.
virtual std::string getLastRequestErrorInfo() const
Gets the error information for the last request.