Skip to content

Another simpler implementation of #890 #891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions httplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,18 @@ class Server {

Server &set_keep_alive_max_count(size_t count);
Server &set_keep_alive_timeout(time_t sec);

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);
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);
template <class Rep, class Period>
Server &set_idle_interval(const std::chrono::duration<Rep, Period> &duration);

Server &set_payload_max_length(size_t length);

Expand Down Expand Up @@ -966,8 +975,16 @@ class ClientImpl {
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_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_basic_auth(const char *username, const char *password);
void set_bearer_token_auth(const char *token);
Expand Down Expand Up @@ -1268,8 +1285,16 @@ class Client {
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_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_basic_auth(const char *username, const char *password);
void set_bearer_token_auth(const char *token);
Expand Down Expand Up @@ -3804,6 +3829,15 @@ class ContentProviderAdapter {
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

// Header utilities
Expand Down Expand Up @@ -4381,20 +4415,47 @@ inline Server &Server::set_read_timeout(time_t sec, time_t usec) {
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) {
write_timeout_sec_ = sec;
write_timeout_usec_ = usec;

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) {
idle_interval_sec_ = sec;
idle_interval_usec_ = usec;

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) {
payload_max_length_ = length;

Expand Down Expand Up @@ -6273,16 +6334,40 @@ inline void ClientImpl::set_connection_timeout(time_t sec, time_t 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) {
read_timeout_sec_ = sec;
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) {
write_timeout_sec_ = sec;
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,
const char *password) {
basic_auth_username_ = username;
Expand Down Expand Up @@ -7372,20 +7457,41 @@ 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_socket_options(SocketOptions socket_options) {
cli_->set_socket_options(std::move(socket_options));
}

inline void Client::set_connection_timeout(time_t sec, time_t 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) {
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) {
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) {
cli_->set_basic_auth(username, password);
}
Expand Down
22 changes: 11 additions & 11 deletions test/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ TEST(ConnectionErrorTest, InvalidHost) {
auto port = 80;
Client cli(host, port);
#endif
cli.set_connection_timeout(2);
cli.set_connection_timeout(std::chrono::seconds(2));

auto res = cli.Get("/");
ASSERT_TRUE(!res);
Expand All @@ -540,7 +540,7 @@ TEST(ConnectionErrorTest, InvalidHost2) {
#else
Client cli(host);
#endif
cli.set_connection_timeout(2);
cli.set_connection_timeout(std::chrono::seconds(2));

auto res = cli.Get("/");
ASSERT_TRUE(!res);
Expand All @@ -556,7 +556,7 @@ TEST(ConnectionErrorTest, InvalidPort) {
#else
Client cli(host, port);
#endif
cli.set_connection_timeout(2);
cli.set_connection_timeout(std::chrono::seconds(2));

auto res = cli.Get("/");
ASSERT_TRUE(!res);
Expand All @@ -573,7 +573,7 @@ TEST(ConnectionErrorTest, Timeout) {
auto port = 8080;
Client cli(host, port);
#endif
cli.set_connection_timeout(2);
cli.set_connection_timeout(std::chrono::seconds(2));

auto res = cli.Get("/");
ASSERT_TRUE(!res);
Expand All @@ -590,7 +590,7 @@ TEST(CancelTest, NoCancel) {
auto port = 80;
Client cli(host, port);
#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; });
ASSERT_TRUE(res);
Expand All @@ -610,7 +610,7 @@ TEST(CancelTest, WithCancelSmallPayload) {
#endif

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);
EXPECT_EQ(Error::Canceled, res.error());
}
Expand All @@ -625,7 +625,7 @@ TEST(CancelTest, WithCancelLargePayload) {
auto port = 80;
Client cli(host, port);
#endif
cli.set_connection_timeout(5);
cli.set_connection_timeout(std::chrono::seconds(5));

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

cli_.set_write_timeout(0, 0);
cli_.set_write_timeout(std::chrono::seconds(0));
auto res =
cli_.Post("/slowpost", 64 * 1024 * 1024,
[&](size_t /*offset*/, size_t /*length*/, DataSink &sink) {
Expand Down Expand Up @@ -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
// without a trailing blank line.
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;
thread t = thread([&] { listen_thread_ok = svr.listen(HOST, PORT); });
while (!svr.is_running()) {
Expand Down Expand Up @@ -3446,7 +3446,7 @@ TEST(KeepAliveTest, ReadTimeout) {

Client cli("localhost", PORT);
cli.set_keep_alive(true);
cli.set_read_timeout(1);
cli.set_read_timeout(std::chrono::seconds(1));

auto resa = cli.Get("/a");
ASSERT_TRUE(!resa);
Expand Down Expand Up @@ -3583,7 +3583,7 @@ TEST(KeepAliveTest, ReadTimeoutSSL) {
SSLClient cli("localhost", PORT);
cli.enable_server_certificate_verification(false);
cli.set_keep_alive(true);
cli.set_read_timeout(1);
cli.set_read_timeout(std::chrono::seconds(1));

auto resa = cli.Get("/a");
ASSERT_TRUE(!resa);
Expand Down