@@ -78,6 +78,9 @@ utcDate._onTimeout = function _onTimeout() {
78
78
} ;
79
79
80
80
81
+ function noopPendingOutput ( amount ) { }
82
+
83
+
81
84
function OutgoingMessage ( ) {
82
85
Stream . call ( this ) ;
83
86
@@ -117,7 +120,7 @@ function OutgoingMessage() {
117
120
this . _header = null ;
118
121
this [ outHeadersKey ] = null ;
119
122
120
- this . _onPendingData = null ;
123
+ this . _onPendingData = noopPendingOutput ;
121
124
}
122
125
util . inherits ( OutgoingMessage , Stream ) ;
123
126
@@ -234,12 +237,18 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) {
234
237
( encoding === 'utf8' || encoding === 'latin1' || ! encoding ) ) {
235
238
data = this . _header + data ;
236
239
} 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 ) ;
243
252
}
244
253
this . _headerSent = true ;
245
254
}
@@ -275,19 +284,13 @@ function _writeRaw(data, encoding, callback) {
275
284
return conn . write ( data , encoding , callback ) ;
276
285
}
277
286
// 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 ) {
283
287
this . output . push ( data ) ;
284
288
this . outputEncodings . push ( encoding ) ;
285
289
this . outputCallbacks . push ( callback ) ;
286
290
this . outputSize += data . length ;
287
- if ( typeof this . _onPendingData === 'function' )
288
- this . _onPendingData ( data . length ) ;
291
+ this . _onPendingData ( data . length ) ;
289
292
return false ;
290
- } ;
293
+ }
291
294
292
295
293
296
OutgoingMessage . prototype . _storeHeader = _storeHeader ;
@@ -624,27 +627,31 @@ Object.defineProperty(OutgoingMessage.prototype, 'headersSent', {
624
627
625
628
const crlf_buf = Buffer . from ( '\r\n' ) ;
626
629
OutgoingMessage . 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 ) {
628
635
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 ) ,
631
638
err ,
632
639
callback ) ;
633
640
634
641
return true ;
635
642
}
636
643
637
- if ( ! this . _header ) {
638
- this . _implicitHeader ( ) ;
644
+ if ( ! msg . _header ) {
645
+ msg . _implicitHeader ( ) ;
639
646
}
640
647
641
- if ( ! this . _hasBody ) {
648
+ if ( ! msg . _hasBody ) {
642
649
debug ( 'This type of response MUST NOT have a body. ' +
643
650
'Ignoring write() calls.' ) ;
644
651
return true ;
645
652
}
646
653
647
- if ( typeof chunk !== 'string' && ! ( chunk instanceof Buffer ) ) {
654
+ if ( ! fromEnd && typeof chunk !== 'string' && ! ( chunk instanceof Buffer ) ) {
648
655
throw new TypeError ( 'First argument must be a string or Buffer' ) ;
649
656
}
650
657
@@ -654,38 +661,28 @@ OutgoingMessage.prototype.write = function write(chunk, encoding, callback) {
654
661
if ( chunk . length === 0 ) return true ;
655
662
656
663
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' )
662
666
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 ;
676
669
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 ) ;
681
673
}
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 ) ;
682
679
} else {
683
- ret = this . _send ( chunk , encoding , callback ) ;
680
+ ret = msg . _send ( chunk , encoding , callback ) ;
684
681
}
685
682
686
683
debug ( 'write ret = ' + ret ) ;
687
684
return ret ;
688
- } ;
685
+ }
689
686
690
687
691
688
function writeAfterEndNT ( err , callback ) {
@@ -736,49 +733,40 @@ function onFinish(outmsg) {
736
733
outmsg . emit ( 'finish' ) ;
737
734
}
738
735
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 ;
743
740
} else if ( typeof encoding === 'function' ) {
744
741
callback = encoding ;
745
742
encoding = null ;
746
743
}
747
744
748
- if ( data && typeof data !== 'string' && ! ( data instanceof Buffer ) ) {
749
- throw new TypeError ( 'First argument must be a string or Buffer' ) ;
750
- }
751
-
752
745
if ( this . finished ) {
753
746
return false ;
754
747
}
755
748
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 ) ;
760
757
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 ;
764
763
}
764
+ write_ ( this , chunk , encoding , null , true ) ;
765
+ } else if ( ! this . _header ) {
766
+ this . _contentLength = 0 ;
765
767
this . _implicitHeader ( ) ;
766
768
}
767
769
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
-
782
770
if ( typeof callback === 'function' )
783
771
this . once ( 'finish' , callback ) ;
784
772
@@ -792,7 +780,7 @@ OutgoingMessage.prototype.end = function end(data, encoding, callback) {
792
780
ret = this . _send ( '' , 'latin1' , finish ) ;
793
781
}
794
782
795
- if ( this . connection && data )
783
+ if ( uncork )
796
784
this . connection . uncork ( ) ;
797
785
798
786
this . finished = true ;
@@ -871,8 +859,7 @@ OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) {
871
859
this . output = [ ] ;
872
860
this . outputEncodings = [ ] ;
873
861
this . outputCallbacks = [ ] ;
874
- if ( typeof this . _onPendingData === 'function' )
875
- this . _onPendingData ( - this . outputSize ) ;
862
+ this . _onPendingData ( - this . outputSize ) ;
876
863
this . outputSize = 0 ;
877
864
878
865
return ret ;
0 commit comments