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

Commit c7e959a

Browse files
committed
1 parent ba5884e commit c7e959a

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

httplib.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,9 @@ enum class Error {
854854
UnsupportedMultipartBoundaryChars,
855855
Compression,
856856
ConnectionTimeout,
857+
858+
// For internal use only
859+
SSLPeerCouldBeClosed_,
857860
};
858861

859862
std::string to_string(const Error error);
@@ -1126,8 +1129,6 @@ class ClientImpl {
11261129
bool is_open() const { return sock != INVALID_SOCKET; }
11271130
};
11281131

1129-
Result send_(Request &&req);
1130-
11311132
virtual bool create_and_connect_socket(Socket &socket, Error &error);
11321133

11331134
// All of:
@@ -1228,6 +1229,9 @@ class ClientImpl {
12281229
Logger logger_;
12291230

12301231
private:
1232+
bool send_(Request &req, Response &res, Error &error);
1233+
Result send_(Request &&req);
1234+
12311235
socket_t create_client_socket(Error &error) const;
12321236
bool read_response_line(Stream &strm, const Request &req, Response &res);
12331237
bool write_request(Stream &strm, Request &req, bool close_connection,
@@ -6278,7 +6282,15 @@ inline bool ClientImpl::read_response_line(Stream &strm, const Request &req,
62786282

62796283
inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
62806284
std::lock_guard<std::recursive_mutex> request_mutex_guard(request_mutex_);
6285+
auto ret = send_(req, res, error);
6286+
if (error == Error::SSLPeerCouldBeClosed_) {
6287+
assert(!ret);
6288+
ret = send_(req, res, error);
6289+
}
6290+
return ret;
6291+
}
62816292

6293+
inline bool ClientImpl::send_(Request &req, Response &res, Error &error) {
62826294
{
62836295
std::lock_guard<std::mutex> guard(socket_mutex_);
62846296

@@ -6289,13 +6301,6 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) {
62896301
auto is_alive = false;
62906302
if (socket_.is_open()) {
62916303
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
62996304
if (!is_alive) {
63006305
// Attempt to avoid sigpipe by shutting down nongracefully if it seems
63016306
// like the other side has already closed the connection Also, there
@@ -6757,6 +6762,16 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req,
67576762
// Send request
67586763
if (!write_request(strm, req, close_connection, error)) { return false; }
67596764

6765+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
6766+
if (is_ssl()) {
6767+
char buf[1];
6768+
if (SSL_peek(socket_.ssl, buf, 1) == 0) {
6769+
error = Error::SSLPeerCouldBeClosed_;
6770+
return false;
6771+
}
6772+
}
6773+
#endif
6774+
67606775
// Receive response and headers
67616776
if (!read_response_line(strm, req, res) ||
67626777
!detail::read_headers(strm, res.headers)) {

test/test.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,15 +4114,23 @@ TEST(KeepAliveTest, SSLClientReconnection) {
41144114
ASSERT_TRUE(result);
41154115
EXPECT_EQ(200, result->status);
41164116

4117+
result = cli.Get("/hi");
4118+
ASSERT_TRUE(result);
4119+
EXPECT_EQ(200, result->status);
4120+
41174121
std::this_thread::sleep_for(std::chrono::seconds(2));
41184122

4123+
// Recoonect
41194124
result = cli.Get("/hi");
4125+
ASSERT_TRUE(result);
4126+
EXPECT_EQ(200, result->status);
41204127

4121-
svr.stop();
4122-
f.wait();
4123-
4128+
result = cli.Get("/hi");
41244129
ASSERT_TRUE(result);
41254130
EXPECT_EQ(200, result->status);
4131+
4132+
svr.stop();
4133+
f.wait();
41264134
}
41274135
#endif
41284136

0 commit comments

Comments
 (0)