@@ -78,6 +78,9 @@ utcDate._onTimeout = function _onTimeout() {
7878} ;
7979
8080
81+ function noopPendingOutput ( amount ) { }
82+
83+
8184function OutgoingMessage ( ) {
8285 Stream . call ( this ) ;
8386
@@ -117,7 +120,7 @@ function OutgoingMessage() {
117120 this . _header = null ;
118121 this [ outHeadersKey ] = null ;
119122
120- this . _onPendingData = null ;
123+ this . _onPendingData = noopPendingOutput ;
121124}
122125util . inherits ( OutgoingMessage , Stream ) ;
123126
@@ -234,12 +237,18 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) {
234237 ( encoding === 'utf8' || encoding === 'latin1' || ! encoding ) ) {
235238 data = this . _header + data ;
236239 } else {
237- this . output . unshift ( this . _header ) ;
238- this . outputEncodings . unshift ( 'latin1' ) ;
239- this . outputCallbacks . unshift ( null ) ;
240- this . outputSize += this . _header . length ;
241- if ( typeof this . _onPendingData === 'function' )
242- this . _onPendingData ( this . _header . length ) ;
240+ var header = this . _header ;
241+ if ( this . output . length === 0 ) {
242+ this . output = [ header ] ;
243+ this . outputEncodings = [ 'latin1' ] ;
244+ this . outputCallbacks = [ null ] ;
245+ } else {
246+ this . output . unshift ( header ) ;
247+ this . outputEncodings . unshift ( 'latin1' ) ;
248+ this . outputCallbacks . unshift ( null ) ;
249+ }
250+ this . outputSize += header . length ;
251+ this . _onPendingData ( header . length ) ;
243252 }
244253 this . _headerSent = true ;
245254 }
@@ -275,19 +284,13 @@ function _writeRaw(data, encoding, callback) {
275284 return conn . write ( data , encoding , callback ) ;
276285 }
277286 // Buffer, as long as we're not destroyed.
278- return this . _buffer ( data , encoding , callback ) ;
279- }
280-
281-
282- OutgoingMessage . prototype . _buffer = function _buffer ( data , encoding , callback ) {
283287 this . output . push ( data ) ;
284288 this . outputEncodings . push ( encoding ) ;
285289 this . outputCallbacks . push ( callback ) ;
286290 this . outputSize += data . length ;
287- if ( typeof this . _onPendingData === 'function' )
288- this . _onPendingData ( data . length ) ;
291+ this . _onPendingData ( data . length ) ;
289292 return false ;
290- } ;
293+ }
291294
292295
293296OutgoingMessage . prototype . _storeHeader = _storeHeader ;
@@ -624,27 +627,31 @@ Object.defineProperty(OutgoingMessage.prototype, 'headersSent', {
624627
625628const crlf_buf = Buffer . from ( '\r\n' ) ;
626629OutgoingMessage . prototype . write = function write ( chunk , encoding , callback ) {
627- if ( this . finished ) {
630+ return write_ ( this , chunk , encoding , callback , false ) ;
631+ } ;
632+
633+ function write_ ( msg , chunk , encoding , callback , fromEnd ) {
634+ if ( msg . finished ) {
628635 var err = new Error ( 'write after end' ) ;
629- nextTick ( this . socket [ async_id_symbol ] ,
630- writeAfterEndNT . bind ( this ) ,
636+ nextTick ( msg . socket [ async_id_symbol ] ,
637+ writeAfterEndNT . bind ( msg ) ,
631638 err ,
632639 callback ) ;
633640
634641 return true ;
635642 }
636643
637- if ( ! this . _header ) {
638- this . _implicitHeader ( ) ;
644+ if ( ! msg . _header ) {
645+ msg . _implicitHeader ( ) ;
639646 }
640647
641- if ( ! this . _hasBody ) {
648+ if ( ! msg . _hasBody ) {
642649 debug ( 'This type of response MUST NOT have a body. ' +
643650 'Ignoring write() calls.' ) ;
644651 return true ;
645652 }
646653
647- if ( typeof chunk !== 'string' && ! ( chunk instanceof Buffer ) ) {
654+ if ( ! fromEnd && typeof chunk !== 'string' && ! ( chunk instanceof Buffer ) ) {
648655 throw new TypeError ( 'First argument must be a string or Buffer' ) ;
649656 }
650657
@@ -654,38 +661,28 @@ OutgoingMessage.prototype.write = function write(chunk, encoding, callback) {
654661 if ( chunk . length === 0 ) return true ;
655662
656663 var len , ret ;
657- if ( this . chunkedEncoding ) {
658- if ( typeof chunk === 'string' &&
659- encoding !== 'hex' &&
660- encoding !== 'base64' &&
661- encoding !== 'latin1' ) {
664+ if ( msg . chunkedEncoding ) {
665+ if ( typeof chunk === 'string' )
662666 len = Buffer . byteLength ( chunk , encoding ) ;
663- chunk = len . toString ( 16 ) + CRLF + chunk + CRLF ;
664- ret = this . _send ( chunk , encoding , callback ) ;
665- } else {
666- // buffer, or a non-toString-friendly encoding
667- if ( typeof chunk === 'string' )
668- len = Buffer . byteLength ( chunk , encoding ) ;
669- else
670- len = chunk . length ;
671-
672- if ( this . connection && ! this . connection . corked ) {
673- this . connection . cork ( ) ;
674- process . nextTick ( connectionCorkNT , this . connection ) ;
675- }
667+ else
668+ len = chunk . length ;
676669
677- this . _send ( len . toString ( 16 ) , 'latin1' , null ) ;
678- this . _send ( crlf_buf , null , null ) ;
679- this . _send ( chunk , encoding , null ) ;
680- ret = this . _send ( crlf_buf , null , callback ) ;
670+ if ( msg . connection && ! msg . connection . corked ) {
671+ msg . connection . cork ( ) ;
672+ process . nextTick ( connectionCorkNT , msg . connection ) ;
681673 }
674+
675+ msg . _send ( len . toString ( 16 ) , 'latin1' , null ) ;
676+ msg . _send ( crlf_buf , null , null ) ;
677+ msg . _send ( chunk , encoding , null ) ;
678+ ret = msg . _send ( crlf_buf , null , callback ) ;
682679 } else {
683- ret = this . _send ( chunk , encoding , callback ) ;
680+ ret = msg . _send ( chunk , encoding , callback ) ;
684681 }
685682
686683 debug ( 'write ret = ' + ret ) ;
687684 return ret ;
688- } ;
685+ }
689686
690687
691688function writeAfterEndNT ( err , callback ) {
@@ -736,49 +733,40 @@ function onFinish(outmsg) {
736733 outmsg . emit ( 'finish' ) ;
737734}
738735
739- OutgoingMessage . prototype . end = function end ( data , encoding , callback ) {
740- if ( typeof data === 'function' ) {
741- callback = data ;
742- data = null ;
736+ OutgoingMessage . prototype . end = function end ( chunk , encoding , callback ) {
737+ if ( typeof chunk === 'function' ) {
738+ callback = chunk ;
739+ chunk = null ;
743740 } else if ( typeof encoding === 'function' ) {
744741 callback = encoding ;
745742 encoding = null ;
746743 }
747744
748- if ( data && typeof data !== 'string' && ! ( data instanceof Buffer ) ) {
749- throw new TypeError ( 'First argument must be a string or Buffer' ) ;
750- }
751-
752745 if ( this . finished ) {
753746 return false ;
754747 }
755748
756- if ( ! this . _header ) {
757- if ( data ) {
758- if ( typeof data === 'string' )
759- this . _contentLength = Buffer . byteLength ( data , encoding ) ;
749+ var uncork ;
750+ if ( chunk ) {
751+ if ( typeof chunk !== 'string' && ! ( chunk instanceof Buffer ) ) {
752+ throw new TypeError ( 'First argument must be a string or Buffer' ) ;
753+ }
754+ if ( ! this . _header ) {
755+ if ( typeof chunk === 'string' )
756+ this . _contentLength = Buffer . byteLength ( chunk , encoding ) ;
760757 else
761- this . _contentLength = data . length ;
762- } else {
763- this . _contentLength = 0 ;
758+ this . _contentLength = chunk . length ;
759+ }
760+ if ( this . connection ) {
761+ this . connection . cork ( ) ;
762+ uncork = true ;
764763 }
764+ write_ ( this , chunk , encoding , null , true ) ;
765+ } else if ( ! this . _header ) {
766+ this . _contentLength = 0 ;
765767 this . _implicitHeader ( ) ;
766768 }
767769
768- if ( data && ! this . _hasBody ) {
769- debug ( 'This type of response MUST NOT have a body. ' +
770- 'Ignoring data passed to end().' ) ;
771- data = null ;
772- }
773-
774- if ( this . connection && data )
775- this . connection . cork ( ) ;
776-
777- if ( data ) {
778- // Normal body write.
779- this . write ( data , encoding ) ;
780- }
781-
782770 if ( typeof callback === 'function' )
783771 this . once ( 'finish' , callback ) ;
784772
@@ -792,7 +780,7 @@ OutgoingMessage.prototype.end = function end(data, encoding, callback) {
792780 ret = this . _send ( '' , 'latin1' , finish ) ;
793781 }
794782
795- if ( this . connection && data )
783+ if ( uncork )
796784 this . connection . uncork ( ) ;
797785
798786 this . finished = true ;
@@ -871,8 +859,7 @@ OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) {
871859 this . output = [ ] ;
872860 this . outputEncodings = [ ] ;
873861 this . outputCallbacks = [ ] ;
874- if ( typeof this . _onPendingData === 'function' )
875- this . _onPendingData ( - this . outputSize ) ;
862+ this . _onPendingData ( - this . outputSize ) ;
876863 this . outputSize = 0 ;
877864
878865 return ret ;
0 commit comments