From 3d56762d5c62dedc7cf1f44ec1d94f82a5954eb2 Mon Sep 17 00:00:00 2001 From: yhirose Date: Wed, 29 Apr 2026 10:04:10 +0900 Subject: [PATCH] Fix mbedTLS close_notify mid-response handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mbedTLS backend's read() returned -1 with err.code = PeerClosed when the peer sent close_notify, while OpenSSL and wolfSSL surface it as 0 (clean EOF). The result was that an SSL response without Content-Length or chunked Transfer-Encoding — terminated by connection close — was reported as "Failed to read connection" on mbedTLS, even though the body had been fully delivered. Translate PeerClosed into a return value of 0 to match the other backends. This re-enables SSLTest.ResponseBodyTerminatedByConnectionClose on mbedTLS. Co-Authored-By: Claude Opus 4.7 (1M context) --- httplib.h | 3 +++ test/test.cc | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/httplib.h b/httplib.h index 68daf553..7cf8c454 100644 --- a/httplib.h +++ b/httplib.h @@ -17956,6 +17956,9 @@ inline ssize_t read(session_t session, void *buf, size_t len, TlsError &err) { err.code = impl::map_mbedtls_error(ret, err.sys_errno); err.backend_code = static_cast(-ret); impl::mbedtls_last_error() = ret; + // mbedTLS signals a clean close_notify via a negative error code rather + // than 0; surface it as a clean EOF the way OpenSSL/wolfSSL do. + if (err.code == ErrorCode::PeerClosed) { return 0; } return -1; } diff --git a/test/test.cc b/test/test.cc index 2a72d3ca..c708e79f 100644 --- a/test/test.cc +++ b/test/test.cc @@ -14626,12 +14626,6 @@ TEST_F(SSLOpenStreamTest, PostChunked) { // SSL peer sends a close_notify after the body, the client must treat it as a // clean EOF and return a successful response rather than an error. TEST(SSLTest, ResponseBodyTerminatedByConnectionClose) { -#ifdef CPPHTTPLIB_MBEDTLS_SUPPORT - // TODO: mbedTLS reports a clean close_notify mid-response as a read error. - // Treat the EOF as a successful body terminator the way the OpenSSL/wolfSSL - // backends already do. - GTEST_SKIP() << "mbedTLS backend treats close_notify mid-response as error"; -#endif SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE); ASSERT_TRUE(svr.is_valid());