node
node copied to clipboard
The `http.Server` adds a `Transfer-Encoding: chunked` header when the response has no body
Version
22 (but maybe every version)
Platform
Microsoft Windows NT 10.0.22631.0 x64 (but maybe not platform-specific)
Subsystem
node:http
What steps will reproduce the bug?
The Transfer-Encoding: chunked
header is always added when there is no response body. There seems to be no way to remove it.
However, since this header is not added when the request method is HEAD, the response headers are different when the request method is GET and HEAD, which is against the HTTP specification.
Example server code:
import { createServer } from 'node:http';
import { finished } from 'node:stream/promises';
createServer(function (req, res) {
finished(req.resume()).then(() => {
res.writeHead(200, { 'Cache-Control': 'no-store' });
res.end(); // No body
}).catch((err) => {
this.emit('error', err);
})
}).listen(8000, '0.0.0.0');
GET:
$ curl -i http://localhost:8000/
HTTP/1.1 200 OK
Cache-Control: no-store
Date: Sat, 23 Nov 2024 09:01:22 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked
HEAD:
$ curl --head -i http://localhost:8000/
HTTP/1.1 200 OK
Cache-Control: no-store
Date: Sat, 23 Nov 2024 09:01:17 GMT
Connection: keep-alive
Keep-Alive: timeout=5
A monkey patching solution I found is to always add the Content-Length: 0
header.
However, I'm not sure if this is really the intended behavior. I think it should be possible to send a response without adding a Content-Length: 0
header when there is no body.
Or, if it's intended behavior, it should be documented.
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior? Why is that the expected behavior?
I would guess that the generally expected behavior is that the Transfer-Encoding: chunked
header is NOT added when there is no response body.
What do you see instead?
.
Additional information
Perhaps this issue https://github.com/denoland/deno/issues/20063 may be related.