Skip to content

Commit 3d328f9

Browse files
committed
refactor: use stream.finished() instead of custom implementation
1 parent f8b5f40 commit 3d328f9

File tree

2 files changed

+45
-58
lines changed

2 files changed

+45
-58
lines changed

index.js

Lines changed: 44 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4636
function 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

9181
function 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

141152
function 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

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
],
99
"license": "MIT",
1010
"repository": "jshttp/on-finished",
11-
"dependencies": {
12-
"ee-first": "1.1.1"
13-
},
1411
"devDependencies": {
1512
"eslint": "8.17.0",
1613
"eslint-config-standard": "14.1.1",
@@ -32,7 +29,7 @@
3229
],
3330
"scripts": {
3431
"lint": "eslint .",
35-
"test": "mocha --reporter spec --bail --check-leaks test/",
32+
"test": "mocha --reporter spec --check-leaks test/",
3633
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
3734
"test-cov": "nyc --reporter=html --reporter=text npm test"
3835
}

0 commit comments

Comments
 (0)