@@ -590,59 +590,59 @@ function parserOnIncomingClient(res, shouldKeepAlive) {
590590}
591591
592592// client
593- function responseKeepAlive ( res , req ) {
593+ function responseKeepAlive ( req ) {
594594 const socket = req . socket ;
595595
596- if ( ! req . shouldKeepAlive ) {
597- if ( socket . writable ) {
598- debug ( 'AGENT socket.destroySoon()' ) ;
599- if ( typeof socket . destroySoon === 'function' )
600- socket . destroySoon ( ) ;
601- else
602- socket . end ( ) ;
603- }
604- assert ( ! socket . writable ) ;
605- } else {
606- debug ( 'AGENT socket keep-alive' ) ;
607- if ( req . timeoutCb ) {
608- socket . setTimeout ( 0 , req . timeoutCb ) ;
609- req . timeoutCb = null ;
610- }
611- socket . removeListener ( 'close' , socketCloseListener ) ;
612- socket . removeListener ( 'error' , socketErrorListener ) ;
613- socket . removeListener ( 'drain' , ondrain ) ;
614- socket . once ( 'error' , freeSocketErrorListener ) ;
615- // There are cases where _handle === null. Avoid those. Passing null to
616- // nextTick() will call getDefaultTriggerAsyncId() to retrieve the id.
617- const asyncId = socket . _handle ? socket . _handle . getAsyncId ( ) : undefined ;
618- // Mark this socket as available, AFTER user-added end
619- // handlers have a chance to run.
620- defaultTriggerAsyncIdScope ( asyncId , process . nextTick , emitFreeNT , socket ) ;
621- }
596+ debug ( 'AGENT socket keep-alive' ) ;
597+ if ( req . timeoutCb ) {
598+ socket . setTimeout ( 0 , req . timeoutCb ) ;
599+ req . timeoutCb = null ;
600+ }
601+ socket . removeListener ( 'close' , socketCloseListener ) ;
602+ socket . removeListener ( 'error' , socketErrorListener ) ;
603+ socket . once ( 'error' , freeSocketErrorListener ) ;
604+ // There are cases where _handle === null. Avoid those. Passing null to
605+ // nextTick() will call getDefaultTriggerAsyncId() to retrieve the id.
606+ const asyncId = socket . _handle ? socket . _handle . getAsyncId ( ) : undefined ;
607+ // Mark this socket as available, AFTER user-added end
608+ // handlers have a chance to run.
609+ defaultTriggerAsyncIdScope ( asyncId , process . nextTick , emitFreeNT , socket ) ;
622610}
623611
624612function responseOnEnd ( ) {
625- const res = this ;
626613 const req = this . req ;
627614
628615 if ( req . socket && req . timeoutCb ) {
629616 req . socket . removeListener ( 'timeout' , emitRequestTimeout ) ;
630617 }
631618
632619 req . _ended = true ;
633- if ( ! req . shouldKeepAlive || req . finished )
634- responseKeepAlive ( res , req ) ;
620+
621+ if ( ! req . shouldKeepAlive ) {
622+ const socket = req . socket ;
623+ if ( socket . writable ) {
624+ debug ( 'AGENT socket.destroySoon()' ) ;
625+ if ( typeof socket . destroySoon === 'function' )
626+ socket . destroySoon ( ) ;
627+ else
628+ socket . end ( ) ;
629+ }
630+ assert ( ! socket . writable ) ;
631+ } else if ( req . finished ) {
632+ // We can assume `req.finished` means all data has been written since:
633+ // - `'responseOnEnd'` means we have been assigned a socket.
634+ // - when we have a socket we write directly to it without buffering.
635+ // - `req.finished` means `end()` has been called and no further data.
636+ // can be written
637+ responseKeepAlive ( req ) ;
638+ }
635639}
636640
637641function requestOnPrefinish ( ) {
638642 const req = this ;
639- const res = this . res ;
640-
641- if ( ! req . shouldKeepAlive )
642- return ;
643643
644- if ( req . _ended )
645- responseKeepAlive ( res , req ) ;
644+ if ( req . shouldKeepAlive && req . _ended )
645+ responseKeepAlive ( req ) ;
646646}
647647
648648function emitFreeNT ( socket ) {
0 commit comments