@@ -20,18 +20,8 @@ module.exports.isFinished = isFinished
2020 * @private
2121 */
2222
23- var asyncHooks = tryRequireAsyncHooks ( )
24- var first = require ( 'ee-first' )
25-
26- /**
27- * Variables.
28- * @private
29- */
30-
31- /* istanbul ignore next */
32- var defer = typeof setImmediate === 'function'
33- ? setImmediate
34- : function ( fn ) { process . nextTick ( fn . bind . apply ( fn , arguments ) ) }
23+ const asyncHooks = tryRequireAsyncHooks ( )
24+ const stream = require ( 'stream' )
3525
3626/**
3727 * Invoke callback when the response has finished, useful for
@@ -45,7 +35,7 @@ var defer = typeof setImmediate === 'function'
4535
4636function onFinished ( msg , listener ) {
4737 if ( isFinished ( msg ) !== false ) {
48- defer ( listener , null , msg )
38+ setImmediate ( listener , null , msg )
4939 return msg
5040 }
5141
@@ -89,57 +79,78 @@ function isFinished (msg) {
8979 */
9080
9181function attachFinishedListener ( msg , callback ) {
92- var eeMsg
93- var eeSocket
94- var finished = false
82+ let finished = false
83+ let cleanupSocket
9584
9685 function onFinish ( error ) {
97- eeMsg . cancel ( )
98- eeSocket . cancel ( )
99-
86+ if ( finished ) return
10087 finished = true
10188 callback ( error )
10289 }
10390
104- // finished on first message event
105- eeMsg = eeSocket = first ( [ [ msg , 'end' , 'finish' ] ] , onFinish )
91+ const cleanupFinished = stream . finished ( msg , ( error ) => {
92+ cleanupFinished ( )
93+ if ( cleanupSocket ) {
94+ cleanupSocket ( )
95+ }
96+
97+ // ignore premature close error
98+ if ( error && error . code !== 'ERR_STREAM_PREMATURE_CLOSE' ) {
99+ onFinish ( error )
100+ } else {
101+ onFinish ( )
102+ }
103+ } )
106104
107105 function onSocket ( socket ) {
108106 // remove listener
109107 msg . removeListener ( 'socket' , onSocket )
110108
111109 if ( finished ) return
112- if ( eeMsg !== eeSocket ) return
110+
111+ function onSocketErrorOrClose ( error ) {
112+ // remove listeners
113+ socket . removeListener ( 'error' , onSocketErrorOrClose )
114+ socket . removeListener ( 'close' , onSocketErrorOrClose )
115+
116+ onFinish ( error )
117+ }
113118
114119 // finished on first socket event
115- eeSocket = first ( [ [ socket , 'error' , 'close' ] ] , onFinish )
120+ socket . on ( 'error' , onSocketErrorOrClose )
121+ socket . on ( 'close' , onSocketErrorOrClose )
122+
123+ // cleanup socket listeners
124+ cleanupSocket = function ( ) {
125+ socket . removeListener ( 'error' , onSocketErrorOrClose )
126+ socket . removeListener ( 'close' , onSocketErrorOrClose )
127+ }
116128 }
117129
118130 if ( msg . socket ) {
119131 // socket already assigned
120132 onSocket ( msg . socket )
121- return
122- }
133+ } else {
134+ // wait for socket to be assigned
135+ msg . on ( 'socket' , onSocket )
123136
124- // wait for socket to be assigned
125- msg . on ( 'socket' , onSocket )
126-
127- if ( msg . socket === undefined ) {
128- // istanbul ignore next: node.js 0.8 patch
129- patchAssignSocket ( msg , onSocket )
137+ // cleanup socket listener in case the socket is never assigned
138+ cleanupSocket = function ( ) {
139+ msg . removeListener ( 'socket' , onSocket )
140+ }
130141 }
131142}
132143
133144/**
134145 * Attach the listener to the message.
135146 *
136147 * @param {object } msg
137- * @return {function }
148+ * @param {function } listener
138149 * @private
139150 */
140151
141152function attachListener ( msg , listener ) {
142- var attached = msg . __onFinished
153+ let attached = msg . __onFinished
143154
144155 // create a private single listener with queue
145156 if ( ! attached || ! attached . queue ) {
@@ -176,27 +187,6 @@ function createListener (msg) {
176187 return listener
177188}
178189
179- /**
180- * Patch ServerResponse.prototype.assignSocket for node.js 0.8.
181- *
182- * @param {ServerResponse } res
183- * @param {function } callback
184- * @private
185- */
186-
187- // istanbul ignore next: node.js 0.8 patch
188- function patchAssignSocket ( res , callback ) {
189- var assignSocket = res . assignSocket
190-
191- if ( typeof assignSocket !== 'function' ) return
192-
193- // res.on('socket', callback) is broken in 0.8
194- res . assignSocket = function _assignSocket ( socket ) {
195- assignSocket . call ( this , socket )
196- callback ( socket )
197- }
198- }
199-
200190/**
201191 * Try to require async_hooks
202192 * @private
0 commit comments