handle content-length header

This commit is contained in:
vaclavt
2022-03-06 19:55:54 +01:00
parent 9966c961d1
commit 45fcabe4b4

View File

@@ -37,12 +37,11 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
} }
// get headers // get headers
std::string::size_type position = ssl_read_packet.find("\r\n\r\n"); std::string::size_type end_of_headers = ssl_read_packet.find("\r\n\r\n");
if (position == std::string::npos) if (end_of_headers == std::string::npos)
throw std::runtime_error("invalid reply, end of headers not found"); throw std::runtime_error("invalid reply, end of headers not found");
const std::string response = ssl_read_packet.substr(0, end_of_headers);
const std::string response = ssl_read_packet.substr(0, position);
auto status_pos = response.find("\r\n"); auto status_pos = response.find("\r\n");
const std::string response_headers = response.substr(status_pos + 2, response.length() - 2 - status_pos); const std::string response_headers = response.substr(status_pos + 2, response.length() - 2 - status_pos);
@@ -54,8 +53,20 @@ std::pair<int, std::string> HttpClient::doRequest(const std::string &method, con
// parse headers // parse headers
responseHeaders(response_headers); responseHeaders(response_headers);
// get content length if given
int content_len = 0;
auto cl_it = headers_map.find("Content-Length");
if (cl_it != headers_map.end()) {
content_len = std::stoi(cl_it->second);
}
// and fetch the rest if not read completely
while (content_len > 0 && content_len > ssl_read_packet.length() - 4 - end_of_headers) {
auto read_bytes = sslRecvPacket();
}
// get body // get body
const std::string body = ssl_read_packet.substr(position + 4, ssl_read_packet.length() - 4 - position); const std::string body = ssl_read_packet.substr(end_of_headers + 4, ssl_read_packet.length() - 4 - end_of_headers);
return std::make_pair(resp_status, body); return std::make_pair(resp_status, body);
@@ -143,17 +154,22 @@ std::string HttpClient::inetAddress(const std::string &hostname) {
} }
int HttpClient::sslRecvPacket() { int HttpClient::sslRecvPacket() {
ssl_read_packet.resize(4096); int buf_len = 16384;
ssl_read_packet.clear(); unsigned char buf[buf_len + 1];
int len = 16384; int len = 0;
char buf[len + 1]; int read_bytes = 0;
memset(buf, 0, sizeof(buf));
do { do {
len = SSL_read(ssl, buf, len); memset(buf, 0, sizeof(buf));
if (len >= 0) { len = SSL_read(ssl, buf, buf_len);
buf[len] = 0; if (len > 0) {
ssl_read_packet.append((const char *) buf); read_bytes += len;
buf[len] = 0; // actually redundant
std::vector<unsigned char> data(buf, buf + len);
std::string chunk(data.begin(), data.end());
ssl_read_packet.append(chunk);
} }
} while (len > 0); } while (len > 0);
@@ -167,7 +183,7 @@ int HttpClient::sslRecvPacket() {
return -1; return -1;
} }
return (int) ssl_read_packet.length(); return read_bytes;
} }
int HttpClient::sslSendPacket(const std::string &buf) { int HttpClient::sslSendPacket(const std::string &buf) {
@@ -252,6 +268,7 @@ int HttpClient::sslRequest(const std::string &server_name, const std::string &re
} }
// read response and return its length // read response and return its length
ssl_read_packet.clear();
return sslRecvPacket(); return sslRecvPacket();
} }