Skip to content

Commit

Permalink
Fix #1959
Browse files Browse the repository at this point in the history
  • Loading branch information
cschreib-ibex committed Oct 9, 2024
1 parent 131bc6c commit 753f5b0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
15 changes: 13 additions & 2 deletions httplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -3251,6 +3251,18 @@ class SSLSocketStream final : public Stream {
};
#endif

bool keep_alive(const std::atomic<socket_t> &svr_sock, socket_t sock,
time_t keep_alive_timeout_sec) {
using namespace std::chrono;
const auto start = steady_clock::now();
while (svr_sock != INVALID_SOCKET &&
(steady_clock::now() - start) < seconds(keep_alive_timeout_sec)) {
if (select_read(sock, 0, 10000) > 0) { return true; }
}

return false;
}

template <typename T>
inline bool
process_server_socket_core(const std::atomic<socket_t> &svr_sock, socket_t sock,
Expand All @@ -3259,8 +3271,7 @@ process_server_socket_core(const std::atomic<socket_t> &svr_sock, socket_t sock,
assert(keep_alive_max_count > 0);
auto ret = false;
auto count = keep_alive_max_count;
while (svr_sock != INVALID_SOCKET && count > 0 &&
select_read(sock, keep_alive_timeout_sec, 0) > 0) {
while (keep_alive(svr_sock, sock, keep_alive_timeout_sec) && count > 0) {
auto close_connection = count == 1;
auto connection_closed = false;
ret = callback(close_connection, connection_closed);
Expand Down
34 changes: 34 additions & 0 deletions test/test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5268,6 +5268,40 @@ TEST(KeepAliveTest, Issue1041) {
EXPECT_EQ(StatusCode::OK_200, result->status);
}

TEST(KeepAliveTest, Issue1959) {
Server svr;
svr.set_keep_alive_timeout(5);

svr.Get("/a", [&](const Request & /*req*/, Response &res) {
res.set_content("a", "text/plain");
});

auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });
auto se = detail::scope_exit([&] {
if (!svr.is_running()) return;
svr.stop();
listen_thread.join();
ASSERT_FALSE(svr.is_running());
});

svr.wait_until_ready();

Client cli("localhost", PORT);
cli.set_keep_alive(true);

using namespace std::chrono;
auto start = steady_clock::now();

cli.Get("/a");

svr.stop();
listen_thread.join();

auto end = steady_clock::now();

EXPECT_LT(duration_cast<milliseconds>(end - start).count(), 5000);
}

#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(KeepAliveTest, SSLClientReconnection) {
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
Expand Down

0 comments on commit 753f5b0

Please sign in to comment.