@@ -49,6 +49,9 @@ const {
49
49
const kOnKeylog = Symbol ( 'onkeylog' ) ;
50
50
const kRequestOptions = Symbol ( 'requestOptions' ) ;
51
51
const kRequestAsyncResource = Symbol ( 'requestAsyncResource' ) ;
52
+
53
+ // TODO(jazelly): make this configurable
54
+ const HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER = 1000 ;
52
55
// New Agent code.
53
56
54
57
// The largest departure from the previous implementation is that
@@ -473,6 +476,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
473
476
socket . unref ( ) ;
474
477
475
478
let agentTimeout = this . options . timeout || 0 ;
479
+ let canKeepSocketAlive = true ;
476
480
477
481
if ( socket . _httpMessage ?. res ) {
478
482
const keepAliveHint = socket . _httpMessage . res . headers [ 'keep-alive' ] ;
@@ -481,9 +485,15 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
481
485
const hint = / ^ t i m e o u t = ( \d + ) / . exec ( keepAliveHint ) ?. [ 1 ] ;
482
486
483
487
if ( hint ) {
484
- const serverHintTimeout = NumberParseInt ( hint ) * 1000 ;
485
-
486
- if ( serverHintTimeout < agentTimeout ) {
488
+ // Let the timer expire before the announced timeout to reduce
489
+ // the likelihood of ECONNRESET errors
490
+ let serverHintTimeout = ( NumberParseInt ( hint ) * 1000 ) - HTTP_AGENT_KEEP_ALIVE_TIMEOUT_BUFFER ;
491
+ serverHintTimeout = serverHintTimeout > 0 ? serverHintTimeout : 0 ;
492
+ if ( serverHintTimeout === 0 ) {
493
+ // Cannot safely reuse the socket because the server timeout is
494
+ // too short
495
+ canKeepSocketAlive = false ;
496
+ } else if ( serverHintTimeout < agentTimeout ) {
487
497
agentTimeout = serverHintTimeout ;
488
498
}
489
499
}
@@ -494,7 +504,7 @@ Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) {
494
504
socket . setTimeout ( agentTimeout ) ;
495
505
}
496
506
497
- return true ;
507
+ return canKeepSocketAlive ;
498
508
} ;
499
509
500
510
Agent . prototype . reuseSocket = function reuseSocket ( socket , req ) {
0 commit comments