@@ -639,18 +639,35 @@ function tickOnSocket(req, socket) {
639639 socket . on ( 'end' , socketOnEnd ) ;
640640 socket . on ( 'close' , socketCloseListener ) ;
641641
642- if ( req . timeout ) {
643- const emitRequestTimeout = ( ) => req . emit ( 'timeout' ) ;
644- socket . once ( 'timeout' , emitRequestTimeout ) ;
645- req . once ( 'response' , ( res ) => {
646- res . once ( 'end' , ( ) => {
647- socket . removeListener ( 'timeout' , emitRequestTimeout ) ;
648- } ) ;
649- } ) ;
642+ if ( req . timeout !== undefined ) {
643+ listenSocketTimeout ( req ) ;
650644 }
651645 req . emit ( 'socket' , socket ) ;
652646}
653647
648+ function listenSocketTimeout ( req ) {
649+ if ( req . timeoutCb ) {
650+ return ;
651+ }
652+ const emitRequestTimeout = ( ) => req . emit ( 'timeout' ) ;
653+ // Set timeoutCb so it will get cleaned up on request end.
654+ req . timeoutCb = emitRequestTimeout ;
655+ // Delegate socket timeout event.
656+ if ( req . socket ) {
657+ req . socket . once ( 'timeout' , emitRequestTimeout ) ;
658+ } else {
659+ req . on ( 'socket' , ( socket ) => {
660+ socket . once ( 'timeout' , emitRequestTimeout ) ;
661+ } ) ;
662+ }
663+ // Remove socket timeout listener after response end.
664+ req . once ( 'response' , ( res ) => {
665+ res . once ( 'end' , ( ) => {
666+ req . socket . removeListener ( 'timeout' , emitRequestTimeout ) ;
667+ } ) ;
668+ } ) ;
669+ }
670+
654671ClientRequest . prototype . onSocket = function onSocket ( socket ) {
655672 process . nextTick ( onSocketNT , this , socket ) ;
656673} ;
@@ -700,42 +717,29 @@ function _deferToConnect(method, arguments_, cb) {
700717}
701718
702719ClientRequest . prototype . setTimeout = function setTimeout ( msecs , callback ) {
720+ listenSocketTimeout ( this ) ;
703721 msecs = validateTimerDuration ( msecs ) ;
704722 if ( callback ) this . once ( 'timeout' , callback ) ;
705723
706- const emitTimeout = ( ) => this . emit ( 'timeout' ) ;
707-
708- if ( this . socket && this . socket . writable ) {
709- if ( this . timeoutCb )
710- this . socket . setTimeout ( 0 , this . timeoutCb ) ;
711- this . timeoutCb = emitTimeout ;
712- this . socket . setTimeout ( msecs , emitTimeout ) ;
713- return this ;
714- }
715-
716- // Set timeoutCb so that it'll get cleaned up on request end
717- this . timeoutCb = emitTimeout ;
718724 if ( this . socket ) {
719- var sock = this . socket ;
720- this . socket . once ( 'connect' , function ( ) {
721- sock . setTimeout ( msecs , emitTimeout ) ;
722- } ) ;
723- return this ;
725+ setSocketTimeout ( this . socket , msecs ) ;
726+ } else {
727+ this . once ( 'socket' , ( sock ) => setSocketTimeout ( sock , msecs ) ) ;
724728 }
725729
726- this . once ( 'socket' , function ( sock ) {
727- if ( sock . connecting ) {
728- sock . once ( 'connect' , function ( ) {
729- sock . setTimeout ( msecs , emitTimeout ) ;
730- } ) ;
731- } else {
732- sock . setTimeout ( msecs , emitTimeout ) ;
733- }
734- } ) ;
735-
736730 return this ;
737731} ;
738732
733+ function setSocketTimeout ( sock , msecs ) {
734+ if ( sock . connecting ) {
735+ sock . once ( 'connect' , function ( ) {
736+ sock . setTimeout ( msecs ) ;
737+ } ) ;
738+ } else {
739+ sock . setTimeout ( msecs ) ;
740+ }
741+ }
742+
739743ClientRequest . prototype . setNoDelay = function setNoDelay ( noDelay ) {
740744 this . _deferToConnect ( 'setNoDelay' , [ noDelay ] ) ;
741745} ;
0 commit comments