diff --git a/boost/network/protocol/http/client/connection/async_normal.hpp b/boost/network/protocol/http/client/connection/async_normal.hpp index d2fb59e0b..98e2b5b0c 100644 --- a/boost/network/protocol/http/client/connection/async_normal.hpp +++ b/boost/network/protocol/http/client/connection/async_normal.hpp @@ -354,7 +354,10 @@ namespace boost { namespace network { namespace http { namespace impl { this->part.begin() , bytes_transferred ); - this->body_promise.set_value(body_string); + if (this->is_chunk_encoding) + this->body_promise.set_value(parse_chunk_encoding(body_string)); + else + this->body_promise.set_value(body_string); } // TODO set the destination value somewhere! this->destination_promise.set_value(""); @@ -428,6 +431,34 @@ namespace boost { namespace network { namespace http { namespace impl { } } } + + string_type parse_chunk_encoding( string_type & body_string ) { + string_type body; + string_type crlf = "\r\n"; + + typename string_type::iterator begin = body_string.begin(); + for (typename string_type::iterator iter = + std::search(begin, body_string.end(), crlf.begin(), crlf.end()); + iter != body_string.end(); + iter = std::search(begin, body_string.end(), crlf.begin(), crlf.end())) { + string_type line(begin, iter); + if (line.empty()) + break; + std::stringstream stream(line); + int len; + stream >> std::hex >> len; + std::advance(iter, 2); + if (!len) + break; + if (len <= body_string.end() - iter) { + body.insert(body.end(), iter, iter + len); + std::advance(iter, len); + } + begin = iter; + } + + return body; + } bool follow_redirect_; resolver_type & resolver_; 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 f0368c0e1..9921f7b8c 100644 --- a/boost/network/protocol/http/client/connection/async_protocol_handler.hpp +++ b/boost/network/protocol/http/client/connection/async_protocol_handler.hpp @@ -286,6 +286,11 @@ namespace boost { namespace network { namespace http { namespace impl { trim(header_pair.second); headers.insert(header_pair); } + // determine if the body parser will need to handle chunked encoding + typename headers_range >::type transfer_encoding_range = + headers.equal_range("Transfer-Encoding"); + is_chunk_encoding = !empty(transfer_encoding_range) + && boost::iequals(boost::begin(transfer_encoding_range)->second, "chunked"); headers_promise.set_value(headers); } @@ -373,6 +378,7 @@ namespace boost { namespace network { namespace http { namespace impl { buffer_type part; typename buffer_type::const_iterator part_begin; string_type partial_parsed; + bool is_chunk_encoding; };