--- a/src/HTTPClient.cpp Sat Mar 12 20:48:25 2022 +0100
+++ b/src/HTTPClient.cpp Sun Mar 13 01:17:59 2022 +0100
@@ -16,6 +16,7 @@
*/
#include <sstream>
+#include <iostream>
#include <curl/curl.h>
@@ -30,15 +31,38 @@
public:
CURL* curl;
std::stringstream responseBody;
- std::vector<std::string> responseHeaders;
+ std::stringstream responseHeaders;
HTTPClientImpl(CURL* curl) : curl(curl) {
}
- static size_t curlWriteCallback(char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl) {
- size_t r = size * nmemb;
- impl->responseBody.write(buffer, r);
- return r;
+ std::vector<std::string> getResponseHeaders() {
+ std::vector<std::string> heathers;
+ std::stringstream name;
+ std::stringstream value;
+ std::stringstream* current = &name;
+ for (char ch = responseHeaders.get(); responseHeaders.good(); ch = responseHeaders.get()) {
+ if (ch == ':') {
+ current = &value;
+ for (char space = responseHeaders.get(); responseHeaders.good() && responseHeaders.peek() == ' '; space = responseHeaders.get()); // skip spaces
+ } else if (ch == '\n') {
+ if (name.tellp() > 0 && current == &value) {
+ heathers.push_back(name.str());
+ heathers.push_back(value.str());
+ } else if (name.tellp() > 0 && current == &value) {
+ // TODO: usually "HTTP/1.1 200 OK" → extract HTTP version and message?
+ }
+
+ name = std::stringstream();
+ value = std::stringstream();
+ current = &name;
+ } else if (ch == '\r') {
+ // ignore
+ } else {
+ current->put(ch);
+ }
+ }
+ return heathers;
}
};
@@ -61,17 +85,26 @@
curl_easy_setopt(impl->curl, CURLOPT_URL, request.url.c_str());
- curl_easy_setopt(impl->curl, CURLOPT_WRITEDATA, impl);
- curl_easy_setopt(impl->curl, CURLOPT_WRITEFUNCTION, HTTPClientImpl::curlWriteCallback);
+ typedef size_t(*CurlWriteCallback)(char*, size_t, size_t, HTTPClient::HTTPClientImpl*);
- // curl_easy_setopt(curl, CURLOPT_HEADERDATA, this);
- // curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, headersCurlCallback);
+ curl_easy_setopt(impl->curl, CURLOPT_WRITEDATA, impl);
+ curl_easy_setopt(impl->curl, CURLOPT_WRITEFUNCTION, (CurlWriteCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl)->size_t {
+ size_t r = size * nmemb;
+ impl->responseBody.write(buffer, r);
+ return r;
+ });
+
+ curl_easy_setopt(impl->curl, CURLOPT_HEADERDATA, impl);
+ curl_easy_setopt(impl->curl, CURLOPT_HEADERFUNCTION, (CurlWriteCallback)[](char* buffer, size_t size, size_t nmemb, HTTPClient::HTTPClientImpl * impl)->size_t {
+ size_t r = size * nmemb;
+ impl->responseHeaders.write(buffer, r);
+ return r;
+ });
curl_easy_perform(impl->curl);
curl_easy_getinfo(impl->curl, CURLINFO_RESPONSE_CODE, &response.responseCode);
- response.success = response.responseCode >= 200 && response.responseCode <= 299;
-
+ response.headers = impl->getResponseHeaders();
response.body = impl->responseBody.str();
impl->responseBody = std::stringstream();