-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unexpected HTTP Parse Error #34350
Comments
@nodejs/http-parser |
Here is a simpler test case without external servers: 'use strict';
const http = require('http');
const net = require('net');
const server = net.createServer();
server.on('connection', function (socket) {
socket.resume();
socket.write(
[
'HTTP/1.1 404 Not Found',
'Transfer-Encoding: chunked',
'',
'0',
'',
''
].join('\r\n')
);
});
server.listen(function () {
const request = http.request({
method: 'HEAD',
port: server.address().port
});
request.on('response', function (response) {
response.resume();
console.log(response.statusCode);
});
request.end();
}); |
It seems this happens every time the HTTP response to a HEAD request has a message body. The only relevant parts I can find on RFC 7230 are: https://tools.ietf.org/html/rfc7230#section-3.3
https://tools.ietf.org/html/rfc7230#section-3.3.3
|
Right, this issue has come up before - numerous times, in fact. Servers shouldn't include a response body when replying to HEAD requests but some buggy servers do. The parser (correctly) assumes that the first byte after the headers-terminating newline is the start of a new response. Node could work around it if it tracked requests and responses, i.e., if it knew no second response is expected because no matching request has been fired off yet. Would still break with HTTP pipelining though. |
/cc @ronag (slightly related with nodejs/undici#246 and nodejs/undici#250) |
From https://tools.ietf.org/html/rfc7231#section-4.3.2
so I think it's ok to mark this as "wontfix". |
What we did in undici was that if we suspect that the server might be sending extra data after the expected response we simply stop pipelining, ignore the extra data and close the connection. Though currently we only do this when we send requests that have undefined semantics, i.e. payload with GET or HEAD, and we know that the server might "misbehave". Though in this case we are sending a valid request and the server is providing an invalid response, i.e. no hint regarding server behavior. I don't have any good ideas how to detect that without fully disabling pipelining. Without pipelining we could do the above and just ignore the rest of the data once we have received what we expect. |
@szmarczak: One way to actually solve this is to always reset the connection after a HEAD response. Though that would significantly reduce performance of HEAD requests. But it would make it more resilient. |
What steps will reproduce the bug?
https://runkit.com/szmarczak/5f0d0b92c01e77001bd2be09
How often does it reproduce? Is there a required condition?
Always.
What is the expected behavior?
What do you see instead?
Additional information
The server replies with these data:
/cc @Kikobeats
The text was updated successfully, but these errors were encountered: