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');

184185

const kConnectionsCheckingInterval = Symbol('http.server.connectionsCheckingInterval');

185186186187

const HTTP_SERVER_TRACE_EVENT_NAME = 'http.server.request';

187-

// TODO(jazelly): make this configurable

188-

const HTTP_SERVER_KEEP_ALIVE_TIMEOUT_BUFFER = 1000;

189188190189

class HTTPServerAsyncResource {

191190

constructor(type, socket) {

@@ -484,6 +483,14 @@ function storeHTTPOptions(options) {

484483

this.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+487494

const connectionsCheckingInterval = options.connectionsCheckingInterval;

488495

if (connectionsCheckingInterval !== undefined) {

489496

validateInteger(connectionsCheckingInterval, 'connectionsCheckingInterval', 0);

@@ -546,6 +553,13 @@ function Server(options, requestListener) {

546553

}

547554548555

storeHTTPOptions.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;

549563

net.Server.call(

550564

this,

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) {

10141028

if (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);

10181033

state.keepAliveTimeoutSet = true;

10191034

}

10201035

} else {