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.
This commit is contained in:
yhirose
2026-08-07 13:41:38 -04:00
parent b2b1d56d6d
commit a1aa2ad9cd
2 changed files with 55 additions and 0 deletions
+33
View File
@@ -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
View File
@@ -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;