Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 8510393

Browse files
committed
Merge pull request cpp-netlib#403 from leecoder/0.11-devel
Added client timeout option for 0.11
2 parents ce53598 + 93a9630 commit 8510393

19 files changed

+160
-29
lines changed

boost/network/protocol/http/client/async_impl.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ struct async_client
3737
typedef function<bool(string_type&)> body_generator_function_type;
3838

3939
async_client(bool cache_resolved, bool follow_redirect,
40-
bool always_verify_peer,
40+
bool always_verify_peer, int timeout,
4141
boost::shared_ptr<boost::asio::io_service> service,
4242
optional<string_type> const& certificate_filename,
4343
optional<string_type> const& verify_path,
4444
optional<string_type> const& certificate_file,
4545
optional<string_type> const& private_key_file)
46-
: connection_base(cache_resolved, follow_redirect),
46+
: connection_base(cache_resolved, follow_redirect, timeout),
4747
service_ptr(service.get()
4848
? service
4949
: boost::make_shared<boost::asio::io_service>()),

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace boost { namespace network { namespace http { namespace impl {
3939
bool follow_redirect,
4040
bool always_verify_peer,
4141
bool https,
42+
int timeout,
4243
optional<string_type> certificate_filename=optional<string_type>(),
4344
optional<string_type> const & verify_path=optional<string_type>(),
4445
optional<string_type> certificate_file=optional<string_type>(),
@@ -52,6 +53,7 @@ namespace boost { namespace network { namespace http { namespace impl {
5253
resolver,
5354
resolve,
5455
follow_redirect,
56+
timeout,
5557
delegate_factory_type::new_connection_delegate(
5658
resolver.get_io_service(),
5759
https,

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ struct http_async_connection
6868
connection_delegate_ptr;
6969

7070
http_async_connection(resolver_type& resolver, resolve_function resolve,
71-
bool follow_redirect, connection_delegate_ptr delegate)
72-
: follow_redirect_(follow_redirect),
71+
bool follow_redirect, int timeout,
72+
connection_delegate_ptr delegate)
73+
: timeout_(timeout),
74+
timer_(resolver.get_io_service()),
75+
follow_redirect_(follow_redirect),
7376
resolver_(resolver),
7477
resolve_(resolve),
7578
request_strand_(resolver.get_io_service()),
@@ -92,6 +95,13 @@ struct http_async_connection
9295
request_strand_.wrap(boost::bind(
9396
&this_type::handle_resolved, this_type::shared_from_this(),
9497
port_, get_body, callback, generator, _1, _2)));
98+
if (timeout_ > 0) {
99+
timer_.expires_from_now(boost::posix_time::seconds(timeout_));
100+
timer_.async_wait(request_strand_.wrap(
101+
boost::bind(&this_type::handle_timeout,
102+
this_type::shared_from_this(),
103+
_1)));
104+
}
95105
return response_;
96106
}
97107

@@ -107,6 +117,11 @@ struct http_async_connection
107117
this->source_promise.set_exception(boost::copy_exception(error));
108118
this->destination_promise.set_exception(boost::copy_exception(error));
109119
this->body_promise.set_exception(boost::copy_exception(error));
120+
this->timer_.cancel();
121+
}
122+
123+
void handle_timeout(boost::system::error_code const &ec) {
124+
if (!ec) delegate_->disconnect();
110125
}
111126

112127
void handle_resolved(boost::uint16_t port, bool get_body,
@@ -348,6 +363,7 @@ struct http_async_connection
348363
this->source_promise.set_value("");
349364
this->part.assign('\0');
350365
this->response_parser_.reset();
366+
this->timer_.cancel();
351367
} else {
352368
// This means the connection has not been closed yet and we want
353369
// to get more
@@ -436,6 +452,8 @@ struct http_async_connection
436452
return body;
437453
}
438454

455+
int timeout_;
456+
boost::asio::deadline_timer timer_;
439457
bool follow_redirect_;
440458
resolver_type& resolver_;
441459
resolve_function resolve_;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct connection_delegate {
1616
function<void(system::error_code const &, size_t)> handler) = 0;
1717
virtual void read_some(asio::mutable_buffers_1 const & read_buffer,
1818
function<void(system::error_code const &, size_t)> handler) = 0;
19+
virtual void disconnect() = 0;
1920
virtual ~connection_delegate() {}
2021
};
2122

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct normal_delegate : connection_delegate {
2222
function<void(system::error_code const &, size_t)> handler);
2323
virtual void read_some(asio::mutable_buffers_1 const & read_buffer,
2424
function<void(system::error_code const &, size_t)> handler);
25+
virtual void disconnect();
2526
~normal_delegate();
2627

2728
private:

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ void boost::network::http::impl::normal_delegate::read_some(
3737
socket_->async_read_some(read_buffer, handler);
3838
}
3939

40+
void boost::network::http::impl::normal_delegate::disconnect() {
41+
if (socket_.get() && socket_->is_open()) {
42+
boost::system::error_code ignored;
43+
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored);
44+
if (!ignored) {
45+
socket_->close(ignored);
46+
}
47+
}
48+
}
49+
4050
boost::network::http::impl::normal_delegate::~normal_delegate() {}
4151

4252
#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_NORMAL_DELEGATE_IPP_20110819 */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct ssl_delegate : connection_delegate,
3636
virtual void read_some(
3737
asio::mutable_buffers_1 const &read_buffer,
3838
function<void(system::error_code const &, size_t)> handler);
39+
virtual void disconnect();
3940
~ssl_delegate();
4041

4142
private:

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ void boost::network::http::impl::ssl_delegate::read_some(
7878
socket_->async_read_some(read_buffer, handler);
7979
}
8080

81+
void boost::network::http::impl::ssl_delegate::disconnect() {
82+
if (socket_.get() && socket_->lowest_layer().is_open()) {
83+
boost::system::error_code ignored;
84+
socket_->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored);
85+
if (!ignored) {
86+
socket_->lowest_layer().close(ignored);
87+
}
88+
}
89+
}
90+
8191
boost::network::http::impl::ssl_delegate::~ssl_delegate() {}
8292

8393
#endif /* BOOST_NETWORK_PROTOCOL_HTTP_CLIENT_CONNECTION_SSL_DELEGATE_IPP_20110819 \

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ struct sync_connection_base {
239239
// ranges
240240
static sync_connection_base<Tag, version_major, version_minor>*
241241
new_connection(resolver_type& resolver, resolver_function_type resolve,
242-
bool https, bool always_verify_peer,
242+
bool https, bool always_verify_peer, int timeout,
243243
optional<string_type> const& certificate_filename =
244244
optional<string_type>(),
245245
optional<string_type> const& verify_path =
@@ -253,7 +253,7 @@ struct sync_connection_base {
253253
return dynamic_cast<
254254
sync_connection_base<Tag, version_major, version_minor>*>(
255255
new https_sync_connection<Tag, version_major, version_minor>(
256-
resolver, resolve,
256+
resolver, resolve, always_verify_peer, timeout,
257257
certificate_filename, verify_path,
258258
certificate_file, private_key_file));
259259
#else
@@ -263,7 +263,8 @@ struct sync_connection_base {
263263
return dynamic_cast<
264264
sync_connection_base<Tag, version_major, version_minor>*>(
265265
new http_sync_connection<Tag, version_major, version_minor>(resolver,
266-
resolve));
266+
resolve,
267+
timeout));
267268
}
268269

269270
virtual void init_socket(string_type const& hostname,

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,26 @@ struct sync_connection_base;
2525
template <class Tag, unsigned version_major, unsigned version_minor>
2626
struct http_sync_connection
2727
: public virtual sync_connection_base<Tag, version_major, version_minor>,
28-
sync_connection_base_impl<Tag, version_major, version_minor> {
28+
sync_connection_base_impl<Tag, version_major, version_minor>,
29+
boost::enable_shared_from_this<http_sync_connection<Tag, version_major, version_minor> > {
2930
typedef typename resolver_policy<Tag>::type resolver_base;
3031
typedef typename resolver_base::resolver_type resolver_type;
3132
typedef typename string<Tag>::type string_type;
3233
typedef function<typename resolver_base::resolver_iterator_pair(
3334
resolver_type&,
3435
string_type const&,
3536
string_type const&)> resolver_function_type;
37+
typedef http_sync_connection<Tag, version_major, version_minor> this_type;
3638
typedef sync_connection_base_impl<Tag, version_major, version_minor>
3739
connection_base;
3840
typedef function<bool(string_type&)> body_generator_function_type;
3941

40-
http_sync_connection(resolver_type& resolver, resolver_function_type resolve)
42+
http_sync_connection(resolver_type& resolver,
43+
resolver_function_type resolve,
44+
int timeout)
4145
: connection_base(),
46+
timeout_(timeout),
47+
timer_(resolver.get_io_service()),
4248
resolver_(resolver),
4349
resolve_(resolve),
4450
socket_(resolver.get_io_service()) {}
@@ -69,6 +75,12 @@ struct http_sync_connection
6975
connection_base::send_request_impl(socket_, method, request_buffer);
7076
}
7177
}
78+
if (timeout_ > 0) {
79+
timer_.expires_from_now(boost::posix_time::seconds(timeout_));
80+
timer_.async_wait(boost::bind(&this_type::handle_timeout,
81+
this_type::shared_from_this(),
82+
_1));
83+
}
7284
}
7385

7486
void read_status(basic_response<Tag>& response_,
@@ -97,6 +109,7 @@ struct http_sync_connection
97109
bool is_open() { return socket_.is_open(); }
98110

99111
void close_socket() {
112+
timer_.cancel();
100113
if (!is_open())
101114
return;
102115
boost::system::error_code ignored;
@@ -107,7 +120,12 @@ struct http_sync_connection
107120
}
108121

109122
private:
123+
void handle_timeout(boost::system::error_code const &ec) {
124+
if (!ec) close_socket();
125+
}
110126

127+
int timeout_;
128+
boost::asio::deadline_timer timer_;
111129
resolver_type& resolver_;
112130
resolver_function_type resolve_;
113131
boost::asio::ip::tcp::socket socket_;

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