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

Lines changed: 32 additions & 1 deletion
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 1 addition & 28 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy