Skip to content

Commit b950ea5

Browse files
committed
remove extra body buffer copy
1 parent bdf1b22 commit b950ea5

File tree

2 files changed

+52
-73
lines changed

2 files changed

+52
-73
lines changed

boost/network/protocol/http/client/connection/async_normal.hpp

+5-68
Original file line numberDiff line numberDiff line change
@@ -363,25 +363,14 @@ struct http_async_connection
363363
// Here we handle the body data ourself and append to an
364364
// ever-growing string buffer.
365365
auto self = this->shared_from_this();
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_type body_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(
366+
this->parse_body(
377367
delegate_,
378368
request_strand_.wrap([=] (boost::system::error_code const &ec,
379369
std::size_t bytes_transferred) {
380370
self->handle_received_data(body, get_body, callback,
381371
ec, bytes_transferred);
382372
}),
383373
remainder);
384-
}
385374
}
386375
return;
387376
case body:
@@ -439,25 +428,17 @@ struct http_async_connection
439428
ec, bytes_transferred);
440429
}));
441430
} else {
442-
string_type body_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(
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(
453435
delegate_,
454436
request_strand_.wrap([=] (boost::system::error_code const &ec,
455437
std::size_t bytes_transferred) {
456438
self->handle_received_data(body, get_body, callback,
457439
ec, bytes_transferred);
458440
}),
459441
bytes_transferred);
460-
}
461442
}
462443
}
463444
return;
@@ -495,50 +476,6 @@ struct http_async_connection
495476
}
496477
}
497478

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_type line(begin, iter);
524-
if (line.empty()) {
525-
std::advance(iter, 2);
526-
begin = iter;
527-
continue;
528-
}
529-
std::stringstream stream(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-
542479
string_type parse_chunk_encoding(string_type& body_string) {
543480
string_type body;
544481
string_type crlf = "\r\n";

boost/network/protocol/http/client/connection/async_protocol_handler.hpp

+47-5
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,47 @@ struct http_async_protocol_handler {
333333
parsed_ok, std::distance(std::end(result_range), part_end));
334334
}
335335

336-
void append_body(size_t bytes) {
337-
partial_parsed.append(part_begin, part_begin + bytes);
338-
part_begin = part.begin();
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_type line(begin, iter);
361+
if (line.empty()) {
362+
std::advance(iter, 2);
363+
begin = iter;
364+
continue;
365+
}
366+
std::stringstream stream(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;
339377
}
340378

341379
template <class Delegate, class Callback>
@@ -344,8 +382,12 @@ struct http_async_protocol_handler {
344382
// buffer.
345383
partial_parsed.append(part_begin, part_begin + bytes);
346384
part_begin = part.begin();
347-
delegate_->read_some(
348-
boost::asio::mutable_buffers_1(part.data(), part.size()), callback);
385+
if (check_parse_body_complete()) {
386+
callback(boost::asio::error::eof, bytes);
387+
} else {
388+
delegate_->read_some(
389+
boost::asio::mutable_buffers_1(part.data(), part.size()), callback);
390+
}
349391
}
350392

351393
typedef response_parser<Tag> response_parser_type;

0 commit comments

Comments
 (0)