Skip to content

Commit 1277fa6

Browse files
authored
Merge pull request #719 from chenzhaoyu/add-active-client-side-close-0.13-release
add client side close for 0.13-release
2 parents c138247 + 0e91891 commit 1277fa6

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

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

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ struct http_async_protocol_handler {
246246
response_parser_type::http_header_line_done);
247247
typename headers_container<Tag>::type headers;
248248
std::pair<string_type, string_type> header_pair;
249+
//init params
250+
is_content_length = false;
251+
content_length = -1;
252+
is_chunk_end = false;
249253
while (!boost::empty(input_range)) {
250254
std::tie(parsed_ok, result_range) = headers_parser.parse_until(
251255
response_parser_type::http_header_colon, input_range);
@@ -266,6 +270,16 @@ struct http_async_protocol_handler {
266270
}
267271
trim(header_pair.second);
268272
headers.insert(header_pair);
273+
if (!is_content_length &&
274+
boost::iequals(header_pair.first, "Content-Length")) {
275+
try {
276+
content_length = std::stoll(header_pair.second);
277+
is_content_length = true;
278+
}
279+
catch (std::exception&) {
280+
//is_content_length = false;
281+
}
282+
}
269283
}
270284
// determine if the body parser will need to handle chunked encoding
271285
typename headers_range<basic_response<Tag> >::type transfer_encoding_range =
@@ -325,6 +339,49 @@ struct http_async_protocol_handler {
325339
parsed_ok, std::distance(std::end(result_range), part_end));
326340
}
327341

342+
inline bool check_parse_body_complete() const {
343+
if (this->is_chunk_encoding) {
344+
return parse_chunk_encoding_complete();
345+
}
346+
if (this->is_content_length && this->content_length >= 0) {
347+
return parse_content_length_complete();
348+
}
349+
return false;
350+
}
351+
352+
inline bool parse_content_length_complete() const {
353+
return this->partial_parsed.length() >= this-> content_length;
354+
}
355+
356+
bool parse_chunk_encoding_complete() const {
357+
string_type body;
358+
string_type crlf = "\r\n";
359+
360+
typename string_type::const_iterator begin = partial_parsed.begin();
361+
for (typename string_type::const_iterator iter =
362+
std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end());
363+
iter != partial_parsed.end();
364+
iter =
365+
std::search(begin, partial_parsed.end(), crlf.begin(), crlf.end())) {
366+
string_type line(begin, iter);
367+
if (line.empty()) {
368+
std::advance(iter, 2);
369+
begin = iter;
370+
continue;
371+
}
372+
std::stringstream stream(line);
373+
int len;
374+
stream >> std::hex >> len;
375+
std::advance(iter, 2);
376+
if (!len) return true;
377+
if (len <= partial_parsed.end() - iter) {
378+
std::advance(iter, len + 2);
379+
}
380+
begin = iter;
381+
}
382+
return false;
383+
}
384+
328385
template <class Delegate, class Callback>
329386
void parse_body(Delegate& delegate_, Callback callback, size_t bytes) {
330387
// TODO(dberris): we should really not use a string for the partial body
@@ -333,8 +390,12 @@ struct http_async_protocol_handler {
333390
std::advance(it, bytes);
334391
partial_parsed.append(part_begin, it);
335392
part_begin = part.begin();
336-
delegate_->read_some(
337-
boost::asio::mutable_buffers_1(part.data(), part.size()), callback);
393+
if (check_parse_body_complete()) {
394+
callback(boost::asio::error::eof, bytes);
395+
} else {
396+
delegate_->read_some(
397+
boost::asio::mutable_buffers_1(part.data(), part.size()), callback);
398+
}
338399
}
339400

340401
typedef response_parser<Tag> response_parser_type;
@@ -353,6 +414,9 @@ struct http_async_protocol_handler {
353414
typename buffer_type::const_iterator part_begin;
354415
string_type partial_parsed;
355416
bool is_chunk_encoding;
417+
bool is_chunk_end;
418+
bool is_content_length;
419+
long long content_length;
356420
};
357421

358422
} // namespace impl

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