Skip to content

Commit d222dbd

Browse files
authored
Fix timeout (#464)
1 parent a001eab commit d222dbd

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

include/cinatra/coro_http_client.hpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,10 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
283283
co_return resp_data{std::make_error_code(std::errc::protocol_error), 404};
284284
}
285285

286-
auto future = start_timer(req_timeout_duration_, "connect timer");
286+
auto future = start_timer(conn_timeout_duration_, "connect timer");
287287

288288
data = co_await connect(u);
289-
if (auto ec = co_await wait_timer(std::move(future)); ec) {
289+
if (auto ec = co_await wait_future(std::move(future)); ec) {
290290
co_return resp_data{ec, 404};
291291
}
292292
if (!data.net_err) {
@@ -637,7 +637,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
637637
return fut;
638638
}
639639

640-
async_simple::coro::Lazy<std::error_code> wait_timer(
640+
async_simple::coro::Lazy<std::error_code> wait_future(
641641
async_simple::Future<async_simple::Unit> &&future) {
642642
if (!enable_timeout_) {
643643
co_return std::error_code{};
@@ -680,10 +680,10 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
680680
size_t size = 0;
681681

682682
if (socket_->has_closed_) {
683-
auto future = start_timer(req_timeout_duration_, "connect timer");
683+
auto future = start_timer(conn_timeout_duration_, "connect timer");
684684

685685
data = co_await connect(u);
686-
if (ec = co_await wait_timer(std::move(future)); ec) {
686+
if (ec = co_await wait_future(std::move(future)); ec) {
687687
co_return resp_data{ec, 404};
688688
}
689689
if (data.net_err) {
@@ -710,6 +710,9 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
710710
data = co_await send_single_part(key, part);
711711

712712
if (data.net_err) {
713+
if (data.net_err == asio::error::operation_aborted) {
714+
data.net_err = std::make_error_code(std::errc::timed_out);
715+
}
713716
co_return data;
714717
}
715718
}
@@ -724,7 +727,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
724727
bool is_keep_alive = true;
725728
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
726729
http_method::POST);
727-
if (auto errc = co_await wait_timer(std::move(future)); errc) {
730+
if (auto errc = co_await wait_future(std::move(future)); errc) {
728731
ec = errc;
729732
}
730733

@@ -868,10 +871,10 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
868871
size_t size = 0;
869872

870873
if (socket_->has_closed_) {
871-
auto future = start_timer(req_timeout_duration_, "connect timer");
874+
auto future = start_timer(conn_timeout_duration_, "connect timer");
872875

873876
data = co_await connect(u);
874-
if (ec = co_await wait_timer(std::move(future)); ec) {
877+
if (ec = co_await wait_future(std::move(future)); ec) {
875878
co_return resp_data{ec, 404};
876879
}
877880
if (data.net_err) {
@@ -896,7 +899,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
896899
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
897900
file_data.data(), rd_size, chunk_size_str, source->eof());
898901
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
899-
co_return resp_data{ec, 404};
902+
break;
900903
}
901904
}
902905
}
@@ -914,7 +917,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
914917
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
915918
file_data.data(), rd_size, chunk_size_str, file.eof());
916919
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
917-
co_return resp_data{ec, 404};
920+
break;
918921
}
919922
}
920923
}
@@ -925,18 +928,23 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
925928
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
926929
result.buf.data(), result.buf.size(), chunk_size_str, result.eof);
927930
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
928-
co_return resp_data{ec, 404};
931+
break;
929932
}
930933
if (result.eof) {
931934
break;
932935
}
933936
}
934937
}
935938

939+
if (ec && ec == asio::error::operation_aborted) {
940+
ec = std::make_error_code(std::errc::timed_out);
941+
co_return resp_data{ec, 404};
942+
}
943+
936944
bool is_keep_alive = true;
937945
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
938946
http_method::POST);
939-
if (auto errc = co_await wait_timer(std::move(future)); errc) {
947+
if (auto errc = co_await wait_future(std::move(future)); errc) {
940948
ec = errc;
941949
}
942950

@@ -1016,7 +1024,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
10161024
}
10171025
}
10181026
socket_->has_closed_ = false;
1019-
if (ec = co_await wait_timer(std::move(conn_future)); ec) {
1027+
if (ec = co_await wait_future(std::move(conn_future)); ec) {
10201028
break;
10211029
}
10221030
}
@@ -1050,7 +1058,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
10501058

10511059
data =
10521060
co_await handle_read(ec, size, is_keep_alive, std::move(ctx), method);
1053-
if (auto errc = co_await wait_timer(std::move(future)); errc) {
1061+
if (auto errc = co_await wait_future(std::move(future)); errc) {
10541062
ec = errc;
10551063
}
10561064
} while (0);

tests/test_cinatra.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,22 @@ TEST_CASE("test basic http request") {
794794
server_thread.join();
795795
}
796796

797+
TEST_CASE("test coro_http_client request timeout") {
798+
coro_http_client client{};
799+
cinatra::coro_http_client::config conf{.conn_timeout_duration = 10s,
800+
.req_timeout_duration = 1ms};
801+
client.init_config(conf);
802+
auto r =
803+
async_simple::coro::syncAwait(client.connect("http://www.baidu.com"));
804+
std::cout << r.net_err.message() << "\n";
805+
if (!r.net_err) {
806+
r = async_simple::coro::syncAwait(client.async_get("/"));
807+
if (r.net_err) {
808+
CHECK(r.net_err == std::errc::timed_out);
809+
}
810+
}
811+
}
812+
797813
#ifdef INJECT_FOR_HTTP_CLIENT_TEST
798814
TEST_CASE("test inject failed") {
799815
// {

0 commit comments

Comments
 (0)