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

Commit6771a55

Browse files
committed
Added connection timeout check to HTTP client.
1 parent4e0add7 commit6771a55

File tree

6 files changed

+99
-21
lines changed

6 files changed

+99
-21
lines changed

‎http/src/http/v2/client/client.cpp

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ namespace network {
3333
boost::asio::streambuf request_buffer_;
3434
boost::asio::streambuf response_buffer_;
3535

36-
// TODO configure chunked transfer encoding
37-
bool chunked_;
38-
39-
// TODO configure deadline timer for timeouts
40-
bool timedout_;
41-
4236
std::uint64_t total_bytes_written_, total_bytes_read_;
4337

4438
request_context(
@@ -47,8 +41,6 @@ namespace network {
4741
: connection_(connection),
4842
request_(request),
4943
options_(options),
50-
chunked_(false),
51-
timedout_(false),
5244
total_bytes_written_(0),
5345
total_bytes_read_(0) {}
5446
};
@@ -63,8 +55,14 @@ namespace network {
6355

6456
~impl();
6557

58+
voidset_error(const boost::system::error_code &ec,
59+
std::shared_ptr<request_context> context);
60+
6661
std::future<response>execute(std::shared_ptr<request_context> context);
6762

63+
voidtimeout(const boost::system::error_code &ec,
64+
std::shared_ptr<request_context> context);
65+
6866
voidconnect(const boost::system::error_code &ec,
6967
tcp::resolver::iterator endpoint_iterator,
7068
std::shared_ptr<request_context> context);
@@ -101,7 +99,11 @@ namespace network {
10199
boost::asio::io_service::strand strand_;
102100
std::unique_ptr<client_connection::async_resolver> resolver_;
103101
std::shared_ptr<client_connection::async_connection> mock_connection_;
102+
// TODO configure deadline timer for timeouts
103+
bool timedout_;
104+
boost::asio::deadline_timer timer_;
104105
std::thread lifetime_thread_;
106+
105107
};
106108

107109
client::impl::impl(client_options options)
@@ -110,6 +112,8 @@ namespace network {
110112
strand_(io_service_),
111113
resolver_(new client_connection::tcp_resolver(
112114
io_service_, options_.cache_resolved())),
115+
timedout_(false),
116+
timer_(io_service_),
113117
lifetime_thread_([=]() { io_service_.run(); }) {}
114118

115119
client::impl::impl(
@@ -120,13 +124,23 @@ namespace network {
120124
sentinel_(new boost::asio::io_service::work(io_service_)),
121125
strand_(io_service_),
122126
resolver_(std::move(mock_resolver)),
127+
timedout_(false),
128+
timer_(io_service_),
123129
lifetime_thread_([=]() { io_service_.run(); }) {}
124130

125131
client::impl::~impl() {
126132
sentinel_.reset();
127133
lifetime_thread_.join();
128134
}
129135

136+
137+
voidclient::impl::set_error(const boost::system::error_code &ec,
138+
std::shared_ptr<request_context> context) {
139+
context->response_promise_.set_exception(std::make_exception_ptr(
140+
std::system_error(ec.value(),std::system_category())));
141+
timer_.cancel();
142+
}
143+
130144
std::future<response>client::impl::execute(
131145
std::shared_ptr<request_context> context) {
132146
std::future<response> res = context->response_promise_.get_future();
@@ -153,15 +167,29 @@ namespace network {
153167
connect(ec, endpoint_iterator, context);
154168
}));
155169

170+
if (options_.timeout() >std::chrono::milliseconds(0)) {
171+
timer_.expires_from_now(boost::posix_time::milliseconds(options_.timeout().count()));
172+
timer_.async_wait(strand_.wrap([=](const boost::system::error_code &ec) {
173+
timeout(ec, context);
174+
}));
175+
}
176+
156177
return res;
157178
}
158179

180+
voidclient::impl::timeout(const boost::system::error_code &ec,
181+
std::shared_ptr<request_context> context) {
182+
if (!ec) {
183+
context->connection_->disconnect();
184+
}
185+
timedout_ =true;
186+
}
187+
159188
voidclient::impl::connect(const boost::system::error_code &ec,
160189
tcp::resolver::iterator endpoint_iterator,
161190
std::shared_ptr<request_context> context) {
162191
if (ec) {
163-
context->response_promise_.set_exception(std::make_exception_ptr(
164-
std::system_error(ec.value(),std::system_category())));
192+
set_error(ec, context);
165193
return;
166194
}
167195

@@ -188,9 +216,13 @@ namespace network {
188216
voidclient::impl::write_request(
189217
const boost::system::error_code &ec,
190218
std::shared_ptr<request_context> context) {
219+
if (timedout_) {
220+
set_error(boost::asio::error::timed_out, context);
221+
return;
222+
}
223+
191224
if (ec) {
192-
context->response_promise_.set_exception(std::make_exception_ptr(
193-
std::system_error(ec.value(),std::system_category())));
225+
set_error(ec, context);
194226
return;
195227
}
196228

@@ -200,6 +232,7 @@ namespace network {
200232
if (!request_stream) {
201233
context->response_promise_.set_exception(std::make_exception_ptr(
202234
client_exception(client_error::invalid_request)));
235+
timer_.cancel();
203236
}
204237

205238
context->connection_->async_write(
@@ -213,9 +246,13 @@ namespace network {
213246
voidclient::impl::write_body(const boost::system::error_code &ec,
214247
std::size_t bytes_written,
215248
std::shared_ptr<request_context> context) {
249+
if (timedout_) {
250+
set_error(boost::asio::error::timed_out, context);
251+
return;
252+
}
253+
216254
if (ec) {
217-
context->response_promise_.set_exception(std::make_exception_ptr(
218-
std::system_error(ec.value(),std::system_category())));
255+
set_error(ec, context);
219256
return;
220257
}
221258

@@ -245,9 +282,13 @@ namespace network {
245282
voidclient::impl::read_response(
246283
const boost::system::error_code &ec, std::size_t bytes_written,
247284
std::shared_ptr<request_context> context) {
285+
if (timedout_) {
286+
set_error(boost::asio::error::timed_out, context);
287+
return;
288+
}
289+
248290
if (ec) {
249-
context->response_promise_.set_exception(std::make_exception_ptr(
250-
std::system_error(ec.value(),std::system_category())));
291+
set_error(ec, context);
251292
return;
252293
}
253294

@@ -272,9 +313,13 @@ namespace network {
272313
const boost::system::error_code &ec, std::size_t,
273314
std::shared_ptr<request_context> context,
274315
std::shared_ptr<response> res) {
316+
if (timedout_) {
317+
set_error(boost::asio::error::timed_out, context);
318+
return;
319+
}
320+
275321
if (ec) {
276-
context->response_promise_.set_exception(std::make_exception_ptr(
277-
std::system_error(ec.value(),std::system_category())));
322+
set_error(ec, context);
278323
return;
279324
}
280325

@@ -304,9 +349,13 @@ namespace network {
304349
const boost::system::error_code &ec, std::size_t,
305350
std::shared_ptr<request_context> context,
306351
std::shared_ptr<response> res) {
352+
if (timedout_) {
353+
set_error(boost::asio::error::timed_out, context);
354+
return;
355+
}
356+
307357
if (ec) {
308-
context->response_promise_.set_exception(std::make_exception_ptr(
309-
std::system_error(ec.value(),std::system_category())));
358+
set_error(ec, context);
310359
return;
311360
}
312361

@@ -370,6 +419,7 @@ namespace network {
370419
// If there's no data else to read, then set the response and exit.
371420
if (bytes_read ==0) {
372421
context->response_promise_.set_value(*res);
422+
timer_.cancel();
373423
return;
374424
}
375425

‎http/src/network/http/v2/client/client.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include<vector>
2222
#include<chrono>
2323
#include<boost/asio/io_service.hpp>
24+
#include<boost/asio/deadline_timer.hpp>
2425
#include<boost/optional.hpp>
2526
#include<network/config.hpp>
2627
#include<network/version.hpp>

‎http/src/network/http/v2/client/connection/async_connection.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ namespace network {
9494
virtualvoidasync_read(boost::asio::streambuf &command_streambuf,
9595
read_callback callback) = 0;
9696

97+
/**
98+
* \brief Breaks the connection.
99+
*/
100+
virtualvoiddisconnect() = 0;
101+
97102
/**
98103
* \brief Cancels an operation on a connection.
99104
*/

‎http/src/network/http/v2/client/connection/normal_connection.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ namespace network {
7575
boost::asio::transfer_at_least(1), callback);
7676
}
7777

78+
virtualvoiddisconnect() {
79+
if (socket_ && socket_->is_open()) {
80+
boost::system::error_code ec;
81+
socket_->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
82+
if (!ec) {
83+
socket_->close(ec);
84+
}
85+
}
86+
}
87+
7888
virtualvoidcancel() {
7989
socket_->cancel();
8090
}

‎http/src/network/http/v2/client/connection/ssl_connection.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,18 @@ namespace network {
100100
boost::asio::transfer_at_least(1), callback);
101101
}
102102

103+
virtualvoiddisconnect() {
104+
if (socket_ && socket_->lowest_layer().is_open()) {
105+
boost::system::error_code ec;
106+
socket_->lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
107+
if (!ec) {
108+
socket_->lowest_layer().close(ec);
109+
}
110+
}
111+
}
112+
103113
virtualvoidcancel() {
104-
//socket_->cancel();
114+
socket_->lowest_layer().cancel();
105115
}
106116

107117
private:

‎http/test/v2/client/units/client_resolution_test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class fake_async_connection : public http_cc::async_connection {
5151
virtualvoidasync_read(boost::asio::streambuf &,
5252
read_callback) { }
5353

54+
virtualvoiddisconnect() { }
55+
5456
virtualvoidcancel() { }
5557

5658
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp