mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
http: reduce likelihood of race conditions on keep-alive timeout
Fixes: https://github.com/nodejs/node/issues/52649 Refs: https://github.com/nodejs/node/issues/54293 Co-authored-by: Arrigo Zanette <zanettea@gmail.com> PR-URL: https://github.com/nodejs/node/pull/54863 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: Jake Yuesong Li <jake.yuesong@gmail.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
This commit is contained in:
@@ -49,6 +49,9 @@ const {
|
||||
const kOnKeylog = Symbol('onkeylog');
|
||||
const kRequestOptions = Symbol('requestOptions');
|
||||
const kRequestAsyncResource = Symbol('requestAsyncResource');
|
||||
|
||||
// TODO(jazelly): make this configurable
|
||||
const HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER = 1000;
|
||||
// New Agent code.
|
||||
|
||||
// The largest departure from the previous implementation is that
|
||||
@@ -473,6 +476,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
|
||||
socket.unref();
|
||||
|
||||
let agentTimeout = this.options.timeout || 0;
|
||||
let canKeepSocketAlive = true;
|
||||
|
||||
if (socket._httpMessage?.res) {
|
||||
const keepAliveHint = socket._httpMessage.res.headers['keep-alive'];
|
||||
@@ -481,9 +485,15 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
|
||||
const hint = /^timeout=(\d+)/.exec(keepAliveHint)?.[1];
|
||||
|
||||
if (hint) {
|
||||
const serverHintTimeout = NumberParseInt(hint) * 1000;
|
||||
|
||||
if (serverHintTimeout < agentTimeout) {
|
||||
// Let the timer expire before the announced timeout to reduce
|
||||
// the likelihood of ECONNRESET errors
|
||||
let serverHintTimeout = (NumberParseInt(hint) * 1000) - HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER;
|
||||
serverHintTimeout = serverHintTimeout > 0 ? serverHintTimeout : 0;
|
||||
if (serverHintTimeout === 0) {
|
||||
// Cannot safely reuse the socket because the server timeout is
|
||||
// too short
|
||||
canKeepSocketAlive = false;
|
||||
} else if (serverHintTimeout < agentTimeout) {
|
||||
agentTimeout = serverHintTimeout;
|
||||
}
|
||||
}
|
||||
@@ -494,7 +504,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
|
||||
socket.setTimeout(agentTimeout);
|
||||
}
|
||||
|
||||
return true;
|
||||
return canKeepSocketAlive;
|
||||
};
|
||||
|
||||
Agent.prototype.reuseSocket = function reuseSocket(socket, req) {
|
||||
|
||||
Reference in New Issue
Block a user