Quellcode durchsuchen

Give WebSocketClient the chrono::duration timeout setters ClientImpl has

WebSocketClient only accepted timeouts as (time_t sec, time_t usec), while
ClientImpl has taken std::chrono::duration overloads for its read, write and
connection timeouts for a long time. Add the same three overloads, forwarding
through the existing detail::duration_to_sec_and_usec helper so the split
matches ClientImpl exactly.

The template bodies go above the first split.py BORDER, next to the class, so
that the .h/.cc split keeps them in the header where instantiation needs them.
yhirose vor 3 Tagen
Ursprung
Commit
a1aa2ad9cd
2 geänderte Dateien mit 55 neuen und 0 gelöschten Zeilen
  1. 33 0
      httplib.h
  2. 22 0
      test/test.cc

+ 33 - 0
httplib.h

@@ -4279,14 +4279,25 @@ public:
   bool is_open() const;
   const std::string &subprotocol() const;
   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);
+  template <class Rep, class Period>
+  void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
+
   void set_websocket_ping_interval(time_t sec);
   void set_websocket_max_missed_pongs(int count);
   void set_tcp_nodelay(bool on);
   void set_address_family(int family);
   void set_ipv6_v6only(bool on);
   void set_socket_options(SocketOptions socket_options);
+
   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_interface(const std::string &intf);
   void set_hostname_addr_map(std::map<std::string, std::string> addr_map);
 
@@ -4342,6 +4353,28 @@ private:
 #endif
 };
 
+template <class Rep, class Period>
+inline void WebSocketClient::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); });
+}
+
+template <class Rep, class Period>
+inline void WebSocketClient::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); });
+}
+
+template <class Rep, class Period>
+inline void WebSocketClient::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);
+  });
+}
+
 namespace impl {
 
 bool is_valid_utf8(const std::string &s);

+ 22 - 0
test/test.cc

@@ -20487,6 +20487,28 @@ TEST_F(WebSocketIntegrationTest, SocketSettings) {
   client.close();
 }
 
+TEST_F(WebSocketIntegrationTest, ChronoTimeoutSetters) {
+  ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) +
+                             "/ws-echo");
+  client.set_connection_timeout(std::chrono::seconds(3));
+  client.set_write_timeout(std::chrono::seconds(3));
+  // A sub-second remainder exercises the seconds/microseconds split.
+  client.set_read_timeout(std::chrono::milliseconds(1500));
+
+  ASSERT_TRUE(client.connect());
+
+  auto start = std::chrono::steady_clock::now();
+  std::string msg;
+  EXPECT_EQ(client.read(msg), ws::ReadResult::Fail);
+  auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
+                     std::chrono::steady_clock::now() - start)
+                     .count();
+  // Above 1s so that dropping the microseconds half of the split fails here,
+  // and well under the 300s default so that ignoring the setter fails too.
+  EXPECT_GE(elapsed, 1400);
+  EXPECT_LT(elapsed, 30000);
+}
+
 TEST(WebSocketPreRoutingTest, RejectWithoutAuth) {
   Server svr;