This commit is contained in:
yhirose 2023-03-03 23:45:19 -05:00 committed by GitHub
parent cdaa5c48db
commit ba5884e779
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 1 deletions

View file

@ -6289,6 +6289,13 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
auto is_alive = false;
if (socket_.is_open()) {
is_alive = detail::is_socket_alive(socket_.sock);
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
if (is_ssl() && is_alive) {
char buf[1];
auto n = SSL_peek(socket_.ssl, buf, 1);
if (n <= 0) { is_alive = false; }
}
#endif
if (!is_alive) {
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
// 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) {
auto ret = false;
auto close_connection = !keep_alive_;
auto se = detail::scope_exit<std::function<void (void)>>([&]() {
auto se = detail::scope_exit<std::function<void(void)>>([&]() {
// Briefly lock mutex in order to mark that a request is no longer ongoing
std::lock_guard<std::mutex> guard(socket_mutex_);
socket_requests_in_flight_ -= 1;

View file

@ -3871,6 +3871,32 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
ASSERT_FALSE(svr.is_running());
}
TEST(ServerStopTest, ClientAccessAfterServerDown) {
httplib::Server svr;
svr.Post("/hi", [&](const httplib::Request & /*req*/, httplib::Response &res) {
res.status = 200;
});
auto thread = std::thread([&]() { svr.listen(HOST, PORT); });
while (!svr.is_running()) {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
Client cli(HOST, PORT);
auto res = cli.Post("/hi", "data", "text/plain");
ASSERT_TRUE(res);
EXPECT_EQ(200, res->status);
svr.stop();
thread.join();
ASSERT_FALSE(svr.is_running());
res = cli.Post("/hi", "data", "text/plain");
ASSERT_FALSE(res);
}
TEST(StreamingTest, NoContentLengthStreaming) {
Server svr;
@ -4067,6 +4093,39 @@ TEST(KeepAliveTest, Issue1041) {
f.wait();
}
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
TEST(KeepAliveTest, SSLClientReconnection) {
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
ASSERT_TRUE(svr.is_valid());
svr.set_keep_alive_timeout(1);
svr.Get("/hi", [](const httplib::Request &, httplib::Response &res) {
res.set_content("Hello World!", "text/plain");
});
auto f = std::async(std::launch::async, [&svr] { svr.listen(HOST, PORT); });
std::this_thread::sleep_for(std::chrono::milliseconds(200));
SSLClient cli(HOST, PORT);
cli.enable_server_certificate_verification(false);
cli.set_keep_alive(true);
auto result = cli.Get("/hi");
ASSERT_TRUE(result);
EXPECT_EQ(200, result->status);
std::this_thread::sleep_for(std::chrono::seconds(2));
result = cli.Get("/hi");
svr.stop();
f.wait();
ASSERT_TRUE(result);
EXPECT_EQ(200, result->status);
}
#endif
TEST(ClientProblemDetectionTest, ContentProvider) {
Server svr;