@@ -246,6 +246,10 @@ struct http_async_protocol_handler {
246246 response_parser_type::http_header_line_done);
247247typename headers_container<Tag>::type headers;
248248 std::pair<string_type, string_type> header_pair;
249+ // init params
250+ is_content_length =false ;
251+ content_length = -1 ;
252+ is_chunk_end =false ;
249253while (!boost::empty (input_range)) {
250254std::tie (parsed_ok, result_range) = headers_parser.parse_until (
251255 response_parser_type::http_header_colon, input_range);
@@ -266,6 +270,10 @@ struct http_async_protocol_handler {
266270 }
267271trim (header_pair.second );
268272 headers.insert (header_pair);
273+ if (boost::iequals (header_pair.first ," Content-Length" )) {
274+ is_content_length =true ;
275+ content_length =std::stoi (header_pair.second );
276+ }
269277 }
270278// determine if the body parser will need to handle chunked encoding
271279typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
@@ -325,6 +333,49 @@ struct http_async_protocol_handler {
325333 parsed_ok,std::distance (std::end (result_range), part_end));
326334 }
327335
336+ inline bool check_parse_body_complete ()const {
337+ if (this ->is_chunk_encoding ) {
338+ return parse_chunk_encoding_complete ();
339+ }
340+ if (this ->is_content_length &&this ->content_length >=0 ) {
341+ return parse_content_length_complete ();
342+ }
343+ return false ;
344+ }
345+
346+ inline bool parse_content_length_complete ()const {
347+ return this ->partial_parsed .length () >=this -> content_length;
348+ }
349+
350+ bool parse_chunk_encoding_complete ()const {
351+ string_type body;
352+ string_type crlf =" \r\n " ;
353+
354+ typename string_type::const_iterator begin = partial_parsed.begin ();
355+ for (typename string_type::const_iterator iter =
356+ std::search (begin, partial_parsed.end (), crlf.begin (), crlf.end ());
357+ iter != partial_parsed.end ();
358+ iter =
359+ std::search (begin, partial_parsed.end (), crlf.begin (), crlf.end ())) {
360+ string_typeline (begin, iter);
361+ if (line.empty ()) {
362+ std::advance (iter,2 );
363+ begin = iter;
364+ continue ;
365+ }
366+ std::stringstreamstream (line);
367+ int len;
368+ stream >> std::hex >> len;
369+ std::advance (iter,2 );
370+ if (!len)return true ;
371+ if (len <= partial_parsed.end () - iter) {
372+ std::advance (iter, len +2 );
373+ }
374+ begin = iter;
375+ }
376+ return false ;
377+ }
378+
328379template <class Delegate ,class Callback >
329380void parse_body (Delegate& delegate_, Callback callback,size_t bytes) {
330381// TODO(dberris): we should really not use a string for the partial body
@@ -333,8 +384,12 @@ struct http_async_protocol_handler {
333384std::advance (it, bytes);
334385 partial_parsed.append (part_begin, it);
335386 part_begin = part.begin ();
336- delegate_->read_some (
337- boost::asio::mutable_buffers_1 (part.data (), part.size ()), callback);
387+ if (check_parse_body_complete ()) {
388+ callback (boost::asio::error::eof, bytes);
389+ }else {
390+ delegate_->read_some (
391+ boost::asio::mutable_buffers_1 (part.data (), part.size ()), callback);
392+ }
338393 }
339394
340395typedef response_parser<Tag> response_parser_type;
@@ -353,6 +408,9 @@ struct http_async_protocol_handler {
353408typename buffer_type::const_iterator part_begin;
354409 string_type partial_parsed;
355410bool is_chunk_encoding;
411+ bool is_chunk_end;
412+ bool is_content_length;
413+ std::size_t content_length;
356414};
357415
358416}// namespace impl