diff --git a/httplib.h b/httplib.h index 6c2323e..02e8719 100644 --- a/httplib.h +++ b/httplib.h @@ -24,6 +24,14 @@ #define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5 #endif +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300 +#endif + +#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND +#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0 +#endif + #ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND #define CPPHTTPLIB_READ_TIMEOUT_SECOND 5 #endif @@ -528,9 +536,10 @@ public: void set_expect_100_continue_handler(Expect100ContinueHandler handler); void set_keep_alive_max_count(size_t count); - void set_read_timeout(time_t sec, time_t usec); - void set_write_timeout(time_t sec, time_t usec); - void set_idle_interval(time_t sec, time_t usec); + void set_read_timeout(time_t sec, time_t usec = 0); + void set_write_timeout(time_t sec, time_t usec = 0); + void set_idle_interval(time_t sec, time_t usec = 0); + void set_payload_max_length(size_t length); bool bind_to_port(const char *host, int port, int socket_flags = 0); @@ -753,16 +762,14 @@ public: void stop(); - void set_timeout_sec(time_t timeout_sec); - - void set_read_timeout(time_t sec, time_t usec); - - void set_write_timeout(time_t sec, time_t usec); + [[deprecated]] void set_timeout_sec(time_t timeout_sec); + void set_connection_timeout(time_t sec, time_t usec = 0); + void set_read_timeout(time_t sec, time_t usec = 0); + void set_write_timeout(time_t sec, time_t usec = 0); void set_keep_alive_max_count(size_t count); void set_basic_auth(const char *username, const char *password); - #ifdef CPPHTTPLIB_OPENSSL_SUPPORT void set_digest_auth(const char *username, const char *password); #endif @@ -774,9 +781,7 @@ public: void set_interface(const char *intf); void set_proxy(const char *host, int port); - void set_proxy_basic_auth(const char *username, const char *password); - #ifdef CPPHTTPLIB_OPENSSL_SUPPORT void set_proxy_digest_auth(const char *username, const char *password); #endif @@ -797,7 +802,8 @@ protected: std::string client_cert_path_; std::string client_key_path_; - time_t timeout_sec_ = 300; + time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND; + time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND; time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND; time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND; time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND; @@ -833,7 +839,7 @@ protected: void copy_settings(const Client &rhs) { client_cert_path_ = rhs.client_cert_path_; client_key_path_ = rhs.client_key_path_; - timeout_sec_ = rhs.timeout_sec_; + connection_timeout_sec_ = rhs.connection_timeout_sec_; read_timeout_sec_ = rhs.read_timeout_sec_; read_timeout_usec_ = rhs.read_timeout_usec_; write_timeout_sec_ = rhs.write_timeout_sec_; @@ -1238,8 +1244,8 @@ public: void stop() { cli_->stop(); } - Client2 &set_timeout_sec(time_t timeout_sec) { - cli_->set_timeout_sec(timeout_sec); + Client2 &set_connection_timeout(time_t sec, time_t usec) { + cli_->set_connection_timeout(sec, usec); return *this; } @@ -1981,7 +1987,7 @@ inline std::string if2ip(const std::string &ifn) { #endif inline socket_t create_client_socket(const char *host, int port, - time_t timeout_sec, + time_t timeout_sec, time_t timeout_usec, const std::string &intf) { return create_socket( host, port, [&](socket_t sock, struct addrinfo &ai) -> bool { @@ -1999,7 +2005,7 @@ inline socket_t create_client_socket(const char *host, int port, ::connect(sock, ai.ai_addr, static_cast(ai.ai_addrlen)); if (ret < 0) { if (is_connection_error() || - !wait_until_socket_is_ready(sock, timeout_sec, 0)) { + !wait_until_socket_is_ready(sock, timeout_sec, timeout_usec)) { close_socket(sock); return false; } @@ -4238,10 +4244,12 @@ inline bool Client::is_valid() const { return true; } inline socket_t Client::create_client_socket() const { if (!proxy_host_.empty()) { return detail::create_client_socket(proxy_host_.c_str(), proxy_port_, - timeout_sec_, interface_); + connection_timeout_sec_, + connection_timeout_usec_, interface_); } - return detail::create_client_socket(host_.c_str(), port_, timeout_sec_, - interface_); + return detail::create_client_socket(host_.c_str(), port_, + connection_timeout_sec_, + connection_timeout_usec_, interface_); } inline bool Client::read_response_line(Stream &strm, Response &res) { @@ -4986,7 +4994,12 @@ inline void Client::stop() { } inline void Client::set_timeout_sec(time_t timeout_sec) { - timeout_sec_ = timeout_sec; + set_connection_timeout(timeout_sec, 0); +} + +inline void Client::set_connection_timeout(time_t sec, time_t usec) { + connection_timeout_sec_ = sec; + connection_timeout_usec_ = usec; } inline void Client::set_read_timeout(time_t sec, time_t usec) { diff --git a/test/test.cc b/test/test.cc index 7fa865a..e77c369 100644 --- a/test/test.cc +++ b/test/test.cc @@ -245,7 +245,7 @@ TEST(ChunkedEncodingTest, FromHTTPWatch) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); auto res = cli.Get("/httpgallery/chunked/chunkedimage.aspx?0.4153841143030137"); @@ -268,7 +268,7 @@ TEST(ChunkedEncodingTest, WithContentReceiver) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); std::string body; auto res = @@ -296,7 +296,7 @@ TEST(ChunkedEncodingTest, WithResponseHandlerAndContentReceiver) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); std::string body; auto res = cli.Get( @@ -328,7 +328,7 @@ TEST(RangeTest, FromHTTPBin) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(5); + cli.set_connection_timeout(5); { httplib::Headers headers; @@ -388,7 +388,7 @@ TEST(ConnectionErrorTest, InvalidHost) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); auto res = cli.Get("/"); ASSERT_TRUE(res == nullptr); @@ -404,7 +404,7 @@ TEST(ConnectionErrorTest, InvalidPort) { auto port = 8080; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); auto res = cli.Get("/"); ASSERT_TRUE(res == nullptr); @@ -420,7 +420,7 @@ TEST(ConnectionErrorTest, Timeout) { auto port = 8080; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(2); + cli.set_connection_timeout(2); auto res = cli.Get("/"); ASSERT_TRUE(res == nullptr); @@ -436,7 +436,7 @@ TEST(CancelTest, NoCancel) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(5); + cli.set_connection_timeout(5); auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; }); ASSERT_TRUE(res != nullptr); @@ -456,7 +456,7 @@ TEST(CancelTest, WithCancelSmallPayload) { #endif auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; }); - cli.set_timeout_sec(5); + cli.set_connection_timeout(5); ASSERT_TRUE(res == nullptr); } @@ -470,7 +470,7 @@ TEST(CancelTest, WithCancelLargePayload) { auto port = 80; httplib::Client cli(host, port); #endif - cli.set_timeout_sec(5); + cli.set_connection_timeout(5); uint32_t count = 0; httplib::Headers headers; @@ -2279,7 +2279,7 @@ TEST_F(ServerTest, MultipartFormDataGzip) { // Sends a raw request to a server listening at HOST:PORT. static bool send_request(time_t read_timeout_sec, const std::string &req, std::string *resp = nullptr) { - auto client_sock = detail::create_client_socket(HOST, PORT, /*timeout_sec=*/5, + auto client_sock = detail::create_client_socket(HOST, PORT, /*timeout_sec=*/5, 0, std::string()); if (client_sock == INVALID_SOCKET) { return false; } @@ -2774,7 +2774,7 @@ TEST(SSLClientServerTest, ClientCertPresent) { httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE); auto res = cli.Get("/test"); - cli.set_timeout_sec(30); + cli.set_connection_timeout(30); ASSERT_TRUE(res != nullptr); ASSERT_EQ(200, res->status); @@ -2843,7 +2843,7 @@ TEST(SSLClientServerTest, MemoryClientCertPresent) { httplib::SSLClient cli(HOST, PORT, client_cert, client_private_key); auto res = cli.Get("/test"); - cli.set_timeout_sec(30); + cli.set_connection_timeout(30); ASSERT_TRUE(res != nullptr); ASSERT_EQ(200, res->status); @@ -2867,7 +2867,7 @@ TEST(SSLClientServerTest, ClientCertMissing) { httplib::SSLClient cli(HOST, PORT); auto res = cli.Get("/test"); - cli.set_timeout_sec(30); + cli.set_connection_timeout(30); ASSERT_TRUE(res == nullptr); svr.stop(); @@ -2889,7 +2889,7 @@ TEST(SSLClientServerTest, TrustDirOptional) { httplib::SSLClient cli(HOST, PORT, CLIENT_CERT_FILE, CLIENT_PRIVATE_KEY_FILE); auto res = cli.Get("/test"); - cli.set_timeout_sec(30); + cli.set_connection_timeout(30); ASSERT_TRUE(res != nullptr); ASSERT_EQ(200, res->status);