Skip to content

Commit 5d60c95

Browse files
committed
Fixing some bugs that deal with temporaries and copies.
1 parent de77ae6 commit 5d60c95

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

boost/network/protocol/http/impl/http_async_connection.hpp

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,14 @@ namespace boost { namespace network { namespace http { namespace impl {
131131

132132
this->method = method;
133133

134-
resolve_(resolver_, host(request), port(request),
134+
boost::uint16_t port_ = port(request);
135+
136+
resolve_(resolver_, host(request), port_,
135137
request_strand_->wrap(
136138
boost::bind(
137139
&http_async_connection<Tag,version_major,version_minor>::handle_resolved,
138140
http_async_connection<Tag,version_major,version_minor>::shared_from_this(),
139-
port(request),
141+
port_,
140142
_1, _2)));
141143
return temp;
142144
}
@@ -335,7 +337,7 @@ namespace boost { namespace network { namespace http { namespace impl {
335337
}
336338

337339
void handle_received_status(boost::system::error_code const & ec, size_t bytes_transferred) {
338-
if (!ec) {
340+
if (!ec || ec == boost::asio::error::eof) {
339341
this->parse_status();
340342
} else {
341343
boost::system::system_error error(ec);
@@ -384,7 +386,7 @@ namespace boost { namespace network { namespace http { namespace impl {
384386
}
385387

386388
void handle_received_status_message(boost::system::error_code const & ec, size_t bytes_transferred) {
387-
if (!ec) {
389+
if (!ec || ec == boost::asio::error::eof) {
388390
this->parse_status_message();
389391
} else {
390392
boost::system::system_error error(ec);
@@ -396,6 +398,43 @@ namespace boost { namespace network { namespace http { namespace impl {
396398
}
397399
}
398400

401+
void parse_headers_real(string_type & headers_part) {
402+
typename boost::iterator_range<typename string_type::const_iterator>
403+
input_range = boost::make_iterator_range(headers_part)
404+
, result_range;
405+
logic::tribool parsed_ok;
406+
response_parser_type headers_parser(response_parser_type::http_header_line_done);
407+
typename headers_container<Tag>::type headers;
408+
std::pair<string_type,string_type> header_pair;
409+
while (!boost::empty(input_range)) {
410+
fusion::tie(parsed_ok, result_range) = headers_parser.parse_until(
411+
response_parser_type::http_header_colon
412+
, input_range);
413+
if (headers_parser.state() != response_parser_type::http_header_colon) break;
414+
header_pair.first = string_type(
415+
boost::begin(result_range),
416+
boost::end(result_range));
417+
input_range.advance_begin(boost::distance(result_range));
418+
fusion::tie(parsed_ok, result_range) = headers_parser.parse_until(
419+
response_parser_type::http_header_line_done
420+
, input_range);
421+
header_pair.second = string_type(
422+
boost::begin(result_range),
423+
boost::end(result_range));
424+
input_range.advance_begin(boost::distance(result_range));
425+
426+
trim(header_pair.first);
427+
if (header_pair.first.size() > 1) {
428+
header_pair.first.erase(
429+
header_pair.first.size() - 1
430+
);
431+
}
432+
trim(header_pair.second);
433+
headers.insert(header_pair);
434+
}
435+
headers_promise.set_value(headers);
436+
}
437+
399438
void parse_headers() {
400439
logic::tribool parsed_ok;
401440
typename boost::iterator_range<typename buffer_type::const_iterator> result_range;
@@ -408,6 +447,7 @@ namespace boost { namespace network { namespace http { namespace impl {
408447
headers_string.append(boost::begin(result_range), boost::end(result_range));
409448
typename buffer_type::const_iterator end = part.end();
410449
std::copy(boost::end(result_range), end, part.begin());
450+
this->parse_headers_real(headers_string);
411451
this->parse_body(std::distance(boost::end(result_range), end));
412452
} else if (parsed_ok == false) {
413453
std::runtime_error error("Invalid header part.");
@@ -425,7 +465,7 @@ namespace boost { namespace network { namespace http { namespace impl {
425465
}
426466

427467
void handle_received_headers(boost::system::error_code const & ec, size_t bytes_transferred) {
428-
if (!ec) {
468+
if (!ec || ec == boost::asio::error::eof) {
429469
this->parse_headers();
430470
} else {
431471
boost::system::system_error error(ec);

libs/network/example/http_client.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,22 @@
1111
*/
1212
#include <boost/program_options.hpp>
1313
#include <boost/network/protocol/http.hpp>
14+
#include <boost/function_output_iterator.hpp>
1415
#include <string>
1516
#include <iostream>
1617

1718
namespace po = boost::program_options;
1819
using namespace std;
1920

21+
struct header_printer {
22+
std::ostream & os;
23+
header_printer(std::ostream & os_) : os(os_) {}
24+
template <class Pair>
25+
void operator()(Pair const & p) {
26+
os << p.first << ": " << p.second << endl;
27+
}
28+
};
29+
2030
int main(int argc, char * argv[]) {
2131
po::options_description options("Allowed options");
2232
string output_filename, source;
@@ -66,14 +76,9 @@ int main(int argc, char * argv[]) {
6676
http_client::response response = client.get(request);
6777

6878
if (show_headers) {
69-
headers_range<http_client::response>::type headers_ = headers(response);
70-
boost::range_iterator<headers_range<http_client::response>::type>::type header, past_end;
71-
header = boost::begin(headers_);
72-
past_end = boost::end(headers_);
73-
while (header != past_end) {
74-
cout << header->first << ": " << header->second << endl;
75-
++header;
76-
};
79+
headers_range<http_client::response>::type headers_ = response.headers();
80+
std::copy(headers_.begin(), headers_.end(),
81+
boost::make_function_output_iterator(header_printer(cout)));
7782
cout << endl;
7883
};
7984

0 commit comments

Comments
 (0)