Close the connection after a response body with no length

A content provider without a length or chunked coding sends a body that
only the end of the connection delimits (RFC 9112 6.3), yet the response
offered keep-alive, so a keep-alive client waited for the server's idle
timeout. Send Connection: close and close after it, as Go's net/http
does. A Content-Length set by the handler is still dropped; the
overload that takes a length frames such a body.
This commit is contained in:
yhirose committed 2026-10-16 23:52:15 -04:00
1 parent 645bdab90e
commit 7bf66db6ca
2 files changed
+46 -2

No files matched your search

+37
View File
@@ -5756,6 +5756,43 @@ TEST(ResponseFramingTest, PostRoutingHandlerChangesAreFramed) {
EXPECT_FALSE(res->has_header("Transfer-Encoding"));
}
TEST(ResponseFramingTest, BodyWithoutLengthEndsWithTheConnection) {
Server svr;
svr.Get("/", [](const Request & /*req*/, Response &res) {
res.set_header("Content-Length", "3");
res.set_content_provider("text/plain", [](size_t, DataSink &sink) {
sink.write("abc", 3);
sink.done();
return true;
});
});
thread t = thread([&] { svr.listen(HOST, PORT); });
auto se = detail::scope_exit([&] {
svr.stop();
t.join();
ASSERT_FALSE(svr.is_running());
});
svr.wait_until_ready();
Client cli(HOST, PORT);
cli.set_keep_alive(true);
auto res = cli.Get("/");
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
EXPECT_EQ("abc", res->body);
EXPECT_FALSE(res->has_header("Content-Length"));
EXPECT_EQ("close", res->get_header_value("Connection"));
EXPECT_FALSE(res->has_header("Keep-Alive"));
// No body to delimit
auto head = cli.Head("/");
ASSERT_TRUE(head) << "Error: " << to_string(head.error());
EXPECT_FALSE(head->has_header("Connection"));
}
TEST(RoutingHandlerTest, PreAndPostRoutingHandlers) {
#ifdef CPPHTTPLIB_SSL_ENABLED
SSLServer svr(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE);