Frame response bodies in one place

A content provider that wrote past the length it was given put the
extra bytes after the framed body, where a keep-alive peer read them as
the next message. Write only what fits and fail the write, on both the
server and the client.

Content-Length and Transfer-Encoding a handler set were sent next to
the ones the library worked out, for ranges and compression, and a
post-routing handler could change the body after Content-Length was
set. Work both out in one place, from the body about to be written,
again after the post-routing handler; a HEAD response keeps the length
its handler gave it. A 1xx, 204 or 304 response sends no body and,
following RFC 9110 8.6, no Content-Length.

The client still sends a Content-Length or Transfer-Encoding its caller
passes, as curl and urllib3 do, and the README says these have to match
the body.
This commit is contained in:
yhirose committed 2026-10-16 19:13:12 -04:00
1 parent bc837b87fc
commit 43c9c6ddf3
3 files changed
+289 -49

No files matched your search

+4
View File
@@ -790,6 +790,8 @@ svr.Get("/stream", [&](const Request &req, Response &res) {
});
```
Write at most `length` bytes per call. Anything past it is not sent, and the response fails.
Without content length:
```cpp
@@ -1127,6 +1129,8 @@ cli.set_default_headers({
auto res = cli.Get("/hi");
```
A `Content-Length` or `Transfer-Encoding` among these headers is sent in place of the one the library would send, so it has to describe the body as written. Leave both out when passing on the headers of another message, as a proxy does.
### POST
```c++