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

Commitb26c440

Browse files
committed
Squashed Asio SSL FUBAR Issue
So, this affects the HTTPS implementation in 0.9.3 as well, where Asiois not exactly being smart about how it deals with SSL errors. We'vehad to do some acrobatics just to determine whether the error codereturned by an operation performed on an SSL stream resulted in a shortread. The change is simple, but tracking it down is so much of a PITA.We probably should file a bug in Asio to be able to better detect thesituation with short reads on SSL streams, and somehow also file a bugfor it. At worst the short read should just use an asio::error::eof sothat it's not too hard to deal with this issue from the user side.Also, this commit has some header-fudging to reduce dependencies andincremental compile-times. A more extensive effort should be done toreduce dependencies across header-files library-wide.
1 parent7ff00ac commitb26c440

File tree

11 files changed

+121
-52
lines changed

11 files changed

+121
-52
lines changed

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,24 @@
99

1010
#include<boost/shared_ptr.hpp>
1111
#include<boost/scoped_ptr.hpp>
12-
#include<boost/asio/io_service.hpp>
13-
#include<boost/network/protocol/http/request.hpp>
14-
#include<boost/network/protocol/http/response.hpp>
1512
#include<boost/network/protocol/http/client/client_connection.hpp>
16-
#include<boost/network/protocol/http/client/connection/resolver_delegate.hpp>
17-
#include<boost/network/protocol/http/client/connection/connection_delegate.hpp>
13+
#include<boost/enable_shared_from_this.hpp>
14+
15+
namespaceboost {namespaceasio {
16+
17+
classio_service;
18+
19+
}// namespace asio
20+
21+
}// namespace boost
1822

1923
namespaceboost {namespacenetwork {namespacehttp {
2024

25+
structrequest;
26+
structresponse;
27+
structresolver_delegate;
28+
structconnection_delegate;
29+
2130
structhttp_async_connection_pimpl;
2231

2332
structhttp_async_connection : client_connection

‎boost/network/protocol/http/client/connection/async_normal.ipp‎

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@
1010
#include<boost/asio/placeholders.hpp>
1111
#include<boost/network/protocol/http/client/connection/async_normal.hpp>
1212
#include<boost/network/protocol/http/request.hpp>
13+
#include<boost/network/protocol/http/response.hpp>
14+
#include<boost/network/protocol/http/client/connection/connection_delegate.hpp>
15+
#include<boost/network/protocol/http/client/connection/resolver_delegate.hpp>
1316
#include<boost/network/protocol/http/algorithms/linearize.hpp>
1417
#include<boost/network/protocol/http/impl/access.hpp>
1518
#include<boost/asio/strand.hpp>
1619
#include<boost/network/detail/debug.hpp>
20+
#ifdef BOOST_NETWORK_ENABLE_HTTPS
21+
#include<boost/asio/ssl/error.hpp>
22+
#endif
1723

1824
namespaceboost {namespacenetwork {namespacehttp {
1925

@@ -59,8 +65,9 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
5965
BOOST_NETWORK_MESSAGE("method:" <<this->method);
6066
boost::uint16_t port_ =port(request);
6167
BOOST_NETWORK_MESSAGE("port:" << port_);
68+
this->host_ =host(request);
6269
resolver_delegate_->resolve(
63-
host(request),
70+
this->host_,
6471
port_,
6572
request_strand_.wrap(
6673
boost::bind(
@@ -131,17 +138,19 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
131138
BOOST_NETWORK_MESSAGE("trying connection to:"
132139
<< iter->endpoint().address() <<":" << port);
133140
asio::ip::tcp::endpointendpoint(iter->endpoint().address(), port);
134-
connection_delegate_->connect(endpoint,
135-
request_strand_.wrap(
136-
boost::bind(
137-
&this_type::handle_connected,
138-
this_type::shared_from_this(),
139-
port,
140-
get_body,
141-
callback,
142-
std::make_pair(++iter,
143-
resolver_iterator()),
144-
placeholders::error)));
141+
connection_delegate_->connect(
142+
endpoint,
143+
this->host_,
144+
request_strand_.wrap(
145+
boost::bind(
146+
&this_type::handle_connected,
147+
this_type::shared_from_this(),
148+
port,
149+
get_body,
150+
callback,
151+
std::make_pair(++iter,
152+
resolver_iterator()),
153+
placeholders::error)));
145154
}else {
146155
BOOST_NETWORK_MESSAGE("error encountered while resolving.");
147156
set_errors(ec ? ec : boost::asio::error::host_not_found);
@@ -174,6 +183,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
174183
BOOST_NETWORK_MESSAGE("trying:" << iter->endpoint().address() <<":" << port);
175184
asio::ip::tcp::endpointendpoint(iter->endpoint().address(), port);
176185
connection_delegate_->connect(endpoint,
186+
this->host_,
177187
request_strand_.wrap(
178188
boost::bind(
179189
&this_type::handle_connected,
@@ -218,7 +228,20 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
218228

219229
voidhandle_received_data(state_t state,bool get_body, body_callback_function_type callback, boost::system::error_codeconst & ec, std::size_t bytes_transferred) {
220230
BOOST_NETWORK_MESSAGE("http_async_connection_pimpl::handle_received_data(...)");
221-
if (!ec || ec == boost::asio::error::eof) {
231+
// Okay, there's some weirdness with Boost.Asio's handling of SSL errors
232+
// so we need to do some acrobatics to make sure that we're handling the
233+
// short-read errors correctly. This is such a PITA that we have to deal
234+
// with this here.
235+
staticlong short_read_error =335544539;
236+
bool is_short_read_error =
237+
#ifdef BOOST_NETWORK_ENABLE_HTTPS
238+
ec.category() == asio::error::ssl_category &&
239+
ec.value() == short_read_error
240+
#else
241+
false
242+
#endif
243+
;
244+
if (!ec || ec == boost::asio::error::eof || is_short_read_error) {
222245
BOOST_NETWORK_MESSAGE("processing data chunk, no error encountered so far...");
223246
logic::tribool parsed_ok;
224247
size_t remainder;
@@ -347,7 +370,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
347370
return;
348371
case body:
349372
BOOST_NETWORK_MESSAGE("parsing body...");
350-
if (ec == boost::asio::error::eof) {
373+
if (ec == boost::asio::error::eof || is_short_read_error) {
351374
BOOST_NETWORK_MESSAGE("end of the line.");
352375
// Here we're handling the case when the connection has been
353376
// closed from the server side, or at least that the end of file
@@ -429,6 +452,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
429452
}
430453
}else {
431454
boost::system::system_errorerror(ec);
455+
BOOST_NETWORK_MESSAGE("error encountered:" << error.what() <<" (" << ec <<")");
432456
this->source_promise.set_exception(boost::copy_exception(error));
433457
this->destination_promise.set_exception(boost::copy_exception(error));
434458
switch (state) {
@@ -773,6 +797,7 @@ struct http_async_connection_pimpl : boost::enable_shared_from_this<http_async_c
773797
buffer_type part;
774798
buffer_type::const_iterator part_begin;
775799
std::string partial_parsed;
800+
std::string host_;
776801
};
777802

778803
// END OF PIMPL DEFINITION

‎boost/network/protocol/http/client/connection/connection_delegate.hpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace boost { namespace network { namespace http {
1515

1616
structconnection_delegate {
1717
virtualvoidconnect(asio::ip::tcp::endpoint & endpoint,
18+
std::stringconst & host,
1819
function<void(system::error_codeconst &)> handler) = 0;
1920
virtualvoidwrite(asio::streambuf & command_streambuf,
2021
function<void(system::error_codeconst &,size_t)> handler) = 0;

‎boost/network/protocol/http/client/connection/normal_delegate.hpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct normal_delegate : connection_delegate {
2424
normal_delegate(asio::io_service & service);
2525

2626
virtualvoidconnect(asio::ip::tcp::endpoint & endpoint,
27+
std::stringconst &host,
2728
function<void(system::error_codeconst &)> handler);
2829
virtualvoidwrite(asio::streambuf & command_streambuf,
2930
function<void(system::error_codeconst &,size_t)> handler);

‎boost/network/protocol/http/client/connection/normal_delegate.ipp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ boost::network::http::normal_delegate::normal_delegate(asio::io_service & servic
2121

2222
voidboost::network::http::normal_delegate::connect(
2323
asio::ip::tcp::endpoint & endpoint,
24+
std::stringconst &host,
2425
function<void(system::error_codeconst &)> handler) {
2526
socket_.reset(newasio::ip::tcp::socket(service_));
2627
socket_->async_connect(endpoint, handler);

‎boost/network/protocol/http/client/connection/simple_connection_factory.ipp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifdef BOOST_NETWORK_DEBUG
1717
#include<boost/network/uri/uri_io.hpp>
1818
#endif
19+
#include<boost/algorithm/string/case_conv.hpp>
1920

2021
#include<boost/network/protocol/http/message/wrappers/uri.hpp>
2122

‎boost/network/protocol/http/client/connection/ssl_delegate.hpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct ssl_delegate : connection_delegate, enable_shared_from_this<ssl_delegate>
2727
client_optionsconst &options);
2828

2929
virtualvoidconnect(asio::ip::tcp::endpoint & endpoint,
30+
std::stringconst &host,
3031
function<void(system::error_codeconst &)> handler);
3132
virtualvoidwrite(asio::streambuf & command_streambuf,
3233
function<void(system::error_codeconst &,size_t)> handler);

‎boost/network/protocol/http/client/connection/ssl_delegate.ipp‎

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,39 @@
1616
boost::network::http::ssl_delegate::ssl_delegate(asio::io_service & service,
1717
client_optionsconst &options) :
1818
service_(service),
19-
options_(options) {}
19+
options_(options) {
20+
BOOST_NETWORK_MESSAGE("ssl_delegate::ssl_delegate(...)");
21+
}
2022

2123
voidboost::network::http::ssl_delegate::connect(
2224
asio::ip::tcp::endpoint & endpoint,
25+
std::stringconst &host,
2326
function<void(system::error_codeconst &)> handler) {
2427
BOOST_NETWORK_MESSAGE("ssl_delegate::connect(...)");
2528
context_.reset(newasio::ssl::context(
26-
service_,
27-
asio::ssl::context::sslv23_client));
29+
asio::ssl::context::sslv23));
2830
std::list<std::string>const & certificate_paths =
2931
options_.openssl_certificate_paths();
3032
std::list<std::string>const & verifier_paths =
3133
options_.openssl_verify_paths();
32-
bool verify_peer = !certificate_paths.empty() || !verifier_paths.empty();
33-
BOOST_NETWORK_MESSAGE("verify peer setting is:" << verify_peer);
34-
if (verify_peer) context_->set_verify_mode(asio::ssl::context::verify_peer);
35-
else context_->set_verify_mode(asio::ssl::context::verify_none);
36-
for (std::list<std::string>::const_iterator it = certificate_paths.begin();
37-
it != certificate_paths.end(); ++it) {
38-
context_->load_verify_file(*it);
39-
}
40-
for (std::list<std::string>::const_iterator it = verifier_paths.begin();
41-
it != verifier_paths.begin(); ++it) {
42-
context_->add_verify_path(*it);
34+
bool use_default_verification = certificate_paths.empty() && verifier_paths.empty();
35+
if (!use_default_verification) {
36+
for (std::list<std::string>::const_iterator it = certificate_paths.begin();
37+
it != certificate_paths.end(); ++it) {
38+
context_->load_verify_file(*it);
39+
}
40+
for (std::list<std::string>::const_iterator it = verifier_paths.begin();
41+
it != verifier_paths.begin(); ++it) {
42+
context_->add_verify_path(*it);
43+
}
44+
BOOST_NETWORK_MESSAGE("verifying peer:" << host);
45+
context_->set_verify_mode(asio::ssl::context::verify_peer);
46+
context_->set_verify_callback(asio::ssl::rfc2818_verification(host));
47+
}else {
48+
BOOST_NETWORK_MESSAGE("not verifying peer");
49+
context_->set_default_verify_paths();
50+
context_->set_verify_mode(asio::ssl::context::verify_peer);
51+
context_->set_verify_callback(asio::ssl::rfc2818_verification(host));
4352
}
4453
socket_.reset(new asio::ssl::stream<asio::ip::tcp::socket>(service_, *context_));
4554
BOOST_NETWORK_MESSAGE("scheduling asynchronous connection...");
@@ -51,12 +60,24 @@ void boost::network::http::ssl_delegate::connect(
5160
handler));
5261
}
5362

54-
voidboost::network::http::ssl_delegate::handle_connected(system::error_codeconst & ec,
55-
function<void(system::error_codeconst &)> handler) {
63+
64+
voidboost::network::http::ssl_delegate::handle_connected(
65+
system::error_codeconst & ec,
66+
function<void(system::error_codeconst &)> handler) {
5667
BOOST_NETWORK_MESSAGE("ssl_delegate::handle_connected(...)");
5768
if (!ec) {
5869
BOOST_NETWORK_MESSAGE("connected to endpoint.");
59-
socket_->async_handshake(asio::ssl::stream_base::client, handler);
70+
// Here we check if there's an existing session for the connection.
71+
SSL_SESSION *existing_session =SSL_get1_session(socket_->impl()->ssl);
72+
if (existing_session ==NULL) {
73+
BOOST_NETWORK_MESSAGE("found no existing session, performing handshake.");
74+
socket_->async_handshake(asio::ssl::stream_base::client, handler);
75+
}else {
76+
BOOST_NETWORK_MESSAGE("found existing session, bypassing handshake.");
77+
SSL_set_session(socket_->impl()->ssl, existing_session);
78+
SSL_connect(socket_->impl()->ssl);
79+
handler(ec);
80+
}
6081
}else {
6182
BOOST_NETWORK_MESSAGE("encountered error:" << ec);
6283
handler(ec);

‎boost/network/protocol/http/message/wrappers/port.ipp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ port_wrapper::operator boost::uint16_t () const {
1919
uri::uri uri_;
2020
request_.get_uri(uri_);
2121
optional<boost::uint16_t> optional_port =port_us(uri_);
22+
if (!optional_port) {
23+
std::string scheme_ =scheme(uri_);
24+
if (scheme_ =="http") {
25+
return80u;
26+
}elseif (scheme_ =="https") {
27+
return443u;
28+
}
29+
}
2230
return optional_port ? *optional_port :80u;
2331
}
2432

‎boost/network/protocol/http/response/response.ipp‎

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct response_pimpl {
2323
promise<std::string> destination_promise;
2424
destination_promise.set_value(destination);
2525
unique_future<std::string> tmp_future = destination_promise.get_future();
26-
destination_future_ =move(tmp_future);
26+
destination_future_ =boost::move(tmp_future);
2727
}
2828

2929
voidget_destination(std::string &destination) {
@@ -38,7 +38,7 @@ struct response_pimpl {
3838
promise<std::string> source_promise;
3939
source_promise.set_value(source);
4040
unique_future<std::string> tmp_future = source_promise.get_future();
41-
source_future_ =move(tmp_future);
41+
source_future_ =boost::move(tmp_future);
4242
}
4343

4444
voidget_source(std::string &source) {
@@ -66,7 +66,7 @@ struct response_pimpl {
6666
headers_promise.get_future();
6767
std::multimap<std::string, std::string>().swap(added_headers_);
6868
std::set<std::string>().swap(removed_headers_);
69-
headers_future_ =move(tmp);
69+
headers_future_ =boost::move(tmp);
7070
}
7171
}
7272

@@ -102,7 +102,7 @@ struct response_pimpl {
102102
promise<std::string> body_promise;
103103
body_promise.set_value(body);
104104
unique_future<std::string> tmp_future = body_promise.get_future();
105-
body_future_ =move(tmp_future);
105+
body_future_ =boost::move(tmp_future);
106106
}
107107

108108
voidappend_body(std::stringconst & data) {/* FIXME: Do something!*/ }
@@ -123,7 +123,7 @@ struct response_pimpl {
123123
promise<boost::uint16_t> status_promise;
124124
status_promise.set_value(status);
125125
unique_future<boost::uint16_t> tmp_future = status_promise.get_future();
126-
status_future_ =move(tmp_future);
126+
status_future_ =boost::move(tmp_future);
127127
}
128128

129129
voidget_status(boost::uint16_t &status) {
@@ -138,7 +138,7 @@ struct response_pimpl {
138138
promise<std::string> status_message_promise_;
139139
status_message_promise_.set_value(status_message);
140140
unique_future<std::string> tmp_future = status_message_promise_.get_future();
141-
status_message_future_ =move(tmp_future);
141+
status_message_future_ =boost::move(tmp_future);
142142
}
143143

144144
voidget_status_message(std::string &status_message) {
@@ -153,7 +153,7 @@ struct response_pimpl {
153153
promise<std::string> version_promise;
154154
version_promise.set_value(version);
155155
unique_future<std::string> tmp_future = version_promise.get_future();
156-
version_future_ =move(tmp_future);
156+
version_future_ =boost::move(tmp_future);
157157
}
158158

159159
voidget_version(std::string &version) {
@@ -166,37 +166,37 @@ struct response_pimpl {
166166

167167
voidset_source_promise(promise<std::string> &promise_) {
168168
unique_future<std::string> tmp_future = promise_.get_future();
169-
source_future_ =move(tmp_future);
169+
source_future_ =boost::move(tmp_future);
170170
}
171171

172172
voidset_destination_promise(promise<std::string> &promise_) {
173173
unique_future<std::string> tmp_future = promise_.get_future();
174-
destination_future_ =move(tmp_future);
174+
destination_future_ =boost::move(tmp_future);
175175
}
176176

177177
voidset_headers_promise(promise<std::multimap<std::string, std::string> > &promise_) {
178178
unique_future<std::multimap<std::string, std::string> > tmp_future = promise_.get_future();
179-
headers_future_ =move(tmp_future);
179+
headers_future_ =boost::move(tmp_future);
180180
}
181181

182182
voidset_status_promise(promise<boost::uint16_t> &promise_) {
183183
unique_future<boost::uint16_t> tmp_future = promise_.get_future();
184-
status_future_ =move(tmp_future);
184+
status_future_ =boost::move(tmp_future);
185185
}
186186

187187
voidset_status_message_promise(promise<std::string> &promise_) {
188188
unique_future<std::string> tmp_future = promise_.get_future();
189-
status_message_future_ =move(tmp_future);
189+
status_message_future_ =boost::move(tmp_future);
190190
}
191191

192192
voidset_version_promise(promise<std::string> &promise_) {
193193
unique_future<std::string> tmp_future = promise_.get_future();
194-
version_future_ =move(tmp_future);
194+
version_future_ =boost::move(tmp_future);
195195
}
196196

197197
voidset_body_promise(promise<std::string> &promise_) {
198198
unique_future<std::string> tmp_future = promise_.get_future();
199-
body_future_ =move(tmp_future);
199+
body_future_ =boost::move(tmp_future);
200200
}
201201

202202
boolequals(response_pimplconst &other) {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp