Skip to content

Commit a75e2d2

Browse files
committed
support res.removeListener('drain'), res.once('drain')
Fixes #152
1 parent becc1c0 commit a75e2d2

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

index.js

+21
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ function compression (options) {
6464

6565
var _end = res.end
6666
var _on = res.on
67+
var _removeListener = res.removeListener
6768
var _write = res.write
6869

6970
// flush
@@ -131,6 +132,26 @@ function compression (options) {
131132
return this
132133
}
133134

135+
res.removeListener = function removeListener (type, listener) {
136+
if (!listeners || type !== 'drain') {
137+
return _removeListener.call(this, type, listener)
138+
}
139+
140+
if (stream) {
141+
return stream.removeListener(type, listener)
142+
}
143+
144+
// remove buffered listener
145+
for (var i = 0; i < listeners.length; i++) {
146+
if (listeners[i][0] === type && listeners[i][1] === listener) {
147+
listeners.splice(i, 1)
148+
break
149+
}
150+
}
151+
152+
return this
153+
}
154+
134155
function nocompress (msg) {
135156
debug('no compression: %s', msg)
136157
addListeners(res, _on, listeners)

test/compression.js

+60
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,66 @@ describe('compression()', function () {
301301
.expect(200, done)
302302
})
303303

304+
it('should support removeListener("drain"); stream present', function (done) {
305+
// compression doesn't proxy listenerCount() to the compression stream, so
306+
// instead watch for a MaxListenersExceededWarning
307+
var hasWarned = false
308+
var onWarning = function (warning) {
309+
hasWarned = true
310+
}
311+
process.on('warning', onWarning)
312+
var server = createServer({threshold: 0}, function (req, res) {
313+
res.setHeader('Content-Type', 'text/plain')
314+
var len = bytes('40kb')
315+
var buf = Buffer.alloc(len, '.')
316+
res.write(buf)
317+
// (12 is greater than the default number of max listeners)
318+
for (var times = 0; times < 12; times++) {
319+
var listener = function () {}
320+
res.on('drain', listener)
321+
res.removeListener('drain', listener)
322+
}
323+
res.end()
324+
})
325+
326+
request(server)
327+
.get('/')
328+
.set('Accept-Encoding', 'gzip')
329+
.expect(function () {
330+
process.removeListener('warning', onWarning)
331+
assert.ok(!hasWarned)
332+
})
333+
.expect(200, done)
334+
})
335+
336+
it('should support removeListener("drain"); buffered', function (done) {
337+
// Variant of above test for scenario when the listener is buffered (stream
338+
// is not yet present)
339+
var hasWarned = false
340+
var onWarning = function (warning) {
341+
hasWarned = true
342+
}
343+
process.on('warning', onWarning)
344+
var server = createServer({threshold: 0}, function (req, res) {
345+
res.setHeader('Content-Type', 'text/plain')
346+
for (var times = 0; times < 12; times++) {
347+
var listener = function () {}
348+
res.on('drain', listener)
349+
res.removeListener('drain', listener)
350+
}
351+
res.end()
352+
})
353+
354+
request(server)
355+
.get('/')
356+
.set('Accept-Encoding', 'gzip')
357+
.expect(function () {
358+
process.removeListener('warning', onWarning)
359+
assert.ok(!hasWarned)
360+
})
361+
.expect(200, done)
362+
})
363+
304364
describe('threshold', function () {
305365
it('should not compress responses below the threshold size', function (done) {
306366
var server = createServer({ threshold: '1kb' }, function (req, res) {

0 commit comments

Comments
 (0)