Skip to content

Commit a5bfddf

Browse files
committed
Fix #1481 (with content provider)
1 parent ed0719f commit a5bfddf

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

httplib.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8547,7 +8547,20 @@ inline void ssl_delete(std::mutex &ctx_mutex, SSL *ssl,
85478547
// the remote has closed the network connection
85488548
// Note that it is not always possible to avoid SIGPIPE, this is merely a
85498549
// best-efforts.
8550-
if (shutdown_gracefully) { SSL_shutdown(ssl); }
8550+
if (shutdown_gracefully) {
8551+
auto is_peer_could_be_closed = false;
8552+
{
8553+
char buf[1];
8554+
if (SSL_peek(ssl, buf, 1) == 0 &&
8555+
SSL_get_error(ssl, 0) == SSL_ERROR_ZERO_RETURN) {
8556+
is_peer_could_be_closed = true;
8557+
}
8558+
}
8559+
8560+
if (!is_peer_could_be_closed) {
8561+
SSL_shutdown(ssl);
8562+
}
8563+
}
85518564

85528565
std::lock_guard<std::mutex> guard(ctx_mutex);
85538566
SSL_free(ssl);

test/test.cc

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4996,6 +4996,60 @@ TEST(KeepAliveTest, SSLClientReconnection) {
49964996
ASSERT_TRUE(result);
49974997
EXPECT_EQ(StatusCode::OK_200, result->status);
49984998
}
4999+
5000+
TEST(KeepAliveTest, SSLClientReconnectionPost) {
5001+
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);
5002+
ASSERT_TRUE(svr.is_valid());
5003+
svr.set_keep_alive_timeout(1);
5004+
std::string content = "reconnect";
5005+
5006+
svr.Post("/hi", [](const httplib::Request &, httplib::Response &res) {
5007+
res.set_content("Hello World!", "text/plain");
5008+
});
5009+
5010+
auto f = std::async(std::launch::async, [&svr] { svr.listen(HOST, PORT); });
5011+
std::this_thread::sleep_for(std::chrono::milliseconds(200));
5012+
5013+
SSLClient cli(HOST, PORT);
5014+
cli.enable_server_certificate_verification(false);
5015+
cli.set_keep_alive(true);
5016+
5017+
auto result = cli.Post(
5018+
"/hi", content.size(),
5019+
[&content](size_t offset, size_t length, DataSink &sink) {
5020+
sink.write(content.c_str(), content.size());
5021+
return true;
5022+
},
5023+
"text/plain");
5024+
ASSERT_TRUE(result);
5025+
EXPECT_EQ(200, result->status);
5026+
5027+
std::this_thread::sleep_for(std::chrono::seconds(2));
5028+
5029+
// Recoonect
5030+
result = cli.Post(
5031+
"/hi", content.size(),
5032+
[&content](size_t offset, size_t length, DataSink &sink) {
5033+
sink.write(content.c_str(), content.size());
5034+
return true;
5035+
},
5036+
"text/plain");
5037+
ASSERT_TRUE(result);
5038+
EXPECT_EQ(200, result->status);
5039+
5040+
result = cli.Post(
5041+
"/hi", content.size(),
5042+
[&content](size_t offset, size_t length, DataSink &sink) {
5043+
sink.write(content.c_str(), content.size());
5044+
return true;
5045+
},
5046+
"text/plain");
5047+
ASSERT_TRUE(result);
5048+
EXPECT_EQ(200, result->status);
5049+
5050+
svr.stop();
5051+
f.wait();
5052+
}
49995053
#endif
50005054

50015055
TEST(ClientProblemDetectionTest, ContentProvider) {

0 commit comments

Comments
 (0)