src/HTTPClient.cpp
branchv_0
changeset 6 59c9ca066322
parent 5 165f6162524d
child 7 0b0374746e48
--- 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();