I am trying to parse HTTPS response using boost::beast::http::parser.
My parser is defined like this:
boost::beast::http::parser<false, boost::beast::http::string_body> response_parser;
And the callback for async read is like this:
void AsyncHttpsRequest::on_response_read(const boost::system::error_code &error_code, uint32_t bytes_transferred)
{
if (bytes_transferred > 0)
{
response_parser.put(boost::asio::buffer(data_buffer, bytes_transferred), http_error_code);
std::cout << "Parser status: " << http_error_code.message() << std::endl;
std::cout << "Read " << bytes_transferred << " bytes of HTTPS response" << std::endl;
std::cout << std::string(data_buffer, bytes_transferred) << std::endl;
}
if (error_code)
{
std::cout << "Error during HTTPS response read: " << error_code.message() << std::endl;
callback(error_code, response_parser.get());
}
else
{
if (response_parser.is_done())
{
callback(error_code, response_parser.get());
}
else
{
std::cout << "Response is not yet finished, reading more" << std::endl;
read_response();
}
}
}
Everything works fine when response has no body, response_parser.is_done() returns true. But when response contains a body it always returns false even if body is fully read. Response also has a Content-Length header which matches the number of bytes in the body, so there is no problem.
Boost docs say that response_parser.is_done() should return true if The semantics of the message indicate a body is expected, and the entire body was parsed.
When I send a request using Connection: keep-alive I am stuck on reading response, because server has nothing left to send and response_parser is not yet done. When I use Connection: close my finish callback is invoked, but boost::beast::http::message parsed has no body inside. However my logging into stdout shows that there is body and it is fully read.
What do I need to do to make boost::beast::http::parser recognize body end and return true on is_done() when the number of bytes read from the body becomes equal to Content-Length?