yhirose 2 years ago
parent
commit
ba5884e779
2 changed files with 67 additions and 1 deletions
  1. 8 1
      httplib.h
  2. 59 0
      test/test.cc

+ 8 - 1
httplib.h

@@ -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;

+ 59 - 0
test/test.cc

@@ -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;