Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 35 additions & 27 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1193,56 +1193,55 @@

* Type: {boolean} Whether the request is sent through a reused socket.

When sending request through a keep-alive enabled agent, the underlying socket
might be reused. But if server closes connection at unfortunate time, client
may run into a 'ECONNRESET' error.
When sending a request through a keep-alive-enabled agent, the underlying socket
might be reused. If the server closes the connection at the same time that the
agent reuses it, the request may encounter an `ECONNRESET` error.

The following example sends requests near the server's keep-alive timeout to
make this race easier to reproduce. It sets
[`server.keepAliveTimeoutBuffer`][] to `0` so the internal socket timeout
matches [`server.keepAliveTimeout`][].

```mjs
import http from 'node:http';
const agent = new http.Agent({ keepAlive: true });

// Server has a 5 seconds keep-alive timeout by default
http
.createServer((req, res) => {
const server = http.createServer(
{ keepAliveTimeout: 3000, keepAliveTimeoutBuffer: 0 },
(req, res) => {
res.write('hello\n');
res.end();
})
.listen(3000);
},
);
server.listen(3000);

setInterval(() => {
// Adapting a keep-alive agent
http.get('http://localhost:3000', { agent }, (res) => {
res.on('data', (data) => {
// Do nothing
});
res.resume();
});
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout
}, 3000);
```

```cjs
const http = require('node:http');
const agent = new http.Agent({ keepAlive: true });

// Server has a 5 seconds keep-alive timeout by default
http
.createServer((req, res) => {
const server = http.createServer(
{ keepAliveTimeout: 3000, keepAliveTimeoutBuffer: 0 },
(req, res) => {
res.write('hello\n');
res.end();
})
.listen(3000);
},
);
server.listen(3000);

setInterval(() => {
// Adapting a keep-alive agent
http.get('http://localhost:3000', { agent }, (res) => {
res.on('data', (data) => {
// Do nothing
});
res.resume();
});
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout
}, 3000);
```

By marking a request whether it reused socket or not, we can do
automatic error retry base on it.
By checking `request.reusedSocket`, an application can retry idempotent requests
that fail because a reused connection was reset.

```mjs
import http from 'node:http';
Expand Down Expand Up @@ -3718,6 +3717,11 @@
- v22.21.0
pr-url: https://github.com/nodejs/node/pull/59824
description: The `shouldUpgradeCallback` option is now supported.
- version:
- v24.6.0
- v22.19.0
pr-url: https://github.com/nodejs/node/pull/59243

Check warning on line 3723 in doc/api/http.md

View workflow job for this annotation

GitHub Actions / lint-pr-url

pr-url doesn't match the URL of the current PR.
description: The `keepAliveTimeoutBuffer` option is supported now.
- version:
- v20.1.0
- v18.17.0
Expand Down Expand Up @@ -3798,6 +3802,10 @@
the last response, before a socket will be destroyed.
See [`server.keepAliveTimeout`][] for more information.
**Default:** `65000`.
* `keepAliveTimeoutBuffer`: An additional buffer time in milliseconds added
to `keepAliveTimeout` to extend the internal socket timeout.
See [`server.keepAliveTimeoutBuffer`][] for more information.
**Default:** `1000`.
* `maxHeaderSize` {number} Optionally overrides the value of
[`--max-http-header-size`][] for requests received by this server, i.e.
the maximum length of request headers in bytes.
Expand Down
Loading