@@ -363,14 +363,25 @@ struct http_async_connection
363363// Here we handle the body data ourself and append to an
364364// ever-growing string buffer.
365365auto self =this ->shared_from_this ();
366- this ->parse_body (
366+ typename protocol_base::buffer_type::const_iterator begin =
367+ this ->part_begin ;
368+ typename protocol_base::buffer_type::const_iterator end = begin;
369+ std::advance (end, remainder);
370+ string_typebody_string (begin, end);
371+ if (check_parse_body_complete (body_string)) {
372+ this ->append_body (remainder);
373+ handle_received_data (body, get_body, callback,
374+ boost::asio::error::eof, bytes_transferred);
375+ }else {
376+ this ->parse_body (
367377 delegate_,
368378 request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
369379 std::size_t bytes_transferred) {
370380 self->handle_received_data (body, get_body, callback,
371381 ec, bytes_transferred);
372382 }),
373383 remainder);
384+ }
374385 }
375386return ;
376387case body:
@@ -428,17 +439,25 @@ struct http_async_connection
428439 ec, bytes_transferred);
429440 }));
430441 }else {
431- // Here we don't have a body callback. Let's make sure that we
432- // deal with the remainder from the headers part in case we do
433- // have data that's still in the buffer.
434- this ->parse_body (
442+ string_typebody_string (this ->partial_parsed );
443+ body_string.append (this ->part .begin (), bytes_transferred);
444+ if (check_parse_body_complete (body_string)) {
445+ this ->append_body (bytes_transferred);
446+ handle_received_data (body, get_body, callback,
447+ boost::asio::error::eof, bytes_transferred);
448+ }else {
449+ // Here we don't have a body callback. Let's make sure that we
450+ // deal with the remainder from the headers part in case we do
451+ // have data that's still in the buffer.
452+ this ->parse_body (
435453 delegate_,
436454 request_strand_.wrap ([=] (boost::system::error_codeconst &ec,
437455 std::size_t bytes_transferred) {
438456 self->handle_received_data (body, get_body, callback,
439457 ec, bytes_transferred);
440458 }),
441459 bytes_transferred);
460+ }
442461 }
443462 }
444463return ;
@@ -476,6 +495,50 @@ struct http_async_connection
476495 }
477496 }
478497
498+ inline bool check_parse_body_complete (string_type& body_string)
499+ {
500+ if (this ->is_chunk_encoding ) {
501+ return parse_chunk_encoding_complete (body_string);
502+ }
503+ if (this ->is_content_length &&this ->content_length >=0 ) {
504+ return parse_content_length_complete (body_string,this ->content_length );
505+ }
506+ return false ;
507+ }
508+
509+ inline bool parse_content_length_complete (string_type& body_string,size_t content_length){
510+ return body_string.length () >= content_length;
511+ }
512+
513+ bool parse_chunk_encoding_complete (string_type& body_string) {
514+ string_type body;
515+ string_type crlf =" \r\n " ;
516+
517+ typename string_type::iterator begin = body_string.begin ();
518+ for (typename string_type::iterator iter =
519+ std::search (begin, body_string.end (), crlf.begin (), crlf.end ());
520+ iter != body_string.end ();
521+ iter =
522+ std::search (begin, body_string.end (), crlf.begin (), crlf.end ())) {
523+ string_typeline (begin, iter);
524+ if (line.empty ()) {
525+ std::advance (iter,2 );
526+ begin = iter;
527+ continue ;
528+ }
529+ std::stringstreamstream (line);
530+ int len;
531+ stream >> std::hex >> len;
532+ std::advance (iter,2 );
533+ if (!len)return true ;
534+ if (len <= body_string.end () - iter) {
535+ std::advance (iter, len +2 );
536+ }
537+ begin = iter;
538+ }
539+ return false ;
540+ }
541+
479542 string_typeparse_chunk_encoding (string_type& body_string) {
480543 string_type body;
481544 string_type crlf =" \r\n " ;