Fix #1481 (with content provider)

This commit is contained in:
yhirose 2023-03-13 22:11:33 -04:00
parent ed0719f2bc
commit a5bfddf17f
2 changed files with 68 additions and 1 deletions

View File

@ -8547,7 +8547,20 @@ inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl,
// the remote has closed the network connection
// Note that it is not always possible to avoid SIGPIPE, this is merely a
// best-efforts.
if (shutdown_gracefully) { SSL_shutdown(ssl); }
if (shutdown_gracefully) {
auto is_peer_could_be_closed = false;
{
char buf[1];
if (SSL_peek(ssl, buf, 1) == 0 &&
SSL_get_error(ssl, 0) == SSL_ERROR_ZERO_RETURN) {
is_peer_could_be_closed = true;
}
}
if (!is_peer_could_be_closed) {
SSL_shutdown(ssl);
}
}
std::lock_guard<std::mutex> guard(ctx_mutex);
SSL_free(ssl);

View File

@ -4996,6 +4996,60 @@ TEST(KeepAliveTest, SSLClientReconnection) {
ASSERT_TRUE(result);
EXPECT_EQ(StatusCode::OK_200, result->status);
}
TEST(KeepAliveTest, SSLClientReconnectionPost) {
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
ASSERT_TRUE(svr.is_valid());
svr.set_keep_alive_timeout(1);
std::string content = "reconnect";
svr.Post("/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.Post(
"/hi", content.size(),
[&content](size_t offset, size_t length, DataSink &sink) {
sink.write(content.c_str(), content.size());
return true;
},
"text/plain");
ASSERT_TRUE(result);
EXPECT_EQ(200, result->status);
std::this_thread::sleep_for(std::chrono::seconds(2));
// Recoonect
result = cli.Post(
"/hi", content.size(),
[&content](size_t offset, size_t length, DataSink &sink) {
sink.write(content.c_str(), content.size());
return true;
},
"text/plain");
ASSERT_TRUE(result);
EXPECT_EQ(200, result->status);
result = cli.Post(
"/hi", content.size(),
[&content](size_t offset, size_t length, DataSink &sink) {
sink.write(content.c_str(), content.size());
return true;
},
"text/plain");
ASSERT_TRUE(result);
EXPECT_EQ(200, result->status);
svr.stop();
f.wait();
}
#endif
TEST(ClientProblemDetectionTest, ContentProvider) {