From c73f1f339987a658d0f0e150a0f162dce1d2d6fa Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 3 Jun 2014 20:30:46 -0400 Subject: [PATCH] fix listeners for delayed stream creation fixes #11 fixes #12 --- HISTORY.md | 5 +++++ index.js | 35 ++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 3123b368..a03a5a99 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * fix listeners for delayed stream creation + 1.0.4 / 2014-06-03 ================== diff --git a/index.js b/index.js index a3a45224..46dc229f 100644 --- a/index.js +++ b/index.js @@ -56,6 +56,7 @@ module.exports = function compression(options) { } return function compression(req, res, next){ + var listeners = [] var write = res.write var on = res.on var end = res.end @@ -108,39 +109,47 @@ module.exports = function compression(options) { }; res.on = function(type, listener){ - if (!stream || type !== 'drain') { + if (type !== 'drain') { return on.call(this, type, listener) } - return stream.on(type, listener) + if (stream) { + return stream.on(type, listener) + } + + // buffer listeners for future stream + listeners.push([type, listener]) + + return this } onHeaders(res, function(){ // default request filter - if (!filter(req, res)) return; + if (!filter(req, res)) return addListeners(res, on, listeners); // vary vary(res, 'Accept-Encoding') - if (!compress) return; + if (!compress) return addListeners(res, on, listeners); var encoding = res.getHeader('Content-Encoding') || 'identity'; // already encoded - if ('identity' != encoding) return; + if ('identity' != encoding) return addListeners(res, on, listeners); // head - if ('HEAD' == req.method) return; + if ('HEAD' == req.method) return addListeners(res, on, listeners); // compression method var accept = accepts(req); var method = accept.encodings(['gzip', 'deflate', 'identity']); // negotiation failed - if (!method || method === 'identity') return; + if (!method || method === 'identity') return addListeners(res, on, listeners); // compression stream stream = exports.methods[method](options); + addListeners(stream, stream.on, listeners); // overwrite the flush method res.flush = function(){ @@ -171,6 +180,18 @@ module.exports = function compression(options) { }; }; +/** + * Add bufferred listeners to stream + */ + +function addListeners(stream, on, listeners) { + var args + + while ((args = listeners.shift())) { + on.apply(stream, args) + } +} + function noop(){} /**