Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Commit ba5884e

Browse files
authored
1 parent cdaa5c4 commit ba5884e

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

httplib.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6289,6 +6289,13 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
62896289
auto is_alive = false;
62906290
if (socket_.is_open()) {
62916291
is_alive = detail::is_socket_alive(socket_.sock);
6292+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
6293+
if (is_ssl() && is_alive) {
6294+
char buf[1];
6295+
auto n = SSL_peek(socket_.ssl, buf, 1);
6296+
if (n <= 0) { is_alive = false; }
6297+
}
6298+
#endif
62926299
if (!is_alive) {
62936300
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
62946301
// like the other side has already closed the connection Also, there
@@ -6339,7 +6346,7 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
63396346
auto ret = false;
63406347
auto close_connection = !keep_alive_;
63416348

6342-
auto se = detail::scope_exit<std::function<void (void)>>([&]() {
6349+
auto se = detail::scope_exit<std::function<void(void)>>([&]() {
63436350
// Briefly lock mutex in order to mark that a request is no longer ongoing
63446351
std::lock_guard<std::mutex> guard(socket_mutex_);
63456352
socket_requests_in_flight_ -= 1;

test/test.cc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,6 +3871,32 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
38713871
ASSERT_FALSE(svr.is_running());
38723872
}
38733873

3874+
TEST(ServerStopTest, ClientAccessAfterServerDown) {
3875+
httplib::Server svr;
3876+
svr.Post("/hi", [&](const httplib::Request & /*req*/, httplib::Response &res) {
3877+
res.status = 200;
3878+
});
3879+
3880+
auto thread = std::thread([&]() { svr.listen(HOST, PORT); });
3881+
3882+
while (!svr.is_running()) {
3883+
std::this_thread::sleep_for(std::chrono::milliseconds(5));
3884+
}
3885+
3886+
Client cli(HOST, PORT);
3887+
3888+
auto res = cli.Post("/hi", "data", "text/plain");
3889+
ASSERT_TRUE(res);
3890+
EXPECT_EQ(200, res->status);
3891+
3892+
svr.stop();
3893+
thread.join();
3894+
ASSERT_FALSE(svr.is_running());
3895+
3896+
res = cli.Post("/hi", "data", "text/plain");
3897+
ASSERT_FALSE(res);
3898+
}
3899+
38743900
TEST(StreamingTest, NoContentLengthStreaming) {
38753901
Server svr;
38763902

@@ -4067,6 +4093,39 @@ TEST(KeepAliveTest, Issue1041) {
40674093
f.wait();
40684094
}
40694095

4096+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
4097+
TEST(KeepAliveTest, SSLClientReconnection) {
4098+
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
4099+
ASSERT_TRUE(svr.is_valid());
4100+
svr.set_keep_alive_timeout(1);
4101+
4102+
svr.Get("/hi", [](const httplib::Request &, httplib::Response &res) {
4103+
res.set_content("Hello World!", "text/plain");
4104+
});
4105+
4106+
auto f = std::async(std::launch::async, [&svr] { svr.listen(HOST, PORT); });
4107+
std::this_thread::sleep_for(std::chrono::milliseconds(200));
4108+
4109+
SSLClient cli(HOST, PORT);
4110+
cli.enable_server_certificate_verification(false);
4111+
cli.set_keep_alive(true);
4112+
4113+
auto result = cli.Get("/hi");
4114+
ASSERT_TRUE(result);
4115+
EXPECT_EQ(200, result->status);
4116+
4117+
std::this_thread::sleep_for(std::chrono::seconds(2));
4118+
4119+
result = cli.Get("/hi");
4120+
4121+
svr.stop();
4122+
f.wait();
4123+
4124+
ASSERT_TRUE(result);
4125+
EXPECT_EQ(200, result->status);
4126+
}
4127+
#endif
4128+
40704129
TEST(ClientProblemDetectionTest, ContentProvider) {
40714130
Server svr;
40724131

0 commit comments

Comments
 (0)