node icon indicating copy to clipboard operation
node copied to clipboard

Node incorrectly responds 400 to invalid data sent after requests with `Connection: close`

Open kenballus opened this issue 1 year ago • 0 comments

Version

v23.0.0-pre

Platform

Linux cef57c85a6b6 6.8.9-arch1-2 #1 SMP PREEMPT_DYNAMIC Tue, 07 May 2024 21:35:54 +0000 x86_64 GNU/Linux

Subsystem

http

What steps will reproduce the bug?

  1. Copy the following into server.js:
require('http').createServer((request, response) => {
    let body = [];
    request.on('data', (chunk) => {
        body.push(chunk);
    }).on('end', () => {
        response.end(JSON.stringify({
            "headers": Object.keys(request.headers).map((key) => [btoa(key), btoa(request.headers[key])]),
            "body": Buffer.concat(body).toString('base64'),
            "uri": btoa(request.url),
            "method": btoa(request.method),
            "version": btoa(request.httpVersion),
        }));
    });
}).listen(80);
  1. Run it:
node server.js
  1. Send it a request with Connection: close, then send some junk data:
printf 'GET / HTTP/1.1\r\nHost: whatever\r\nConnection: close\r\n\r\nInvalid!' | nc localhost 80

How often does it reproduce? Is there a required condition?

Reproduces every time with no special conditions required.

What is the expected behavior? Why is that the expected behavior?

The expected behavior is for the server to respond to the initial request, and then close the connection without processing the invalid data.

This is the expected behavior because of the following line in RFC 9112:

A server that receives a "close" connection option MUST initiate closure of the connection (see below) after it sends the final response to the request that contained the "close" connection option. The server SHOULD send a "close" connection option in its final response on that connection. The server MUST NOT process any further requests received on that connection.

Other servers (AIOHTTP, Apache httpd, CherryPy, Daphne, Deno, FastHTTP, Go net/http, Gunicorn, H2O, Hyper, Jetty, Libevent, Libsoup, Lighttpd, Mongoose, Nginx, Passenger, Proxygen, Apache Tomcat, Tornado, OpenWrt uhttpd, Unicorn, Waitress, WEBrick, Werkzeug) handle this in the expected way.

What do you see instead?

The server responds 400, indicating that the invalid data was processed:

HTTP/1.1 400 Bad Request\r\n
Connection: close\r\n
\r\n

Additional information

No response

kenballus avatar May 20 '24 20:05 kenballus