diff --git a/httplib.h b/httplib.h index 87f58e4..9209f6c 100644 --- a/httplib.h +++ b/httplib.h @@ -668,9 +668,18 @@ public: Server &set_keep_alive_max_count(size_t count); Server &set_keep_alive_timeout(time_t sec); + Server &set_read_timeout(time_t sec, time_t usec = 0); + template + Server &set_read_timeout(const std::chrono::duration &duration); + Server &set_write_timeout(time_t sec, time_t usec = 0); + template + Server &set_write_timeout(const std::chrono::duration &duration); + Server &set_idle_interval(time_t sec, time_t usec = 0); + template + Server &set_idle_interval(const std::chrono::duration &duration); Server &set_payload_max_length(size_t length); @@ -966,8 +975,16 @@ public: void set_socket_options(SocketOptions socket_options); void set_connection_timeout(time_t sec, time_t usec = 0); + template + void set_connection_timeout(const std::chrono::duration &duration); + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); void set_basic_auth(const char *username, const char *password); void set_bearer_token_auth(const char *token); @@ -1268,8 +1285,16 @@ public: void set_socket_options(SocketOptions socket_options); void set_connection_timeout(time_t sec, time_t usec = 0); + template + void set_connection_timeout(const std::chrono::duration &duration); + void set_read_timeout(time_t sec, time_t usec = 0); + template + void set_read_timeout(const std::chrono::duration &duration); + void set_write_timeout(time_t sec, time_t usec = 0); + template + void set_write_timeout(const std::chrono::duration &duration); void set_basic_auth(const char *username, const char *password); void set_bearer_token_auth(const char *token); @@ -3804,6 +3829,15 @@ private: ContentProviderWithoutLength content_provider_; }; +template +inline void duration_to_sec_and_usec(const T &duration, U callback) { + auto sec = std::chrono::duration_cast(duration).count(); + auto usec = std::chrono::duration_cast( + duration - std::chrono::seconds(sec)) + .count(); + callback(sec, usec); +} + } // namespace detail // Header utilities @@ -4381,6 +4415,15 @@ inline Server &Server::set_read_timeout(time_t sec, time_t usec) { return *this; } +template +inline Server &Server::set_read_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_read_timeout(sec, usec); + }); + return *this; +} + inline Server &Server::set_write_timeout(time_t sec, time_t usec) { write_timeout_sec_ = sec; write_timeout_usec_ = usec; @@ -4388,6 +4431,15 @@ inline Server &Server::set_write_timeout(time_t sec, time_t usec) { return *this; } +template +inline Server &Server::set_write_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_write_timeout(sec, usec); + }); + return *this; +} + inline Server &Server::set_idle_interval(time_t sec, time_t usec) { idle_interval_sec_ = sec; idle_interval_usec_ = usec; @@ -4395,6 +4447,15 @@ inline Server &Server::set_idle_interval(time_t sec, time_t usec) { return *this; } +template +inline Server &Server::set_idle_interval( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_idle_interval(sec, usec); + }); + return *this; +} + inline Server &Server::set_payload_max_length(size_t length) { payload_max_length_ = length; @@ -6273,16 +6334,40 @@ inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) { connection_timeout_usec_ = usec; } +template +inline void ClientImpl::set_connection_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_connection_timeout(sec, usec); + }); +} + inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) { read_timeout_sec_ = sec; read_timeout_usec_ = usec; } +template +inline void ClientImpl::set_read_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_read_timeout(sec, usec); + }); +} + inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) { write_timeout_sec_ = sec; write_timeout_usec_ = usec; } +template +inline void ClientImpl::set_write_timeout( + const std::chrono::duration &duration) { + detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) { + set_write_timeout(sec, usec); + }); +} + inline void ClientImpl::set_basic_auth(const char *username, const char *password) { basic_auth_username_ = username; @@ -7372,6 +7457,7 @@ inline void Client::set_default_headers(Headers headers) { } inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); } + inline void Client::set_socket_options(SocketOptions socket_options) { cli_->set_socket_options(std::move(socket_options)); } @@ -7379,13 +7465,33 @@ inline void Client::set_socket_options(SocketOptions socket_options) { inline void Client::set_connection_timeout(time_t sec, time_t usec) { cli_->set_connection_timeout(sec, usec); } + +template +inline void Client::set_connection_timeout( + const std::chrono::duration &duration) { + cli_->set_connection_timeout(duration); +} + inline void Client::set_read_timeout(time_t sec, time_t usec) { cli_->set_read_timeout(sec, usec); } + +template +inline void Client::set_read_timeout( + const std::chrono::duration &duration) { + cli_->set_read_timeout(duration); +} + inline void Client::set_write_timeout(time_t sec, time_t usec) { cli_->set_write_timeout(sec, usec); } +template +inline void Client::set_write_timeout( + const std::chrono::duration &duration) { + cli_->set_write_timeout(duration); +} + inline void Client::set_basic_auth(const char *username, const char *password) { cli_->set_basic_auth(username, password); } diff --git a/test/test.cc b/test/test.cc index 58f3c48..d7e5021 100644 --- a/test/test.cc +++ b/test/test.cc @@ -525,7 +525,7 @@ TEST(ConnectionErrorTest, InvalidHost) { auto port = 80; Client cli(host, port); #endif - cli.set_connection_timeout(2); + cli.set_connection_timeout(std::chrono::seconds(2)); auto res = cli.Get("/"); ASSERT_TRUE(!res); @@ -540,7 +540,7 @@ TEST(ConnectionErrorTest, InvalidHost2) { #else Client cli(host); #endif - cli.set_connection_timeout(2); + cli.set_connection_timeout(std::chrono::seconds(2)); auto res = cli.Get("/"); ASSERT_TRUE(!res); @@ -556,7 +556,7 @@ TEST(ConnectionErrorTest, InvalidPort) { #else Client cli(host, port); #endif - cli.set_connection_timeout(2); + cli.set_connection_timeout(std::chrono::seconds(2)); auto res = cli.Get("/"); ASSERT_TRUE(!res); @@ -573,7 +573,7 @@ TEST(ConnectionErrorTest, Timeout) { auto port = 8080; Client cli(host, port); #endif - cli.set_connection_timeout(2); + cli.set_connection_timeout(std::chrono::seconds(2)); auto res = cli.Get("/"); ASSERT_TRUE(!res); @@ -590,7 +590,7 @@ TEST(CancelTest, NoCancel) { auto port = 80; Client cli(host, port); #endif - cli.set_connection_timeout(5); + cli.set_connection_timeout(std::chrono::seconds(5)); auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; }); ASSERT_TRUE(res); @@ -610,7 +610,7 @@ TEST(CancelTest, WithCancelSmallPayload) { #endif auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; }); - cli.set_connection_timeout(5); + cli.set_connection_timeout(std::chrono::seconds(5)); ASSERT_TRUE(!res); EXPECT_EQ(Error::Canceled, res.error()); } @@ -625,7 +625,7 @@ TEST(CancelTest, WithCancelLargePayload) { auto port = 80; Client cli(host, port); #endif - cli.set_connection_timeout(5); + cli.set_connection_timeout(std::chrono::seconds(5)); uint32_t count = 0; auto res = cli.Get("/range/65536", @@ -2478,7 +2478,7 @@ TEST_F(ServerTest, SlowPostFail) { char buffer[64 * 1024]; memset(buffer, 0x42, sizeof(buffer)); - cli_.set_write_timeout(0, 0); + cli_.set_write_timeout(std::chrono::seconds(0)); auto res = cli_.Post("/slowpost", 64 * 1024 * 1024, [&](size_t /*offset*/, size_t /*length*/, DataSink &sink) { @@ -3146,7 +3146,7 @@ static void test_raw_request(const std::string &req, // bug to reproduce, probably to force the server to process a request // without a trailing blank line. const time_t client_read_timeout_sec = 1; - svr.set_read_timeout(client_read_timeout_sec + 1, 0); + svr.set_read_timeout(std::chrono::seconds(client_read_timeout_sec + 1)); bool listen_thread_ok = false; thread t = thread([&] { listen_thread_ok = svr.listen(HOST, PORT); }); while (!svr.is_running()) { @@ -3446,7 +3446,7 @@ TEST(KeepAliveTest, ReadTimeout) { Client cli("localhost", PORT); cli.set_keep_alive(true); - cli.set_read_timeout(1); + cli.set_read_timeout(std::chrono::seconds(1)); auto resa = cli.Get("/a"); ASSERT_TRUE(!resa); @@ -3583,7 +3583,7 @@ TEST(KeepAliveTest, ReadTimeoutSSL) { SSLClient cli("localhost", PORT); cli.enable_server_certificate_verification(false); cli.set_keep_alive(true); - cli.set_read_timeout(1); + cli.set_read_timeout(std::chrono::seconds(1)); auto resa = cli.Get("/a"); ASSERT_TRUE(!resa);