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

+9 -2
View File
@@ -12091,8 +12091,9 @@ inline bool is_partial_content(const Request &req, const Response &res) {
}
// Sets the Content-Length or Transfer-Encoding framing the body that
// Server::write_response_core() writes. Only the library sets them: one from a
// handler would go out next to it, or describe some other body.
// Server::write_response_core() writes, or closes the connection after a body
// that has neither. Only the library sets them: one from a handler would go
// out next to it, or describe some other body.
inline void set_framing_headers(const Request &req, Response &res,
const std::string &boundary,
const std::string &content_type) {
@@ -12109,6 +12110,12 @@ inline void set_framing_headers(const Request &req, Response &res,
if (res.content_length_ == 0) {
if (res.is_chunked_content_provider_) {
res.set_header("Transfer-Encoding", "chunked");
} else if (req.method != "HEAD") {
// RFC 9112 6.3: a body with neither ends where the connection does.
res.headers.erase("Keep-Alive");
if (!has_header_token(res.headers, "Connection", "close")) {
res.set_header("Connection", "close");
}
}
return;
}