Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit01140d2

Browse files
committed
Fixing HTTP 1.1 pipelining support implementation, so it does not fail when it tries to re-use a connection when the server gives up.
1 parent0aed5d1 commit01140d2

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

‎boost/network/protocol/http/impl/sync_connection_base.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ namespace boost { namespace network { namespace http { namespace impl {
224224

225225
voidclose_socket() {
226226
if (is_open()) {
227+
socket_.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
227228
socket_.lowest_layer().close();
228229
}
229230
}
@@ -275,7 +276,7 @@ namespace boost { namespace network { namespace http { namespace impl {
275276

276277
boolis_open() {return socket_.is_open(); }
277278

278-
voidclose_socket() {if (is_open()) { socket_.close(); } }
279+
voidclose_socket() {if (is_open()) { socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both); socket_.close(); } }
279280

280281
private:
281282

‎boost/network/protocol/http/policies/pooled_connection.hpp

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace boost { namespace network { namespace http {
4040
, get_connection_(get_connection) {}
4141

4242
basic_response<Tag>send_request(string_typeconst & method, basic_request<Tag> request_,bool get_body) {
43-
returnsend_request_recursive(method, request_, get_body,0);
43+
returnsend_request_impl(method, request_, get_body);
4444
}
4545

4646
~connection_impl () {
@@ -49,50 +49,67 @@ namespace boost { namespace network { namespace http {
4949

5050
private:
5151

52-
basic_response<Tag>send_request_recursive(string_typeconst & method, basic_request<Tag> request_,bool get_body,int count) {
53-
if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT)
54-
throwstd::runtime_error("Redirection exceeds maximum redirect count.");
55-
56-
basic_response<Tag> response_;
57-
// check if the socket is open first
58-
if (!pimpl->is_open()) {
59-
pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
60-
}
61-
pimpl->send_request_impl(method, request_);
62-
response_ = basic_response<Tag>();
63-
response_ <<source(request_.host());
64-
65-
boost::asio::streambuf response_buffer;
66-
pimpl->read_status(response_, response_buffer);
67-
pimpl->read_headers(response_, response_buffer);
68-
if (
69-
get_body && response_.status() !=304
70-
&& (response_.status() !=204)
71-
&&not (response_.status() >=100 && response_.status() <=199)
72-
) {
73-
pimpl->read_body(response_, response_buffer);
74-
}
75-
76-
if (connection_follow_redirect_) {
77-
boost::uint16_t status = response_.status();
78-
if (status >=300 && status <=307) {
79-
typename headers_range<basic_response<Tag> >::type location_range =headers(response_)["Location"];
80-
typename range_iterator<typename headers_range<basic_request<Tag> >::type>::type location_header =begin(location_range);
81-
if (location_header !=end(location_range)) {
82-
request_.uri(location_header->second);
83-
connection_ptr connection_;
84-
connection_ =get_connection_(resolver_, request_);
85-
return connection_->send_request_recursive(method, request_, get_body, ++count);
86-
}elsethrowstd::runtime_error("Location header not defined in redirect response.");
52+
basic_response<Tag>send_request_impl(string_typeconst & method, basic_request<Tag> request_,bool get_body) {
53+
boost::uint8_t count =0;
54+
bool retry =false;
55+
do {
56+
if (count >= BOOST_NETWORK_HTTP_MAXIMUM_REDIRECT_COUNT)
57+
throwstd::runtime_error("Redirection exceeds maximum redirect count.");
58+
59+
basic_response<Tag> response_;
60+
// check if the socket is open first
61+
if (!pimpl->is_open()) {
62+
pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
63+
}
64+
response_ = basic_response<Tag>();
65+
response_ <<source(request_.host());
66+
67+
pimpl->send_request_impl(method, request_);
68+
boost::asio::streambuf response_buffer;
69+
70+
try {
71+
pimpl->read_status(response_, response_buffer);
72+
}catch (boost::system::system_error & e) {
73+
if (!retry && e.code() == boost::asio::error::eof) {
74+
retry =true;
75+
pimpl->init_socket(request_.host(), lexical_cast<string_type>(request_.port()));
76+
continue;
77+
}
78+
throw;// it's a retry, and there's something wrong.
79+
}
80+
81+
pimpl->read_headers(response_, response_buffer);
82+
83+
if (
84+
get_body && response_.status() !=304
85+
&& (response_.status() !=204)
86+
&&not (response_.status() >=100 && response_.status() <=199)
87+
) {
88+
pimpl->read_body(response_, response_buffer);
8789
}
88-
}
8990

90-
typename headers_range<basic_response<Tag> >::type connection_range =headers(response_)["Connection"];
91-
if (!empty(connection_range) &&begin(connection_range)->second ==string_type("close")) {
92-
pimpl->close_socket();
93-
}
91+
if (connection_follow_redirect_) {
92+
boost::uint16_t status = response_.status();
93+
if (status >=300 && status <=307) {
94+
typename headers_range<basic_response<Tag> >::type location_range =headers(response_)["Location"];
95+
typename range_iterator<typename headers_range<basic_request<Tag> >::type>::type location_header =begin(location_range);
96+
if (location_header !=end(location_range)) {
97+
request_.uri(location_header->second);
98+
connection_ptr connection_;
99+
connection_ =get_connection_(resolver_, request_);
100+
++count;
101+
continue;
102+
}elsethrowstd::runtime_error("Location header not defined in redirect response.");
103+
}
104+
}
105+
106+
typename headers_range<basic_response<Tag> >::type connection_range =headers(response_)["Connection"];
107+
if (!empty(connection_range) &&begin(connection_range)->second ==string_type("close")) {
108+
pimpl->close_socket();
109+
}
94110

95-
return response_;
111+
return response_;
112+
}while(true);
96113
}
97114

98115
shared_ptr<http::impl::sync_connection_base<Tag,version_major,version_minor> > pimpl;

‎libs/network/test/http_1_1_test.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(http_cached_resolve, T, tag_types) {
5858
http::basic_client<T,1,1>client_(http::basic_client<T,1,1>::cache_resolved);
5959
http::basic_response<T> response_;
6060
BOOST_CHECK_NO_THROW ( response_ = client_.get(request) );
61-
BOOST_CHECK_NO_THROW ( response_ = client_.get(other_request) );
61+
//BOOST_CHECK_NO_THROW ( response_ = client_.get(other_request) );
62+
response_ = client_.get(other_request);
6263
}
6364

6465
BOOST_AUTO_TEST_CASE_TEMPLATE(http_redirection_test, T, tag_types) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp