From d222dbda1a067c634fb0046147ec10b5025d51d5 Mon Sep 17 00:00:00 2001 From: qicosmos Date: Tue, 19 Dec 2023 17:18:20 +0800 Subject: [PATCH] Fix timeout (#464) --- include/cinatra/coro_http_client.hpp | 36 +++++++++++++++++----------- tests/test_cinatra.cpp | 16 +++++++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/include/cinatra/coro_http_client.hpp b/include/cinatra/coro_http_client.hpp index f2331e83..b4fc9ea2 100644 --- a/include/cinatra/coro_http_client.hpp +++ b/include/cinatra/coro_http_client.hpp @@ -283,10 +283,10 @@ class coro_http_client : public std::enable_shared_from_this { 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) { @@ -637,7 +637,7 @@ class coro_http_client : public std::enable_shared_from_this { return fut; } - async_simple::coro::Lazy wait_timer( + async_simple::coro::Lazy wait_future( async_simple::Future &&future) { if (!enable_timeout_) { co_return std::error_code{}; @@ -680,10 +680,10 @@ class coro_http_client : public std::enable_shared_from_this { 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) { @@ -710,6 +710,9 @@ class coro_http_client : public std::enable_shared_from_this { 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; } } @@ -724,7 +727,7 @@ class coro_http_client : public std::enable_shared_from_this { 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; } @@ -868,10 +871,10 @@ class coro_http_client : public std::enable_shared_from_this { 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) { @@ -896,7 +899,7 @@ class coro_http_client : public std::enable_shared_from_this { auto bufs = cinatra::to_chunked_buffers( 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; } } } @@ -914,7 +917,7 @@ class coro_http_client : public std::enable_shared_from_this { auto bufs = cinatra::to_chunked_buffers( 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; } } } @@ -925,7 +928,7 @@ class coro_http_client : public std::enable_shared_from_this { auto bufs = cinatra::to_chunked_buffers( 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; @@ -933,10 +936,15 @@ class coro_http_client : public std::enable_shared_from_this { } } + 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; } @@ -1016,7 +1024,7 @@ class coro_http_client : public std::enable_shared_from_this { } } 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; } } @@ -1050,7 +1058,7 @@ class coro_http_client : public std::enable_shared_from_this { 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); diff --git a/tests/test_cinatra.cpp b/tests/test_cinatra.cpp index ea8c22ca..f051cbfb 100644 --- a/tests/test_cinatra.cpp +++ b/tests/test_cinatra.cpp @@ -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") { // {