From 45fcabe4b4911be22708757752b5ceb22c73b1dd Mon Sep 17 00:00:00 2001 From: vaclavt Date: Sun, 6 Mar 2022 19:55:54 +0100 Subject: [PATCH] handle content-length header --- clib/sslclient.cpp | 49 +++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/clib/sslclient.cpp b/clib/sslclient.cpp index dc9f58e..787f816 100644 --- a/clib/sslclient.cpp +++ b/clib/sslclient.cpp @@ -37,12 +37,11 @@ std::pair 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 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 len = 16384; - char buf[len + 1]; - memset(buf, 0, sizeof(buf)); + int buf_len = 16384; + unsigned char buf[buf_len + 1]; + + 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 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(); }