diff --git a/README.md b/README.md index c3375da8..682517b4 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,8 @@ function shouldCompress (req, res) { ### res.flush This module adds a `res.flush()` method to force the partially-compressed -response to be flushed to the client. +response to be flushed to the client. This function accepts a callback which gets +invoked when the response has been flushed to the client ## Examples diff --git a/index.js b/index.js index 3a0c18e3..5dd09c7b 100644 --- a/index.js +++ b/index.js @@ -79,9 +79,9 @@ function compression (options) { var _write = res.write // flush - res.flush = function flush () { + res.flush = function flush (cb) { if (stream) { - stream.flush() + stream.flush(cb) } } diff --git a/package.json b/package.json index 449cbe23..b73fd476 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^5.2.0", "eslint-plugin-standard": "^4.1.0", - "mocha": "^9.2.2", + "mocha": "^10.8.2", "nyc": "^15.1.0", "supertest": "^6.2.3" }, @@ -41,7 +41,7 @@ }, "scripts": { "lint": "eslint .", - "test": "mocha --check-leaks --reporter spec", + "test": "mocha --check-leaks --exit --reporter spec", "test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test" } diff --git a/test/compression.js b/test/compression.js index 9ba4838d..78173c33 100644 --- a/test/compression.js +++ b/test/compression.js @@ -835,6 +835,117 @@ describe('compression()', function () { .end() }) + it('should invoke flush callback when supplied for gzip', function (done) { + var chunks = 0; var callbackInvoked = false + var resp + var server = createServer({ threshold: 0 }, function (req, res) { + resp = res + res.setHeader('Content-Type', 'text/plain') + write() + }) + + function flushCallback () { + callbackInvoked = true + } + + function write () { + chunks++ + if (chunks === 20) return resp.end() + if (chunks > 20) return chunks-- + resp.write('..') + resp.flush(flushCallback) + } + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .request() + .on('response', function (res) { + assert.equal(res.headers['content-encoding'], 'gzip') + res.on('data', write) + res.on('end', function () { + assert.equal(chunks, 20) + assert.equal(callbackInvoked, true) + done() + }) + }) + .end() + }) + + it('should invoke flush callback when supplied for brotli', function (done) { + var chunks = 0; var callbackInvoked = false + var resp + var server = createServer({ threshold: 0 }, function (req, res) { + resp = res + res.setHeader('Content-Type', 'text/plain') + write() + }) + + function flushCallback () { + callbackInvoked = true + } + + function write () { + chunks++ + if (chunks === 20) return resp.end() + if (chunks > 20) return chunks-- + resp.write('..') + resp.flush(flushCallback) + } + + request(server) + .get('/') + .set('Accept-Encoding', 'br') + .request() + .on('response', function (res) { + assert.equal(res.headers['content-encoding'], 'br') + res.on('data', write) + res.on('end', function () { + assert.equal(chunks, 20) + assert.equal(callbackInvoked, true) + done() + }) + }) + .end() + }) + + it('should invoke flush callback when supplied for deflate', function (done) { + var chunks = 0; var callbackInvoked = false + var resp + var server = createServer({ threshold: 0 }, function (req, res) { + resp = res + res.setHeader('Content-Type', 'text/plain') + write() + }) + + function flushCallback () { + callbackInvoked = true + } + + function write () { + chunks++ + if (chunks === 20) return resp.end() + if (chunks > 20) return chunks-- + resp.write('..') + resp.flush(flushCallback) + } + + request(server) + .get('/') + .set('Accept-Encoding', 'deflate') + .request() + .on('response', function (res) { + assert.equal(res.headers['content-encoding'], 'deflate') + res.on('data', write) + res.on('end', function () { + assert.equal(chunks, 20) + assert.equal(callbackInvoked, true) + done() + }) + }) + .end() + }) + it('should flush small chunks for deflate', function (done) { var chunks = 0 var next