Skip to content

Commit 6ff84d3

Browse files
authored
Another simpler implementation of #890 (#891)
1 parent b845425 commit 6ff84d3

File tree

2 files changed

+117
-11
lines changed

2 files changed

+117
-11
lines changed

httplib.h

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,9 +668,18 @@ class Server {
668668

669669
Server &set_keep_alive_max_count(size_t count);
670670
Server &set_keep_alive_timeout(time_t sec);
671+
671672
Server &set_read_timeout(time_t sec, time_t usec = 0);
673+
template <class Rep, class Period>
674+
Server &set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
675+
672676
Server &set_write_timeout(time_t sec, time_t usec = 0);
677+
template <class Rep, class Period>
678+
Server &set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
679+
673680
Server &set_idle_interval(time_t sec, time_t usec = 0);
681+
template <class Rep, class Period>
682+
Server &set_idle_interval(const std::chrono::duration<Rep, Period> &duration);
674683

675684
Server &set_payload_max_length(size_t length);
676685

@@ -966,8 +975,16 @@ class ClientImpl {
966975
void set_socket_options(SocketOptions socket_options);
967976

968977
void set_connection_timeout(time_t sec, time_t usec = 0);
978+
template <class Rep, class Period>
979+
void set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
980+
969981
void set_read_timeout(time_t sec, time_t usec = 0);
982+
template <class Rep, class Period>
983+
void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
984+
970985
void set_write_timeout(time_t sec, time_t usec = 0);
986+
template <class Rep, class Period>
987+
void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
971988

972989
void set_basic_auth(const char *username, const char *password);
973990
void set_bearer_token_auth(const char *token);
@@ -1268,8 +1285,16 @@ class Client {
12681285
void set_socket_options(SocketOptions socket_options);
12691286

12701287
void set_connection_timeout(time_t sec, time_t usec = 0);
1288+
template <class Rep, class Period>
1289+
void set_connection_timeout(const std::chrono::duration<Rep, Period> &duration);
1290+
12711291
void set_read_timeout(time_t sec, time_t usec = 0);
1292+
template <class Rep, class Period>
1293+
void set_read_timeout(const std::chrono::duration<Rep, Period> &duration);
1294+
12721295
void set_write_timeout(time_t sec, time_t usec = 0);
1296+
template <class Rep, class Period>
1297+
void set_write_timeout(const std::chrono::duration<Rep, Period> &duration);
12731298

12741299
void set_basic_auth(const char *username, const char *password);
12751300
void set_bearer_token_auth(const char *token);
@@ -3804,6 +3829,15 @@ class ContentProviderAdapter {
38043829
ContentProviderWithoutLength content_provider_;
38053830
};
38063831

3832+
template <typename T, typename U>
3833+
inline void duration_to_sec_and_usec(const T &duration, U callback) {
3834+
auto sec = std::chrono::duration_cast<std::chrono::seconds>(duration).count();
3835+
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(
3836+
duration - std::chrono::seconds(sec))
3837+
.count();
3838+
callback(sec, usec);
3839+
}
3840+
38073841
} // namespace detail
38083842

38093843
// Header utilities
@@ -4381,20 +4415,47 @@ inline Server &Server::set_read_timeout(time_t sec, time_t usec) {
43814415
return *this;
43824416
}
43834417

4418+
template <class Rep, class Period>
4419+
inline Server &Server::set_read_timeout(
4420+
const std::chrono::duration<Rep, Period> &duration) {
4421+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
4422+
set_read_timeout(sec, usec);
4423+
});
4424+
return *this;
4425+
}
4426+
43844427
inline Server &Server::set_write_timeout(time_t sec, time_t usec) {
43854428
write_timeout_sec_ = sec;
43864429
write_timeout_usec_ = usec;
43874430

43884431
return *this;
43894432
}
43904433

4434+
template <class Rep, class Period>
4435+
inline Server &Server::set_write_timeout(
4436+
const std::chrono::duration<Rep, Period> &duration) {
4437+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
4438+
set_write_timeout(sec, usec);
4439+
});
4440+
return *this;
4441+
}
4442+
43914443
inline Server &Server::set_idle_interval(time_t sec, time_t usec) {
43924444
idle_interval_sec_ = sec;
43934445
idle_interval_usec_ = usec;
43944446

43954447
return *this;
43964448
}
43974449

4450+
template <class Rep, class Period>
4451+
inline Server &Server::set_idle_interval(
4452+
const std::chrono::duration<Rep, Period> &duration) {
4453+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
4454+
set_idle_interval(sec, usec);
4455+
});
4456+
return *this;
4457+
}
4458+
43984459
inline Server &Server::set_payload_max_length(size_t length) {
43994460
payload_max_length_ = length;
44004461

@@ -6273,16 +6334,40 @@ inline void ClientImpl::set_connection_timeout(time_t sec, time_t usec) {
62736334
connection_timeout_usec_ = usec;
62746335
}
62756336

6337+
template <class Rep, class Period>
6338+
inline void ClientImpl::set_connection_timeout(
6339+
const std::chrono::duration<Rep, Period> &duration) {
6340+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
6341+
set_connection_timeout(sec, usec);
6342+
});
6343+
}
6344+
62766345
inline void ClientImpl::set_read_timeout(time_t sec, time_t usec) {
62776346
read_timeout_sec_ = sec;
62786347
read_timeout_usec_ = usec;
62796348
}
62806349

6350+
template <class Rep, class Period>
6351+
inline void ClientImpl::set_read_timeout(
6352+
const std::chrono::duration<Rep, Period> &duration) {
6353+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
6354+
set_read_timeout(sec, usec);
6355+
});
6356+
}
6357+
62816358
inline void ClientImpl::set_write_timeout(time_t sec, time_t usec) {
62826359
write_timeout_sec_ = sec;
62836360
write_timeout_usec_ = usec;
62846361
}
62856362

6363+
template <class Rep, class Period>
6364+
inline void ClientImpl::set_write_timeout(
6365+
const std::chrono::duration<Rep, Period> &duration) {
6366+
detail::duration_to_sec_and_usec(duration, [&](time_t sec, time_t usec) {
6367+
set_write_timeout(sec, usec);
6368+
});
6369+
}
6370+
62866371
inline void ClientImpl::set_basic_auth(const char *username,
62876372
const char *password) {
62886373
basic_auth_username_ = username;
@@ -7372,20 +7457,41 @@ inline void Client::set_default_headers(Headers headers) {
73727457
}
73737458

73747459
inline void Client::set_tcp_nodelay(bool on) { cli_->set_tcp_nodelay(on); }
7460+
73757461
inline void Client::set_socket_options(SocketOptions socket_options) {
73767462
cli_->set_socket_options(std::move(socket_options));
73777463
}
73787464

73797465
inline void Client::set_connection_timeout(time_t sec, time_t usec) {
73807466
cli_->set_connection_timeout(sec, usec);
73817467
}
7468+
7469+
template <class Rep, class Period>
7470+
inline void Client::set_connection_timeout(
7471+
const std::chrono::duration<Rep, Period> &duration) {
7472+
cli_->set_connection_timeout(duration);
7473+
}
7474+
73827475
inline void Client::set_read_timeout(time_t sec, time_t usec) {
73837476
cli_->set_read_timeout(sec, usec);
73847477
}
7478+
7479+
template <class Rep, class Period>
7480+
inline void Client::set_read_timeout(
7481+
const std::chrono::duration<Rep, Period> &duration) {
7482+
cli_->set_read_timeout(duration);
7483+
}
7484+
73857485
inline void Client::set_write_timeout(time_t sec, time_t usec) {
73867486
cli_->set_write_timeout(sec, usec);
73877487
}
73887488

7489+
template <class Rep, class Period>
7490+
inline void Client::set_write_timeout(
7491+
const std::chrono::duration<Rep, Period> &duration) {
7492+
cli_->set_write_timeout(duration);
7493+
}
7494+
73897495
inline void Client::set_basic_auth(const char *username, const char *password) {
73907496
cli_->set_basic_auth(username, password);
73917497
}

test/test.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ TEST(ConnectionErrorTest, InvalidHost) {
525525
auto port = 80;
526526
Client cli(host, port);
527527
#endif
528-
cli.set_connection_timeout(2);
528+
cli.set_connection_timeout(std::chrono::seconds(2));
529529

530530
auto res = cli.Get("/");
531531
ASSERT_TRUE(!res);
@@ -540,7 +540,7 @@ TEST(ConnectionErrorTest, InvalidHost2) {
540540
#else
541541
Client cli(host);
542542
#endif
543-
cli.set_connection_timeout(2);
543+
cli.set_connection_timeout(std::chrono::seconds(2));
544544

545545
auto res = cli.Get("/");
546546
ASSERT_TRUE(!res);
@@ -556,7 +556,7 @@ TEST(ConnectionErrorTest, InvalidPort) {
556556
#else
557557
Client cli(host, port);
558558
#endif
559-
cli.set_connection_timeout(2);
559+
cli.set_connection_timeout(std::chrono::seconds(2));
560560

561561
auto res = cli.Get("/");
562562
ASSERT_TRUE(!res);
@@ -573,7 +573,7 @@ TEST(ConnectionErrorTest, Timeout) {
573573
auto port = 8080;
574574
Client cli(host, port);
575575
#endif
576-
cli.set_connection_timeout(2);
576+
cli.set_connection_timeout(std::chrono::seconds(2));
577577

578578
auto res = cli.Get("/");
579579
ASSERT_TRUE(!res);
@@ -590,7 +590,7 @@ TEST(CancelTest, NoCancel) {
590590
auto port = 80;
591591
Client cli(host, port);
592592
#endif
593-
cli.set_connection_timeout(5);
593+
cli.set_connection_timeout(std::chrono::seconds(5));
594594

595595
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return true; });
596596
ASSERT_TRUE(res);
@@ -610,7 +610,7 @@ TEST(CancelTest, WithCancelSmallPayload) {
610610
#endif
611611

612612
auto res = cli.Get("/range/32", [](uint64_t, uint64_t) { return false; });
613-
cli.set_connection_timeout(5);
613+
cli.set_connection_timeout(std::chrono::seconds(5));
614614
ASSERT_TRUE(!res);
615615
EXPECT_EQ(Error::Canceled, res.error());
616616
}
@@ -625,7 +625,7 @@ TEST(CancelTest, WithCancelLargePayload) {
625625
auto port = 80;
626626
Client cli(host, port);
627627
#endif
628-
cli.set_connection_timeout(5);
628+
cli.set_connection_timeout(std::chrono::seconds(5));
629629

630630
uint32_t count = 0;
631631
auto res = cli.Get("/range/65536",
@@ -2478,7 +2478,7 @@ TEST_F(ServerTest, SlowPostFail) {
24782478
char buffer[64 * 1024];
24792479
memset(buffer, 0x42, sizeof(buffer));
24802480

2481-
cli_.set_write_timeout(0, 0);
2481+
cli_.set_write_timeout(std::chrono::seconds(0));
24822482
auto res =
24832483
cli_.Post("/slowpost", 64 * 1024 * 1024,
24842484
[&](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
@@ -3146,7 +3146,7 @@ static void test_raw_request(const std::string &req,
31463146
// bug to reproduce, probably to force the server to process a request
31473147
// without a trailing blank line.
31483148
const time_t client_read_timeout_sec = 1;
3149-
svr.set_read_timeout(client_read_timeout_sec + 1, 0);
3149+
svr.set_read_timeout(std::chrono::seconds(client_read_timeout_sec + 1));
31503150
bool listen_thread_ok = false;
31513151
thread t = thread([&] { listen_thread_ok = svr.listen(HOST, PORT); });
31523152
while (!svr.is_running()) {
@@ -3446,7 +3446,7 @@ TEST(KeepAliveTest, ReadTimeout) {
34463446

34473447
Client cli("localhost", PORT);
34483448
cli.set_keep_alive(true);
3449-
cli.set_read_timeout(1);
3449+
cli.set_read_timeout(std::chrono::seconds(1));
34503450

34513451
auto resa = cli.Get("/a");
34523452
ASSERT_TRUE(!resa);
@@ -3583,7 +3583,7 @@ TEST(KeepAliveTest, ReadTimeoutSSL) {
35833583
SSLClient cli("localhost", PORT);
35843584
cli.enable_server_certificate_verification(false);
35853585
cli.set_keep_alive(true);
3586-
cli.set_read_timeout(1);
3586+
cli.set_read_timeout(std::chrono::seconds(1));
35873587

35883588
auto resa = cli.Get("/a");
35893589
ASSERT_TRUE(!resa);

0 commit comments

Comments
 (0)