Skip to content

Commit 4fc7dda

Browse files
committed
remove buffer copy
1 parent bdf1b22 commit 4fc7dda

File tree

2 files changed

+66
-83
lines changed

2 files changed

+66
-83
lines changed

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

Lines changed: 19 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -367,21 +367,14 @@ struct http_async_connection
367367
this->part_begin;
368368
typename protocol_base::buffer_type::const_iterator end = begin;
369369
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(
377-
delegate_,
378-
request_strand_.wrap([=] (boost::system::error_code const &ec,
379-
std::size_t bytes_transferred) {
380-
self->handle_received_data(body, get_body, callback,
381-
ec, bytes_transferred);
382-
}),
383-
remainder);
384-
}
370+
this->parse_body(
371+
delegate_,
372+
request_strand_.wrap([=] (boost::system::error_code const &ec,
373+
std::size_t bytes_transferred) {
374+
self->handle_received_data(body, get_body, callback,
375+
ec, bytes_transferred);
376+
}),
377+
remainder);
385378
}
386379
return;
387380
case body:
@@ -439,25 +432,17 @@ struct http_async_connection
439432
ec, bytes_transferred);
440433
}));
441434
} 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(
453-
delegate_,
454-
request_strand_.wrap([=] (boost::system::error_code const &ec,
455-
std::size_t bytes_transferred) {
456-
self->handle_received_data(body, get_body, callback,
457-
ec, bytes_transferred);
458-
}),
459-
bytes_transferred);
460-
}
435+
// Here we don't have a body callback. Let's make sure that we
436+
// deal with the remainder from the headers part in case we do
437+
// have data that's still in the buffer.
438+
this->parse_body(
439+
delegate_,
440+
request_strand_.wrap([=] (boost::system::error_code const &ec,
441+
std::size_t bytes_transferred) {
442+
self->handle_received_data(body, get_body, callback,
443+
ec, bytes_transferred);
444+
}),
445+
bytes_transferred);
461446
}
462447
}
463448
return;
@@ -495,50 +480,6 @@ struct http_async_connection
495480
}
496481
}
497482

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-
542483
string_type parse_chunk_encoding(string_type& body_string) {
543484
string_type body;
544485
string_type crlf = "\r\n";

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

Lines changed: 47 additions & 5 deletions
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)