Browse Source

Another simpler implementation of #890 (#891)

yhirose 4 years ago
parent
commit
6ff84d34d1
2 changed files with 117 additions and 11 deletions
  1. 106 0
      httplib.h
  2. 11 11
      test/test.cc

+ 106 - 0
httplib.h

@@ -668,9 +668,18 @@ public:
 
 
   Server &set_keep_alive_max_count(size_t count);
   Server &set_keep_alive_max_count(size_t count);
   Server &set_keep_alive_timeout(time_t sec);
   Server &set_keep_alive_timeout(time_t sec);
+
   Server &set_read_timeout(time_t sec, time_t usec = 0);
   Server &set_read_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  Server &set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   Server &set_write_timeout(time_t sec, time_t usec = 0);
   Server &set_write_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  Server &set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   Server &set_idle_interval(time_t sec, time_t usec = 0);
   Server &set_idle_interval(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  Server &set_idle_interval(const std::chrono::duration<Rep, Period> &duration);
 
 
   Server &set_payload_max_length(size_t length);
   Server &set_payload_max_length(size_t length);
 
 
@@ -966,8 +975,16 @@ public:
   void set_socket_options(SocketOptions socket_options);
   void set_socket_options(SocketOptions socket_options);
 
 
   void set_connection_timeout(time_t sec, time_t usec = 0);
   void set_connection_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   void set_read_timeout(time_t sec, time_t usec = 0);
   void set_read_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   void set_write_timeout(time_t sec, time_t usec = 0);
   void set_write_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
 
 
   void set_basic_auth(const char *username, const char *password);
   void set_basic_auth(const char *username, const char *password);
   void set_bearer_token_auth(const char *token);
   void set_bearer_token_auth(const char *token);
@@ -1268,8 +1285,16 @@ public:
   void set_socket_options(SocketOptions socket_options);
   void set_socket_options(SocketOptions socket_options);
 
 
   void set_connection_timeout(time_t sec, time_t usec = 0);
   void set_connection_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   void set_read_timeout(time_t sec, time_t usec = 0);
   void set_read_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   void set_write_timeout(time_t sec, time_t usec = 0);
   void set_write_timeout(time_t sec, time_t usec = 0);
+  template <class Rep, class Period>
+  void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
 
 
   void set_basic_auth(const char *username, const char *password);
   void set_basic_auth(const char *username, const char *password);
   void set_bearer_token_auth(const char *token);
   void set_bearer_token_auth(const char *token);
@@ -3804,6 +3829,15 @@ private:
   ContentProviderWithoutLength content_provider_;
   ContentProviderWithoutLength content_provider_;
 };
 };
 
 
+template <typename T, typename U>
+inline void duration_to_sec_and_usec(const T &duration, U callback) {
+  auto sec = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
+  auto usec = std::chrono::duration_cast<std::chrono::microseconds>(
+                  duration - std::chrono::seconds(sec))
+                  .count();
+  callback(sec, usec);
+}
+
 } // namespace detail
 } // namespace detail
 
 
 // Header utilities
 // Header utilities
@@ -4381,6 +4415,15 @@ inline Server &Server::set_read_timeout(time_t sec, time_t usec) {
   return *this;
   return *this;
 }
 }
 
 
+template <class Rep, class Period>
+inline Server &Server::set_read_timeout(
+  const std::chrono::duration<Rep, Period> &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) {
 inline Server &Server::set_write_timeout(time_t sec, time_t usec) {
   write_timeout_sec_ = sec;
   write_timeout_sec_ = sec;
   write_timeout_usec_ = usec;
   write_timeout_usec_ = usec;
@@ -4388,6 +4431,15 @@ inline Server &Server::set_write_timeout(time_t sec, time_t usec) {
   return *this;
   return *this;
 }
 }
 
 
+template <class Rep, class Period>
+inline Server &Server::set_write_timeout(
+  const std::chrono::duration<Rep, Period> &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) {
 inline Server &Server::set_idle_interval(time_t sec, time_t usec) {
   idle_interval_sec_ = sec;
   idle_interval_sec_ = sec;
   idle_interval_usec_ = usec;
   idle_interval_usec_ = usec;
@@ -4395,6 +4447,15 @@ inline Server &Server::set_idle_interval(time_t sec, time_t usec) {
   return *this;
   return *this;
 }
 }
 
 
+template <class Rep, class Period>
+inline Server &Server::set_idle_interval(
+  const std::chrono::duration<Rep, Period> &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) {
 inline Server &Server::set_payload_max_length(size_t length) {
   payload_max_length_ = 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;
   connection_timeout_usec_ = usec;
 }
 }
 
 
+template <class Rep, class Period>
+inline void ClientImpl::set_connection_timeout(
+  const std::chrono::duration<Rep, Period> &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) {
 inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) {
   read_timeout_sec_ = sec;
   read_timeout_sec_ = sec;
   read_timeout_usec_ = usec;
   read_timeout_usec_ = usec;
 }
 }
 
 
+template <class Rep, class Period>
+inline void ClientImpl::set_read_timeout(
+  const std::chrono::duration<Rep, Period> &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) {
 inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) {
   write_timeout_sec_ = sec;
   write_timeout_sec_ = sec;
   write_timeout_usec_ = usec;
   write_timeout_usec_ = usec;
 }
 }
 
 
+template <class Rep, class Period>
+inline void ClientImpl::set_write_timeout(
+  const std::chrono::duration<Rep, Period> &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,
 inline void ClientImpl::set_basic_auth(const char *username,
                                        const char *password) {
                                        const char *password) {
   basic_auth_username_ = username;
   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_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); }
+
 inline void Client::set_socket_options(SocketOptions socket_options) {
 inline void Client::set_socket_options(SocketOptions socket_options) {
   cli_->set_socket_options(std::move(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) {
 inline void Client::set_connection_timeout(time_t sec, time_t usec) {
   cli_->set_connection_timeout(sec, usec);
   cli_->set_connection_timeout(sec, usec);
 }
 }
+
+template <class Rep, class Period>
+inline void Client::set_connection_timeout(
+  const std::chrono::duration<Rep, Period> &duration) {
+  cli_->set_connection_timeout(duration);
+}
+
 inline void Client::set_read_timeout(time_t sec, time_t usec) {
 inline void Client::set_read_timeout(time_t sec, time_t usec) {
   cli_->set_read_timeout(sec, usec);
   cli_->set_read_timeout(sec, usec);
 }
 }
+
+template <class Rep, class Period>
+inline void Client::set_read_timeout(
+  const std::chrono::duration<Rep, Period> &duration) {
+  cli_->set_read_timeout(duration);
+}
+
 inline void Client::set_write_timeout(time_t sec, time_t usec) {
 inline void Client::set_write_timeout(time_t sec, time_t usec) {
   cli_->set_write_timeout(sec, usec);
   cli_->set_write_timeout(sec, usec);
 }
 }
 
 
+template <class Rep, class Period>
+inline void Client::set_write_timeout(
+  const std::chrono::duration<Rep, Period> &duration) {
+  cli_->set_write_timeout(duration);
+}
+
 inline void Client::set_basic_auth(const char *username, const char *password) {
 inline void Client::set_basic_auth(const char *username, const char *password) {
   cli_->set_basic_auth(username, password);
   cli_->set_basic_auth(username, password);
 }
 }

+ 11 - 11
test/test.cc

@@ -525,7 +525,7 @@ TEST(ConnectionErrorTest, InvalidHost) {
   auto port = 80;
   auto port = 80;
   Client cli(host, port);
   Client cli(host, port);
 #endif
 #endif
-  cli.set_connection_timeout(2);
+  cli.set_connection_timeout(std::chrono::seconds(2));
 
 
   auto res = cli.Get("/");
   auto res = cli.Get("/");
   ASSERT_TRUE(!res);
   ASSERT_TRUE(!res);
@@ -540,7 +540,7 @@ TEST(ConnectionErrorTest, InvalidHost2) {
 #else
 #else
   Client cli(host);
   Client cli(host);
 #endif
 #endif
-  cli.set_connection_timeout(2);
+  cli.set_connection_timeout(std::chrono::seconds(2));
 
 
   auto res = cli.Get("/");
   auto res = cli.Get("/");
   ASSERT_TRUE(!res);
   ASSERT_TRUE(!res);
@@ -556,7 +556,7 @@ TEST(ConnectionErrorTest, InvalidPort) {
 #else
 #else
   Client cli(host, port);
   Client cli(host, port);
 #endif
 #endif
-  cli.set_connection_timeout(2);
+  cli.set_connection_timeout(std::chrono::seconds(2));
 
 
   auto res = cli.Get("/");
   auto res = cli.Get("/");
   ASSERT_TRUE(!res);
   ASSERT_TRUE(!res);
@@ -573,7 +573,7 @@ TEST(ConnectionErrorTest, Timeout) {
   auto port = 8080;
   auto port = 8080;
   Client cli(host, port);
   Client cli(host, port);
 #endif
 #endif
-  cli.set_connection_timeout(2);
+  cli.set_connection_timeout(std::chrono::seconds(2));
 
 
   auto res = cli.Get("/");
   auto res = cli.Get("/");
   ASSERT_TRUE(!res);
   ASSERT_TRUE(!res);
@@ -590,7 +590,7 @@ TEST(CancelTest, NoCancel) {
   auto port = 80;
   auto port = 80;
   Client cli(host, port);
   Client cli(host, port);
 #endif
 #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; });
   auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
   ASSERT_TRUE(res);
   ASSERT_TRUE(res);
@@ -610,7 +610,7 @@ TEST(CancelTest, WithCancelSmallPayload) {
 #endif
 #endif
 
 
   auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; });
   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);
   ASSERT_TRUE(!res);
   EXPECT_EQ(Error::Canceled, res.error());
   EXPECT_EQ(Error::Canceled, res.error());
 }
 }
@@ -625,7 +625,7 @@ TEST(CancelTest, WithCancelLargePayload) {
   auto port = 80;
   auto port = 80;
   Client cli(host, port);
   Client cli(host, port);
 #endif
 #endif
-  cli.set_connection_timeout(5);
+  cli.set_connection_timeout(std::chrono::seconds(5));
 
 
   uint32_t count = 0;
   uint32_t count = 0;
   auto res = cli.Get("/range/65536",
   auto res = cli.Get("/range/65536",
@@ -2478,7 +2478,7 @@ TEST_F(ServerTest, SlowPostFail) {
   char buffer[64 * 1024];
   char buffer[64 * 1024];
   memset(buffer, 0x42, sizeof(buffer));
   memset(buffer, 0x42, sizeof(buffer));
 
 
-  cli_.set_write_timeout(0, 0);
+  cli_.set_write_timeout(std::chrono::seconds(0));
   auto res =
   auto res =
       cli_.Post("/slowpost", 64 * 1024 * 1024,
       cli_.Post("/slowpost", 64 * 1024 * 1024,
                 [&](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
                 [&](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
   // bug to reproduce, probably to force the server to process a request
   // without a trailing blank line.
   // without a trailing blank line.
   const time_t client_read_timeout_sec = 1;
   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;
   bool listen_thread_ok = false;
   thread t = thread([&] { listen_thread_ok = svr.listen(HOST, PORT); });
   thread t = thread([&] { listen_thread_ok = svr.listen(HOST, PORT); });
   while (!svr.is_running()) {
   while (!svr.is_running()) {
@@ -3446,7 +3446,7 @@ TEST(KeepAliveTest, ReadTimeout) {
 
 
   Client cli("localhost", PORT);
   Client cli("localhost", PORT);
   cli.set_keep_alive(true);
   cli.set_keep_alive(true);
-  cli.set_read_timeout(1);
+  cli.set_read_timeout(std::chrono::seconds(1));
 
 
   auto resa = cli.Get("/a");
   auto resa = cli.Get("/a");
   ASSERT_TRUE(!resa);
   ASSERT_TRUE(!resa);
@@ -3583,7 +3583,7 @@ TEST(KeepAliveTest, ReadTimeoutSSL) {
   SSLClient cli("localhost", PORT);
   SSLClient cli("localhost", PORT);
   cli.enable_server_certificate_verification(false);
   cli.enable_server_certificate_verification(false);
   cli.set_keep_alive(true);
   cli.set_keep_alive(true);
-  cli.set_read_timeout(1);
+  cli.set_read_timeout(std::chrono::seconds(1));
 
 
   auto resa = cli.Get("/a");
   auto resa = cli.Get("/a");
   ASSERT_TRUE(!resa);
   ASSERT_TRUE(!resa);