http: add server.keepAliveTimeoutBuffer option · nodejs/node@e79c93a
@@ -25,6 +25,7 @@ const {
2525 ArrayIsArray,
2626 Error,
2727 MathMin,
28+ NumberIsFinite,
2829 ObjectKeys,
2930 ObjectSetPrototypeOf,
3031 ReflectApply,
@@ -184,8 +185,6 @@ const kConnections = Symbol('http.server.connections');
184185const kConnectionsCheckingInterval = Symbol('http.server.connectionsCheckingInterval');
185186186187const HTTP_SERVER_TRACE_EVENT_NAME = 'http.server.request';
187-// TODO(jazelly): make this configurable
188-const HTTP_SERVER_KEEP_ALIVE_TIMEOUT_BUFFER = 1000;
189188190189class HTTPServerAsyncResource {
191190constructor(type, socket) {
@@ -484,6 +483,14 @@ function storeHTTPOptions(options) {
484483this.keepAliveTimeout = 5_000; // 5 seconds;
485484}
486485486+const keepAliveTimeoutBuffer = options.keepAliveTimeoutBuffer;
487+if (keepAliveTimeoutBuffer !== undefined) {
488+validateInteger(keepAliveTimeoutBuffer, 'keepAliveTimeoutBuffer', 0);
489+this.keepAliveTimeoutBuffer = keepAliveTimeoutBuffer;
490+} else {
491+this.keepAliveTimeoutBuffer = 1000;
492+}
493+487494const connectionsCheckingInterval = options.connectionsCheckingInterval;
488495if (connectionsCheckingInterval !== undefined) {
489496validateInteger(connectionsCheckingInterval, 'connectionsCheckingInterval', 0);
@@ -546,6 +553,13 @@ function Server(options, requestListener) {
546553}
547554548555storeHTTPOptions.call(this, options);
556+557+// Optional buffer added to the keep-alive timeout when setting socket timeouts.
558+// Helps reduce ECONNRESET errors from clients by extending the internal timeout.
559+// Default is 1000ms if not specified.
560+const buf = options.keepAliveTimeoutBuffer;
561+this.keepAliveTimeoutBuffer =
562+(typeof buf === 'number' && NumberIsFinite(buf) && buf >= 0) ? buf : 1000;
549563net.Server.call(
550564this,
551565{ allowHalfOpen: true, noDelay: options.noDelay ?? true,
@@ -1012,9 +1026,10 @@ function resOnFinish(req, res, socket, state, server) {
10121026}
10131027} else if (state.outgoing.length === 0) {
10141028if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
1015-// Increase the internal timeout wrt the advertised value to reduce
1029+// Extend the internal timeout by the configured buffer to reduce
10161030// the likelihood of ECONNRESET errors.
1017-socket.setTimeout(server.keepAliveTimeout + HTTP_SERVER_KEEP_ALIVE_TIMEOUT_BUFFER);
1031+// This allows fine-tuning beyond the advertised keepAliveTimeout.
1032+socket.setTimeout(server.keepAliveTimeout + server.keepAliveTimeoutBuffer);
10181033state.keepAliveTimeoutSet = true;
10191034}
10201035} else {