@@ -71,6 +71,24 @@ function OutgoingMessage() {
7171 this . _header = null ;
7272 this . _headers = null ;
7373 this . _headerNames = { } ;
74+
75+ // Call remaining callbacks if stream closes prematurely
76+ this . once ( 'close' , function ( ) {
77+ if ( this . output . length === 0 ) return ;
78+
79+ const err = new Error ( 'stream closed prematurely' ) ;
80+ const outputCallbacks = this . outputCallbacks ;
81+
82+ this . output = [ ] ;
83+ this . outputEncodings = [ ] ;
84+ this . outputCallbacks = [ ] ;
85+
86+ for ( var i = 0 ; i < outputCallbacks . length ; i ++ ) {
87+ let callback = outputCallbacks [ i ] ;
88+ if ( callback )
89+ callback ( err ) ;
90+ }
91+ } ) ;
7492}
7593util . inherits ( OutgoingMessage , Stream ) ;
7694
@@ -162,12 +180,8 @@ OutgoingMessage.prototype._writeRaw = function(data, encoding, callback) {
162180
163181 // Directly write to socket.
164182 return connection . write ( data , encoding , callback ) ;
165- } else if ( connection && connection . destroyed ) {
166- // The socket was destroyed. If we're still trying to write to it,
167- // then we haven't gotten the 'close' event yet.
168- return false ;
169183 } else {
170- // buffer, as long as we're not destroyed.
184+ // buffer, as long as we didn't get the "close" event
171185 return this . _buffer ( data , encoding , callback ) ;
172186 }
173187} ;
@@ -430,10 +444,13 @@ OutgoingMessage.prototype.write = function(chunk, encoding, callback) {
430444 throw new TypeError ( 'first argument must be a string or Buffer' ) ;
431445 }
432446
433-
434447 // If we get an empty string or buffer, then just do nothing, and
435448 // signal the user to keep writing.
436- if ( chunk . length === 0 ) return true ;
449+ if ( chunk . length === 0 ) {
450+ if ( typeof callback === 'function' )
451+ process . nextTick ( callback ) ;
452+ return true ;
453+ }
437454
438455 var len , ret ;
439456 if ( this . chunkedEncoding ) {
@@ -517,11 +534,26 @@ OutgoingMessage.prototype.end = function(data, encoding, callback) {
517534 throw new TypeError ( 'first argument must be a string or Buffer' ) ;
518535 }
519536
537+ var self = this ;
538+
520539 if ( this . finished ) {
540+ if ( data && data . length > 0 ) {
541+ // Report that writing the data has failed
542+ // because the stream was already 'ended'.
543+ var err = new Error ( 'write after end' ) ;
544+ process . nextTick ( function ( ) {
545+ self . emit ( 'error' , err ) ;
546+ if ( callback ) callback ( err ) ;
547+ } ) ;
548+ } else {
549+ // The user wanted to end the stream anyway,
550+ // so we don't need to report a failure.
551+ if ( callback )
552+ process . nextTick ( callback ) ;
553+ }
521554 return false ;
522555 }
523556
524- var self = this ;
525557 function finish ( ) {
526558 self . emit ( 'finish' ) ;
527559 }
0 commit comments