Skip to content
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

http server.headersTimeout keeps the socket open after timeout #26165

Open
mariusgrigaitis opened this issue Feb 17, 2019 · 1 comment
Open
Labels
http Issues or PRs related to the http subsystem.

Comments

@mariusgrigaitis
Copy link

  • Version: v11.6.0
  • Platform: Darwin Mariuss-MBP-2.lan 18.2.0 Darwin Kernel Version 18.2.0: Mon Nov 12 20:24:46 PST 2018; root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64
  • Subsystem: http

In case timeout is reached for server.headersTimeout, node keeps the socket open until it receives data or server.timeout is reached.

I believe this issue causes dropped connections / 502 errors on AWS ALB (load balancer), because it tries to send data and socket closes immediately after data is received.

I have set server.headersTimeout = 10 * 1000 and ran tcpdump to confirm.

image

As you can see in the dump, 24 seconds has passed, data was received, acknowledged and socket closed after data was received.

I expected socket to be closed after 10 seconds has passed without data.

@fahrradflucht
Copy link
Contributor

fahrradflucht commented May 14, 2024

I tried to reproduce what is described in this issue (see attached snippets at the end), but I wasn't able to:

  • When connectionsCheckingInterval is set to a value lower than the headersTimeout, the timeout triggers as expected and the socket is closed.
  • When connectionsCheckingInterval is higher, then the timeout is not triggered (I first thought this might be how to get into this case), but still the socket won't get closed when it is written to. Instead, the request will just be handled is if there was no headers timeout.

This is the behavior I observed on both node 11.6.0 (report) and 22.1.0 (current) - 23.4.0 Darwin fwiw.

Repro attempt source
// server.js
const http = require("http");

const server = http.createServer({
    // connectionsCheckingInterval: 1000, // enable this to trigger headersTimeout
},(req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello, World!\n");
});

server.headersTimeout = 5 * 1000; // 5 seconds
server.timeout = 30 * 1000; // 30 seconds

server.listen(3000, () => {
  console.log("Server running at http://127.0.0.1:3000/");
});
// client.js
const net = require('net');

const client = new net.Socket();

client.connect(3000, '127.0.0.1', () => {
    console.log('Connected to server');

    client.write('GET / HTTP/1.1\r\n')

    // Wait 10 seconds before sending the request headers to simulate delay
    setTimeout(() => {
        console.log('Sending remaining request headers');
        const request = [
            'Host: 127.0.0.1',
            'Connection: keep-alive',
            '',
            ''
        ].join('\r\n');
        client.write(request);
    }, 10000);
});

client.on('data', (data) => {
    console.log(`Received: ${data}`);
    client.destroy(); // Kill client after server's response
});

client.on('close', () => {
    console.log('Connection closed');
});

client.on('error', (err) => {
    console.error(`Error: ${err.message}`);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http Issues or PRs related to the http subsystem.
Projects
None yet
Development

No branches or pull requests

3 participants