Skip to content

Commit 30be91d

Browse files
committed
Refactor chunked encoding body parsing.
1 parent c6c1607 commit 30be91d

File tree

3 files changed

+39
-29
lines changed

3 files changed

+39
-29
lines changed

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

+32-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,10 @@ namespace boost { namespace network { namespace http { namespace impl {
354354
this->part.begin()
355355
, bytes_transferred
356356
);
357-
this->body_promise.set_value(body_string);
357+
if (this->is_chunk_encoding)
358+
this->body_promise.set_value(parse_chunk_encoding(body_string));
359+
else
360+
this->body_promise.set_value(body_string);
358361
}
359362
// TODO set the destination value somewhere!
360363
this->destination_promise.set_value("");
@@ -428,6 +431,34 @@ namespace boost { namespace network { namespace http { namespace impl {
428431
}
429432
}
430433
}
434+
435+
string_type parse_chunk_encoding( string_type & body_string ) {
436+
string_type body;
437+
string_type crlf = "\r\n";
438+
439+
typename string_type::iterator begin = body_string.begin();
440+
for (typename string_type::iterator iter =
441+
std::search(begin, body_string.end(), crlf.begin(), crlf.end());
442+
iter != body_string.end();
443+
iter = std::search(begin, body_string.end(), crlf.begin(), crlf.end())) {
444+
string_type line(begin, iter);
445+
if (line.empty())
446+
break;
447+
std::stringstream stream(line);
448+
int len;
449+
stream >> std::hex >> len;
450+
std::advance(iter, 2);
451+
if (!len)
452+
break;
453+
if (len <= body_string.end() - iter) {
454+
body.insert(body.end(), iter, iter + len);
455+
std::advance(iter, len);
456+
}
457+
begin = iter;
458+
}
459+
460+
return body;
461+
}
431462

432463
bool follow_redirect_;
433464
resolver_type & resolver_;

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

+6
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,11 @@ namespace boost { namespace network { namespace http { namespace impl {
286286
trim(header_pair.second);
287287
headers.insert(header_pair);
288288
}
289+
// determine if the body parser will need to handle chunked encoding
290+
typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
291+
headers.equal_range("Transfer-Encoding");
292+
is_chunk_encoding = !empty(transfer_encoding_range)
293+
&& boost::iequals(boost::begin(transfer_encoding_range)->second, "chunked");
289294
headers_promise.set_value(headers);
290295
}
291296

@@ -373,6 +378,7 @@ namespace boost { namespace network { namespace http { namespace impl {
373378
buffer_type part;
374379
typename buffer_type::const_iterator part_begin;
375380
string_type partial_parsed;
381+
bool is_chunk_encoding;
376382
};
377383

378384

boost/network/protocol/http/message/async_message.hpp

+1-28
Original file line numberDiff line numberDiff line change
@@ -118,34 +118,7 @@ namespace boost { namespace network { namespace http {
118118
}
119119

120120
string_type const body() const {
121-
string_type body;
122-
string_type partial_parsed = body_.get();
123-
124-
typename headers_range<basic_response<Tag> >::type transfer_encoding_range = headers().equal_range("Transfer-Encoding");
125-
if (!empty(transfer_encoding_range) && boost::iequals(boost::begin(transfer_encoding_range)->second, "chunked")) {
126-
typename string_type::iterator begin = partial_parsed.begin();
127-
string_type crlf = "\r\n";
128-
for (typename string_type::iterator iter = std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end());
129-
iter != partial_parsed.end();
130-
iter = std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end())) {
131-
string_type line(begin, iter);
132-
if (line.empty()) break;
133-
std::stringstream stream(line);
134-
int len;
135-
stream >> std::hex >> len;
136-
iter += 2;
137-
if (!len) break;
138-
if (len <= partial_parsed.end() - iter) {
139-
body.insert(body.end(), iter, iter + len);
140-
iter += len;
141-
}
142-
begin = iter;
143-
}
144-
} else {
145-
std::swap(body, partial_parsed);
146-
}
147-
148-
return body;
121+
return body_.get();
149122
}
150123

151124
void body(boost::shared_future<string_type> const & future) const {

0 commit comments

Comments
 (0)