@@ -20,18 +20,8 @@ module.exports.isFinished = isFinished
20
20
* @private
21
21
*/
22
22
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' )
35
25
36
26
/**
37
27
* Invoke callback when the response has finished, useful for
@@ -45,7 +35,7 @@ var defer = typeof setImmediate === 'function'
45
35
46
36
function onFinished ( msg , listener ) {
47
37
if ( isFinished ( msg ) !== false ) {
48
- defer ( listener , null , msg )
38
+ setImmediate ( listener , null , msg )
49
39
return msg
50
40
}
51
41
@@ -89,57 +79,78 @@ function isFinished (msg) {
89
79
*/
90
80
91
81
function attachFinishedListener ( msg , callback ) {
92
- var eeMsg
93
- var eeSocket
94
- var finished = false
82
+ let finished = false
83
+ let cleanupSocket
95
84
96
85
function onFinish ( error ) {
97
- eeMsg . cancel ( )
98
- eeSocket . cancel ( )
99
-
86
+ if ( finished ) return
100
87
finished = true
101
88
callback ( error )
102
89
}
103
90
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
+ } )
106
104
107
105
function onSocket ( socket ) {
108
106
// remove listener
109
107
msg . removeListener ( 'socket' , onSocket )
110
108
111
109
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
+ }
113
118
114
119
// 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
+ }
116
128
}
117
129
118
130
if ( msg . socket ) {
119
131
// socket already assigned
120
132
onSocket ( msg . socket )
121
- return
122
- }
133
+ } else {
134
+ // wait for socket to be assigned
135
+ msg . on ( 'socket' , onSocket )
123
136
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
+ }
130
141
}
131
142
}
132
143
133
144
/**
134
145
* Attach the listener to the message.
135
146
*
136
147
* @param {object } msg
137
- * @return {function }
148
+ * @param {function } listener
138
149
* @private
139
150
*/
140
151
141
152
function attachListener ( msg , listener ) {
142
- var attached = msg . __onFinished
153
+ let attached = msg . __onFinished
143
154
144
155
// create a private single listener with queue
145
156
if ( ! attached || ! attached . queue ) {
@@ -176,27 +187,6 @@ function createListener (msg) {
176
187
return listener
177
188
}
178
189
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
-
200
190
/**
201
191
* Try to require async_hooks
202
192
* @private
0 commit comments