From 23ff9a56055bce4df26f9d421d3e5a1a5a0cb379 Mon Sep 17 00:00:00 2001 From: Alex Kasko Date: Thu, 18 Sep 2025 13:44:39 +0100 Subject: [PATCH 1/2] Fix error reporting in SSLClient When the `SSLClient` is used to connect to a plain-HTTP server (which can happen in clients due to some end-user misconfiguration) it can return a failure from the `send()` call without setting the `Error` reference to the corresponding error code. This can cause problems to callers, that may expect that, when the check like this is passed on the response: ```c++ if (res.error() == Error::Success) ``` then they can access the response contents with `res.value()`. When `SSLClient`'s connection fails - the contents `unique_ptr` is not set and an attemt to access it causes UB. This change fixes the `SSLClient::create_and_connect_socket` method making sure that, the `Error` value is set correctly when the `is_valid()` check fails. --- httplib.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/httplib.h b/httplib.h index db55d07..2327b04 100644 --- a/httplib.h +++ b/httplib.h @@ -10911,7 +10911,11 @@ inline long SSLClient::get_openssl_verify_result() const { inline SSL_CTX *SSLClient::ssl_context() const { return ctx_; } inline bool SSLClient::create_and_connect_socket(Socket &socket, Error &error) { - return is_valid() && ClientImpl::create_and_connect_socket(socket, error); + if (!is_valid()) { + error = Error::SSLConnection; + return false; + } + return ClientImpl::create_and_connect_socket(socket, error); } // Assumes that socket_mutex_ is locked and that there are no requests in flight From 8aedbf4547b4dc051846536da51695b4f3a2ec88 Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 25 Oct 2025 19:31:48 -0400 Subject: [PATCH 2/2] Add a unit test --- test/test.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test.cc b/test/test.cc index d58b87e..3779ca2 100644 --- a/test/test.cc +++ b/test/test.cc @@ -8366,6 +8366,19 @@ TEST(SSLClientTest, Issue2004_Online) { EXPECT_EQ(body.substr(0, 15), ""); } +TEST(SSLClientTest, ErrorReportingWhenInvalid) { + // Create SSLClient with invalid cert/key to make is_valid() return false + SSLClient cli("localhost", 8080, "nonexistent_cert.pem", + "nonexistent_key.pem"); + + // is_valid() should be false due to cert loading failure + ASSERT_FALSE(cli.is_valid()); + + auto res = cli.Get("/"); + ASSERT_FALSE(res); + EXPECT_EQ(Error::SSLConnection, res.error()); +} + #if 0 TEST(SSLClientTest, SetInterfaceWithINET6) { auto cli = std::make_shared("https://httpbin.org");