Skip to content

Commit

Permalink
Fix timeout (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Dec 19, 2023
1 parent a001eab commit d222dbd
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
36 changes: 22 additions & 14 deletions include/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,10 +283,10 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
co_return resp_data{std::make_error_code(std::errc::protocol_error), 404};
}

auto future = start_timer(req_timeout_duration_, "connect timer");
auto future = start_timer(conn_timeout_duration_, "connect timer");

data = co_await connect(u);
if (auto ec = co_await wait_timer(std::move(future)); ec) {
if (auto ec = co_await wait_future(std::move(future)); ec) {
co_return resp_data{ec, 404};
}
if (!data.net_err) {
Expand Down Expand Up @@ -637,7 +637,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
return fut;
}

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

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

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

if (data.net_err) {
if (data.net_err == asio::error::operation_aborted) {
data.net_err = std::make_error_code(std::errc::timed_out);
}
co_return data;
}
}
Expand All @@ -724,7 +727,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
bool is_keep_alive = true;
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
http_method::POST);
if (auto errc = co_await wait_timer(std::move(future)); errc) {
if (auto errc = co_await wait_future(std::move(future)); errc) {
ec = errc;
}

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

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

data = co_await connect(u);
if (ec = co_await wait_timer(std::move(future)); ec) {
if (ec = co_await wait_future(std::move(future)); ec) {
co_return resp_data{ec, 404};
}
if (data.net_err) {
Expand All @@ -896,7 +899,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
file_data.data(), rd_size, chunk_size_str, source->eof());
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
co_return resp_data{ec, 404};
break;
}
}
}
Expand All @@ -914,7 +917,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
file_data.data(), rd_size, chunk_size_str, file.eof());
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
co_return resp_data{ec, 404};
break;
}
}
}
Expand All @@ -925,18 +928,23 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
auto bufs = cinatra::to_chunked_buffers<asio::const_buffer>(
result.buf.data(), result.buf.size(), chunk_size_str, result.eof);
if (std::tie(ec, size) = co_await async_write(bufs); ec) {
co_return resp_data{ec, 404};
break;
}
if (result.eof) {
break;
}
}
}

if (ec && ec == asio::error::operation_aborted) {
ec = std::make_error_code(std::errc::timed_out);
co_return resp_data{ec, 404};
}

bool is_keep_alive = true;
data = co_await handle_read(ec, size, is_keep_alive, std::move(ctx),
http_method::POST);
if (auto errc = co_await wait_timer(std::move(future)); errc) {
if (auto errc = co_await wait_future(std::move(future)); errc) {
ec = errc;
}

Expand Down Expand Up @@ -1016,7 +1024,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
}
}
socket_->has_closed_ = false;
if (ec = co_await wait_timer(std::move(conn_future)); ec) {
if (ec = co_await wait_future(std::move(conn_future)); ec) {
break;
}
}
Expand Down Expand Up @@ -1050,7 +1058,7 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {

data =
co_await handle_read(ec, size, is_keep_alive, std::move(ctx), method);
if (auto errc = co_await wait_timer(std::move(future)); errc) {
if (auto errc = co_await wait_future(std::move(future)); errc) {
ec = errc;
}
} while (0);
Expand Down
16 changes: 16 additions & 0 deletions tests/test_cinatra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,22 @@ TEST_CASE("test basic http request") {
server_thread.join();
}

TEST_CASE("test coro_http_client request timeout") {
coro_http_client client{};
cinatra::coro_http_client::config conf{.conn_timeout_duration = 10s,
.req_timeout_duration = 1ms};
client.init_config(conf);
auto r =
async_simple::coro::syncAwait(client.connect("http://www.baidu.com"));
std::cout << r.net_err.message() << "\n";
if (!r.net_err) {
r = async_simple::coro::syncAwait(client.async_get("/"));
if (r.net_err) {
CHECK(r.net_err == std::errc::timed_out);
}
}
}

#ifdef INJECT_FOR_HTTP_CLIENT_TEST
TEST_CASE("test inject failed") {
// {
Expand Down

0 comments on commit d222dbd

Please sign in to comment.