diff --git a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp index a1cebc0e1..e6bdc426b 100644 --- a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp +++ b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -246,6 +246,10 @@ struct http_async_protocol_handler { response_parser_type::http_header_line_done); typename headers_container::type headers; std::pair header_pair; + //init params + is_content_length = false; + content_length = -1; + is_chunk_end = false; while (!boost::empty(input_range)) { std::tie(parsed_ok, result_range) = headers_parser.parse_until( response_parser_type::http_header_colon, input_range); @@ -266,6 +270,16 @@ struct http_async_protocol_handler { } trim(header_pair.second); headers.insert(header_pair); + if (!is_content_length && + boost::iequals(header_pair.first, "Content-Length")) { + try { + content_length = std::stoll(header_pair.second); + is_content_length = true; + } + catch (std::exception&) { + //is_content_length = false; + } + } } // determine if the body parser will need to handle chunked encoding typename headers_range >::type transfer_encoding_range = @@ -325,6 +339,49 @@ struct http_async_protocol_handler { parsed_ok, std::distance(std::end(result_range), part_end)); } + inline bool check_parse_body_complete() const { + if (this->is_chunk_encoding) { + return parse_chunk_encoding_complete(); + } + if (this->is_content_length && this->content_length >= 0) { + return parse_content_length_complete(); + } + return false; + } + + inline bool parse_content_length_complete() const { + return this->partial_parsed.length() >= this-> content_length; + } + + bool parse_chunk_encoding_complete() const { + string_type body; + string_type crlf = "\r\n"; + + typename string_type::const_iterator begin = partial_parsed.begin(); + for (typename string_type::const_iterator iter = + std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end()); + iter != partial_parsed.end(); + iter = + std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end())) { + string_type line(begin, iter); + if (line.empty()) { + std::advance(iter, 2); + begin = iter; + continue; + } + std::stringstream stream(line); + int len; + stream >> std::hex >> len; + std::advance(iter, 2); + if (!len) return true; + if (len <= partial_parsed.end() - iter) { + std::advance(iter, len + 2); + } + begin = iter; + } + return false; + } + template void parse_body(Delegate& delegate_, Callback callback, size_t bytes) { // TODO(dberris): we should really not use a string for the partial body @@ -333,8 +390,12 @@ struct http_async_protocol_handler { std::advance(it, bytes); partial_parsed.append(part_begin, it); part_begin = part.begin(); - delegate_->read_some( - boost::asio::mutable_buffers_1(part.data(), part.size()), callback); + if (check_parse_body_complete()) { + callback(boost::asio::error::eof, bytes); + } else { + delegate_->read_some( + boost::asio::mutable_buffers_1(part.data(), part.size()), callback); + } } typedef response_parser response_parser_type; @@ -353,6 +414,9 @@ struct http_async_protocol_handler { typename buffer_type::const_iterator part_begin; string_type partial_parsed; bool is_chunk_encoding; + bool is_chunk_end; + bool is_content_length; + long long content_length; }; } // namespace impl pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy