@@ -647,18 +647,35 @@ function tickOnSocket(req, socket) {
647647 socket . on ( 'end' , socketOnEnd ) ;
648648 socket . on ( 'close' , socketCloseListener ) ;
649649
650- if ( req . timeout ) {
651- const emitRequestTimeout = ( ) => req . emit ( 'timeout' ) ;
652- socket . once ( 'timeout' , emitRequestTimeout ) ;
653- req . once ( 'response' , ( res ) => {
654- res . once ( 'end' , ( ) => {
655- socket . removeListener ( 'timeout' , emitRequestTimeout ) ;
656- } ) ;
657- } ) ;
650+ if ( req . timeout !== undefined ) {
651+ listenSocketTimeout ( req ) ;
658652 }
659653 req . emit ( 'socket' , socket ) ;
660654}
661655
656+ function listenSocketTimeout ( req ) {
657+ if ( req . timeoutCb ) {
658+ return ;
659+ }
660+ const emitRequestTimeout = ( ) => req . emit ( 'timeout' ) ;
661+ // Set timeoutCb so that it'll get cleaned up on request end
662+ req . timeoutCb = emitRequestTimeout ;
663+ // delegate socket timeout event
664+ if ( req . socket ) {
665+ req . socket . once ( 'timeout' , emitRequestTimeout ) ;
666+ } else {
667+ req . on ( 'socket' , ( socket ) => {
668+ socket . once ( 'timeout' , emitRequestTimeout ) ;
669+ } ) ;
670+ }
671+ // remove socket timeout listener after response end
672+ req . once ( 'response' , ( res ) => {
673+ res . once ( 'end' , ( ) => {
674+ req . socket . removeListener ( 'timeout' , emitRequestTimeout ) ;
675+ } ) ;
676+ } ) ;
677+ }
678+
662679ClientRequest . prototype . onSocket = function onSocket ( socket ) {
663680 process . nextTick ( onSocketNT , this , socket ) ;
664681} ;
@@ -708,42 +725,29 @@ function _deferToConnect(method, arguments_, cb) {
708725}
709726
710727ClientRequest . prototype . setTimeout = function setTimeout ( msecs , callback ) {
728+ listenSocketTimeout ( this ) ;
711729 msecs = validateTimerDuration ( msecs ) ;
712730 if ( callback ) this . once ( 'timeout' , callback ) ;
713731
714- const emitTimeout = ( ) => this . emit ( 'timeout' ) ;
715-
716- if ( this . socket && this . socket . writable ) {
717- if ( this . timeoutCb )
718- this . socket . setTimeout ( 0 , this . timeoutCb ) ;
719- this . timeoutCb = emitTimeout ;
720- this . socket . setTimeout ( msecs , emitTimeout ) ;
721- return this ;
722- }
723-
724- // Set timeoutCb so that it'll get cleaned up on request end
725- this . timeoutCb = emitTimeout ;
726732 if ( this . socket ) {
727- var sock = this . socket ;
728- this . socket . once ( 'connect' , function ( ) {
729- sock . setTimeout ( msecs , emitTimeout ) ;
730- } ) ;
731- return this ;
733+ setSocketTimeout ( this . socket , msecs ) ;
734+ } else {
735+ this . once ( 'socket' , ( sock ) => setSocketTimeout ( sock , msecs ) ) ;
732736 }
733737
734- this . once ( 'socket' , function ( sock ) {
735- if ( sock . connecting ) {
736- sock . once ( 'connect' , function ( ) {
737- sock . setTimeout ( msecs , emitTimeout ) ;
738- } ) ;
739- } else {
740- sock . setTimeout ( msecs , emitTimeout ) ;
741- }
742- } ) ;
743-
744738 return this ;
745739} ;
746740
741+ function setSocketTimeout ( sock , msecs ) {
742+ if ( sock . connecting ) {
743+ sock . once ( 'connect' , function ( ) {
744+ sock . setTimeout ( msecs ) ;
745+ } ) ;
746+ } else {
747+ sock . setTimeout ( msecs ) ;
748+ }
749+ }
750+
747751ClientRequest . prototype . setNoDelay = function setNoDelay ( noDelay ) {
748752 this . _deferToConnect ( 'setNoDelay' , [ noDelay ] ) ;
749753} ;
0 commit comments