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
std::string::size_type position = ssl_read_packet.find("\r\n\r\n");
if (position == std::string::npos)
std::string::size_type end_of_headers = ssl_read_packet.find("\r\n\r\n");
if (end_of_headers == std::string::npos)
throw std::runtime_error("invalid reply, end of headers not found");
const std::string response = ssl_read_packet.substr(0, position);
const std::string response = ssl_read_packet.substr(0, end_of_headers);
auto status_pos = response.find("\r\n");
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
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
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);
@@ -143,17 +154,22 @@ std::string HttpClient::inetAddress(const std::string &hostname) {
}
int HttpClient::sslRecvPacket() {
ssl_read_packet.resize(4096);
ssl_read_packet.clear();
int buf_len = 16384;
unsigned char buf[buf_len + 1];
int len = 16384;
char buf[len + 1];
memset(buf, 0, sizeof(buf));
int len = 0;
int read_bytes = 0;
do {
len = SSL_read(ssl, buf, len);
if (len >= 0) {
buf[len] = 0;
ssl_read_packet.append((const char *) buf);
memset(buf, 0, sizeof(buf));
len = SSL_read(ssl, buf, buf_len);
if (len > 0) {
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);
@@ -167,7 +183,7 @@ int HttpClient::sslRecvPacket() {
return -1;
}
return (int) ssl_read_packet.length();
return read_bytes;
}
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
ssl_read_packet.clear();
return sslRecvPacket();
}