From f4a997ed406f7488a65554616456690808e42820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 03:26:50 -0300 Subject: [PATCH 01/29] fix: call underlying implementation properly --- index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 1d089427..7ec4596b 100644 --- a/index.js +++ b/index.js @@ -75,7 +75,7 @@ function compression (options) { // proxy - res.write = function write (chunk, encoding) { + res.write = function write (chunk, encoding, cb) { if (ended) { return false } @@ -85,11 +85,11 @@ function compression (options) { } return stream - ? stream.write(toBuffer(chunk, encoding)) + ? stream.write(toBuffer(chunk, encoding), cb || encoding) : _write.call(this, chunk, encoding) } - res.end = function end (chunk, encoding) { + res.end = function end (chunk, encoding, cb) { if (ended) { return false } @@ -112,7 +112,7 @@ function compression (options) { // write Buffer for Node.js 0.8 return chunk - ? stream.end(toBuffer(chunk, encoding)) + ? stream.end(toBuffer(chunk, encoding), cb || encoding) : stream.end() } From 3ad026f7cf6bcc00802dab95f48d30318b2fb176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:07:56 -0300 Subject: [PATCH 02/29] test(response): test response write with cb --- test/compression.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/compression.js b/test/compression.js index 6975ea0b..5069e07a 100644 --- a/test/compression.js +++ b/test/compression.js @@ -10,6 +10,26 @@ var zlib = require('zlib') var compression = require('..') describe('compression()', function () { + it('request should end', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + + res.write(Buffer.from('hello, world'), (err) => { + if (err) { + console.error('err', err) + } + + res.end() + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldNotHaveHeader('Content-Encoding')) + .expect(200, done) + }) + it('should skip HEAD', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') From 03361ecf1098e9f8b0a9ad0f34a888dcce26d055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:25:26 -0300 Subject: [PATCH 03/29] test(response.write): fix test expect --- test/compression.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/compression.js b/test/compression.js index 5069e07a..551b365b 100644 --- a/test/compression.js +++ b/test/compression.js @@ -11,10 +11,12 @@ var compression = require('..') describe('compression()', function () { it('request should end', function (done) { + var reponseText = 'hello, world' + var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') - res.write(Buffer.from('hello, world'), (err) => { + res.write(Buffer.from(reponseText), (err) => { if (err) { console.error('err', err) } @@ -26,7 +28,7 @@ describe('compression()', function () { request(server) .get('/') .set('Accept-Encoding', 'gzip') - .expect(shouldNotHaveHeader('Content-Encoding')) + .expect(shouldHaveBodyLength(reponseText.length)) .expect(200, done) }) From d76b3cbb11cab9adc32165151edbbdb233bb53d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:33:14 -0300 Subject: [PATCH 04/29] fix(response.write): call underlying implementation properly --- index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 7ec4596b..20f1164b 100644 --- a/index.js +++ b/index.js @@ -85,8 +85,8 @@ function compression (options) { } return stream - ? stream.write(toBuffer(chunk, encoding), cb || encoding) - : _write.call(this, chunk, encoding) + ? stream.write(toBuffer(chunk, encoding), encoding, cb) + : _write.call(this, chunk, encoding, cb) } res.end = function end (chunk, encoding, cb) { @@ -104,7 +104,7 @@ function compression (options) { } if (!stream) { - return _end.call(this, chunk, encoding) + return _end.call(this, chunk, encoding, cb) } // mark ended @@ -112,7 +112,7 @@ function compression (options) { // write Buffer for Node.js 0.8 return chunk - ? stream.end(toBuffer(chunk, encoding), cb || encoding) + ? stream.end(toBuffer(chunk, encoding), encoding, cb) : stream.end() } From 46538254a23eb7b6bfb7250e710d1518027532f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:35:48 -0300 Subject: [PATCH 05/29] test(response.write): should have Content-Encoding header --- test/compression.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/compression.js b/test/compression.js index 551b365b..37345eca 100644 --- a/test/compression.js +++ b/test/compression.js @@ -28,6 +28,7 @@ describe('compression()', function () { request(server) .get('/') .set('Accept-Encoding', 'gzip') + .expect(shouldHaveHeader('Content-Encoding')) .expect(shouldHaveBodyLength(reponseText.length)) .expect(200, done) }) @@ -702,6 +703,12 @@ function shouldHaveBodyLength (length) { } } +function shouldHaveHeader (header) { + return function (res) { + assert.ok((header.toLowerCase() in res.headers), 'should have header ' + header) + } +} + function shouldNotHaveHeader (header) { return function (res) { assert.ok(!(header.toLowerCase() in res.headers), 'should not have header ' + header) From 244059825091dcc138e1b3d76dfee67be07eb8e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:42:22 -0300 Subject: [PATCH 06/29] fix(response.write): handle optional arguments --- index.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 20f1164b..1fe4f689 100644 --- a/index.js +++ b/index.js @@ -80,6 +80,11 @@ function compression (options) { return false } + if (!cb && typeof encoding === 'function') { + cb = encoding + encoding = undefined + } + if (!this._header) { this._implicitHeader() } @@ -94,6 +99,11 @@ function compression (options) { return false } + if (!cb && typeof encoding === 'function') { + cb = encoding + encoding = undefined + } + if (!this._header) { // estimate the length if (!this.getHeader('Content-Length')) { @@ -113,7 +123,7 @@ function compression (options) { // write Buffer for Node.js 0.8 return chunk ? stream.end(toBuffer(chunk, encoding), encoding, cb) - : stream.end() + : stream.end(cb) } res.on = function on (type, listener) { From 2991c82fe08371778c15751db0eee622d2018bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 10 Jul 2022 04:57:12 -0300 Subject: [PATCH 07/29] fix(response.write): handle end(cb) --- index.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 1fe4f689..564f64b6 100644 --- a/index.js +++ b/index.js @@ -99,9 +99,14 @@ function compression (options) { return false } - if (!cb && typeof encoding === 'function') { - cb = encoding - encoding = undefined + if (!cb) { + if (typeof chunk === 'function') { + cb = chunk + chunk = encoding = undefined + } else if (typeof encoding === 'function') { + cb = encoding + encoding = undefined + } } if (!this._header) { From 2b3369cc158c4ca1dcfffc0d523ed37073ebc701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Mon, 11 Jul 2022 23:34:45 -0300 Subject: [PATCH 08/29] refactor(response-proxy): match nodejs behavior --- index.js | 69 ++++++++++++----- test/compression.js | 176 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 215 insertions(+), 30 deletions(-) diff --git a/index.js b/index.js index 564f64b6..57932f0e 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,8 @@ var debug = require('debug')('compression') var onHeaders = require('on-headers') var vary = require('vary') var zlib = require('zlib') +var isUint8Array = require('@stdlib/assert-is-uint8array') +const { ServerResponse } = require('http') /** * Module exports. @@ -56,6 +58,8 @@ function compression (options) { threshold = 1024 } + function noop () { } + return function compression (req, res, next) { var ended = false var length @@ -75,40 +79,69 @@ function compression (options) { // proxy - res.write = function write (chunk, encoding, cb) { - if (ended) { - return false + res.write = function write (chunk, encoding, callback) { + if (chunk === null) { + // throw ERR_STREAM_NULL_VALUES + return _write.call(this, chunk, encoding, callback) + } else if (typeof chunk === 'string' || isUint8Array(chunk)) { + // noop + } else { + // throw ERR_INVALID_ARG_TYPE + return _write.call(this, chunk, encoding, callback) } - if (!cb && typeof encoding === 'function') { - cb = encoding + if (!callback && typeof encoding === 'function') { + callback = encoding encoding = undefined } + if (typeof callback !== 'function') { + callback = noop + } + + if (res.destroyed || res.finished || ended) { + // HACK: node doesn't expose internal errors, + // we need to fake response to throw underlying errors type + var fakeRes = new ServerResponse({}) + if (!res.destroyed) { + fakeRes.destroyed = fakeRes.finished = true + } else { + fakeRes.destroyed = true + } + // throw ERR_STREAM_DESTROYED or ERR_STREAM_WRITE_AFTER_END + return _write.call(fakeRes, chunk, encoding, callback) + } + if (!this._header) { this._implicitHeader() } return stream - ? stream.write(toBuffer(chunk, encoding), encoding, cb) - : _write.call(this, chunk, encoding, cb) + ? stream.write(toBuffer(chunk, encoding), encoding, callback) + : _write.call(this, chunk, encoding, callback) } - res.end = function end (chunk, encoding, cb) { - if (ended) { - return false - } - - if (!cb) { + res.end = function end (chunk, encoding, callback) { + if (!callback) { if (typeof chunk === 'function') { - cb = chunk + callback = chunk chunk = encoding = undefined } else if (typeof encoding === 'function') { - cb = encoding + callback = encoding encoding = undefined } } + if (typeof callback !== 'function') { + callback = noop + } + + if (this.destroyed || this.finished || ended) { + this.finished = ended + // throw ERR_STREAM_WRITE_AFTER_END or ERR_STREAM_ALREADY_FINISHED + return _end.call(this, chunk, encoding, callback) + } + if (!this._header) { // estimate the length if (!this.getHeader('Content-Length')) { @@ -119,7 +152,7 @@ function compression (options) { } if (!stream) { - return _end.call(this, chunk, encoding, cb) + return _end.call(this, chunk, encoding, callback) } // mark ended @@ -127,8 +160,8 @@ function compression (options) { // write Buffer for Node.js 0.8 return chunk - ? stream.end(toBuffer(chunk, encoding), encoding, cb) - : stream.end(cb) + ? stream.end(toBuffer(chunk, encoding), encoding, callback) + : stream.end(callback) } res.on = function on (type, listener) { diff --git a/test/compression.js b/test/compression.js index 37345eca..b85de1b9 100644 --- a/test/compression.js +++ b/test/compression.js @@ -6,21 +6,136 @@ var crypto = require('crypto') var http = require('http') var request = require('supertest') var zlib = require('zlib') +var sinon = require('sinon') var compression = require('..') describe('compression()', function () { - it('request should end', function (done) { - var reponseText = 'hello, world' + describe('should work with valid types (string, Buffer, Uint8Array)', function () { + it('res.write(string)', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end('hello world') + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, done) + }) + + it('res.write(Buffer)', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end(Buffer.from('hello world')) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, done) + }) + + it('res.write(Uint8Array)', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end(new Uint8Array(1)) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, done) + }) + }) + + describe('should throw with invalid types', function () { + it('res.write(1) should fire ERR_INVALID_ARG_TYPE', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + try { + res.write(1) + } catch (err) { + assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') + res.statusCode = 500 + res.flush() + res.end() + } + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(500, done) + }) + + it('res.write({}) should fire ERR_INVALID_ARG_TYPE', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + try { + res.write({}) + } catch (err) { + assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') + res.statusCode = 500 + res.flush() + res.end() + } + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(500, done) + }) + it('res.write(null) should fire ERR_STREAM_NULL_VALUES', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + try { + res.write(null) + } catch (err) { + assert.ok(err.code === 'ERR_STREAM_NULL_VALUES') + res.statusCode = 500 + res.flush() + res.end() + } + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(500, done) + }) + }) + + it('res.write() should throw ERR_STREAM_DESTROYED when destoyed stream', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') + res.end('hello world') - res.write(Buffer.from(reponseText), (err) => { - if (err) { - console.error('err', err) - } + server.on('close', () => { + res.write('hello world', function (err) { + assert.ok(err.code === 'ERR_STREAM_DESTROYED') + }) + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldHaveHeader('Content-Encoding')) + .expect(shouldHaveBodyLength('hello world'.length)) + .expect(200, done) + }) + it('res.write() should call callback if passsed', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + + res.write('hello, world', function () { res.end() }) }) @@ -29,10 +144,32 @@ describe('compression()', function () { .get('/') .set('Accept-Encoding', 'gzip') .expect(shouldHaveHeader('Content-Encoding')) - .expect(shouldHaveBodyLength(reponseText.length)) + .expect(shouldHaveBodyLength('hello, world'.length)) .expect(200, done) }) + it('res.write() should call callback with error after end', function (done) { + var onError = sinon.spy(function (err) { + assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') + }) + + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end() + + res.write('hello, world', onError) + + process.nextTick(function () { + assert.ok(onError.callCount > 0) + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .end(done) + }) + it('should skip HEAD', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') @@ -460,17 +597,28 @@ describe('compression()', function () { }) it('should return false writing after end', function (done) { + var onError = sinon.spy(function (err) { + assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') + }) + var server = createServer({ threshold: 0 }, function (req, res) { + res.on('error', onError) res.setHeader('Content-Type', 'text/plain') + res.end('hello, world') - assert.ok(res.write() === false) - assert.ok(res.end() === false) + + assert.ok(res.write('', onError) === false) + + process.nextTick(function () { + assert.ok(onError.callCount > 0) + }) }) request(server) .get('/') .set('Accept-Encoding', 'gzip') - .expect('Content-Encoding', 'gzip', done) + .expect('Content-Encoding', 'gzip') + .end(done) }) }) @@ -682,9 +830,12 @@ describe('compression()', function () { }) }) -function createServer (opts, fn) { +function createServer (opts, fn, t) { var _compression = compression(opts) return http.createServer(function (req, res) { + if (t) { + res.on('finish', function () { console.log(t.title, 'server closed') }) + } _compression(req, res, function (err) { if (err) { res.statusCode = err.status || 500 @@ -705,7 +856,8 @@ function shouldHaveBodyLength (length) { function shouldHaveHeader (header) { return function (res) { - assert.ok((header.toLowerCase() in res.headers), 'should have header ' + header) + var ok = (header.toLowerCase() in res.headers) + assert.ok(ok, 'should have header ' + header) } } From 3493e8ce022e79918da887f13178962e0c9d1923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Mon, 11 Jul 2022 23:42:29 -0300 Subject: [PATCH 09/29] test(compression): avoid arrow fn --- test/compression.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compression.js b/test/compression.js index b85de1b9..30d1c95d 100644 --- a/test/compression.js +++ b/test/compression.js @@ -116,7 +116,7 @@ describe('compression()', function () { res.setHeader('Content-Type', 'text/plain') res.end('hello world') - server.on('close', () => { + server.on('close', function () { res.write('hello world', function (err) { assert.ok(err.code === 'ERR_STREAM_DESTROYED') }) From 50ca417f02c66394a150c1824c5ca98256a76bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Tue, 12 Jul 2022 00:15:13 -0300 Subject: [PATCH 10/29] test(compression): add ERR_STREAM_ALREADY_FINISHED --- test/compression.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/compression.js b/test/compression.js index 30d1c95d..67330ccd 100644 --- a/test/compression.js +++ b/test/compression.js @@ -111,7 +111,7 @@ describe('compression()', function () { }) }) - it('res.write() should throw ERR_STREAM_DESTROYED when destoyed stream', function (done) { + it('res.write() should throw ERR_STREAM_DESTROYED when stream is already destroyed', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') res.end('hello world') @@ -131,6 +131,26 @@ describe('compression()', function () { .expect(200, done) }) + it('res.write() should throw ERR_STREAM_ALREADY_FINISHED when stream is already finished', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end('hello world') + + server.on('close', function () { + res.end(function (err) { + assert.ok(err.code === 'ERR_STREAM_ALREADY_FINISHED') + }) + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldHaveHeader('Content-Encoding')) + .expect(shouldHaveBodyLength('hello world'.length)) + .expect(200, done) + }) + it('res.write() should call callback if passsed', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') From e87ca6b9086ed30ea997c997cc5afee8050f7652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Wed, 13 Jul 2022 09:06:30 -0300 Subject: [PATCH 11/29] fix(package): add missing dep --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 30f8422c..cfa50f29 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "license": "MIT", "repository": "expressjs/compression", "dependencies": { + "@stdlib/assert-is-uint8array": "^0.0.8", "accepts": "~1.3.7", "bytes": "3.0.0", "compressible": "~2.0.17", @@ -28,7 +29,8 @@ "eslint-plugin-standard": "4.0.1", "istanbul": "0.4.5", "mocha": "6.2.0", - "supertest": "4.0.2" + "supertest": "4.0.2", + "sinon": "^4.0.0" }, "files": [ "LICENSE", From 48c7ad6ce21e700603e4d3ff2fd384b8d7a797e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Wed, 13 Jul 2022 15:33:15 -0300 Subject: [PATCH 12/29] fix(package): format --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5dc8e08..a8d07669 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "eslint-plugin-standard": "4.0.1", "istanbul": "0.4.5", "mocha": "6.2.3", - "supertest": "4.0.2" + "supertest": "4.0.2", "sinon": "^4.0.0" }, "files": [ From 1abb05607fb0eea43130dea795a20db9c9730e87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sat, 16 Jul 2022 10:45:01 -0300 Subject: [PATCH 13/29] fix(package): use sinon 4.5.0 target --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a8d07669..07bf4ed6 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "istanbul": "0.4.5", "mocha": "6.2.3", "supertest": "4.0.2", - "sinon": "^4.0.0" + "sinon": "4.5.0" }, "files": [ "LICENSE", From ee0c68c7721b85477384c7b877cf0347ee9f2c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 21:06:30 -0300 Subject: [PATCH 14/29] refactor(lib): remove assert-is-uint8array dependency --- index.js | 7 +++++-- package.json | 8 ++++---- test/compression.js | 20 -------------------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/index.js b/index.js index 57932f0e..bc105fc7 100644 --- a/index.js +++ b/index.js @@ -22,8 +22,7 @@ var debug = require('debug')('compression') var onHeaders = require('on-headers') var vary = require('vary') var zlib = require('zlib') -var isUint8Array = require('@stdlib/assert-is-uint8array') -const { ServerResponse } = require('http') +var { ServerResponse } = require('http') /** * Module exports. @@ -38,6 +37,10 @@ module.exports.filter = shouldCompress */ var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/ +var hasUint8Array = (typeof Uint8Array === 'function') +function isUint8Array (arg) { + return hasUint8Array && arg && (arg instanceof Uint8Array || arg.toString() === '[object Uint8Array]') +} /** * Compress response data with gzip / deflate. diff --git a/package.json b/package.json index 9dd0d611..a4a7d5d1 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "license": "MIT", "repository": "expressjs/compression", "dependencies": { - "@stdlib/assert-is-uint8array": "^0.0.8", "accepts": "~1.3.8", "bytes": "3.0.0", "compressible": "~2.0.18", @@ -29,8 +28,9 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.2", "nyc": "15.1.0", - "supertest": "6.2.3", - "sinon": "4.5.0" + "semver": "^7.3.7", + "sinon": "4.5.0", + "supertest": "6.2.3" }, "files": [ "LICENSE", @@ -42,7 +42,7 @@ }, "scripts": { "lint": "eslint .", - "test": "mocha --check-leaks --reporter spec --bail", + "test": "mocha --check-leaks -reporter spec --bail", "test-ci": "nyc --reporter=lcovonly --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test" } diff --git a/test/compression.js b/test/compression.js index 67330ccd..c4148034 100644 --- a/test/compression.js +++ b/test/compression.js @@ -111,26 +111,6 @@ describe('compression()', function () { }) }) - it('res.write() should throw ERR_STREAM_DESTROYED when stream is already destroyed', function (done) { - var server = createServer({ threshold: 0 }, function (req, res) { - res.setHeader('Content-Type', 'text/plain') - res.end('hello world') - - server.on('close', function () { - res.write('hello world', function (err) { - assert.ok(err.code === 'ERR_STREAM_DESTROYED') - }) - }) - }) - - request(server) - .get('/') - .set('Accept-Encoding', 'gzip') - .expect(shouldHaveHeader('Content-Encoding')) - .expect(shouldHaveBodyLength('hello world'.length)) - .expect(200, done) - }) - it('res.write() should throw ERR_STREAM_ALREADY_FINISHED when stream is already finished', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') From b96d7ac632d7c5d4f42ac9bf50756ac7667f87f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 21:15:10 -0300 Subject: [PATCH 15/29] fix(package): remove semver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a4a7d5d1..da882804 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.2", "nyc": "15.1.0", - "semver": "^7.3.7", + "sinon": "4.5.0", "supertest": "6.2.3" }, From 0736a7fa36db42f564bfb5bface1f3b980a0d850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 21:34:37 -0300 Subject: [PATCH 16/29] fix(package): typo in test script --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index da882804..9fc111bc 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.2", "nyc": "15.1.0", - "sinon": "4.5.0", "supertest": "6.2.3" }, @@ -42,7 +41,7 @@ }, "scripts": { "lint": "eslint .", - "test": "mocha --check-leaks -reporter spec --bail", + "test": "mocha --check-leaks --reporter spec --bail", "test-ci": "nyc --reporter=lcovonly --reporter=text npm test", "test-cov": "nyc --reporter=html --reporter=text npm test" } From 27c391f0a42efc9adcf61e26347e50e379f6598d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 21:39:41 -0300 Subject: [PATCH 17/29] use sinon 3.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9fc111bc..66e5b63f 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.2", "nyc": "15.1.0", - "sinon": "4.5.0", + "sinon": "3.3.0", "supertest": "6.2.3" }, "files": [ From 96bccad6964c7eda9a6917272b1c62abce785860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 22:31:09 -0300 Subject: [PATCH 18/29] remove sinon --- package.json | 1 - test/compression.js | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 66e5b63f..41f27fb2 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "eslint-plugin-standard": "4.1.0", "mocha": "9.2.2", "nyc": "15.1.0", - "sinon": "3.3.0", "supertest": "6.2.3" }, "files": [ diff --git a/test/compression.js b/test/compression.js index c4148034..c8bfd12b 100644 --- a/test/compression.js +++ b/test/compression.js @@ -6,7 +6,6 @@ var crypto = require('crypto') var http = require('http') var request = require('supertest') var zlib = require('zlib') -var sinon = require('sinon') var compression = require('..') @@ -149,9 +148,11 @@ describe('compression()', function () { }) it('res.write() should call callback with error after end', function (done) { - var onError = sinon.spy(function (err) { + var onErrorCalled = false + var onError = function (err) { assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') - }) + onErrorCalled = true + } var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') @@ -160,7 +161,7 @@ describe('compression()', function () { res.write('hello, world', onError) process.nextTick(function () { - assert.ok(onError.callCount > 0) + assert.ok(onErrorCalled) }) }) @@ -597,9 +598,11 @@ describe('compression()', function () { }) it('should return false writing after end', function (done) { - var onError = sinon.spy(function (err) { + var onErrorCalled = false + var onError = function (err) { assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') - }) + onErrorCalled = true + } var server = createServer({ threshold: 0 }, function (req, res) { res.on('error', onError) @@ -610,7 +613,7 @@ describe('compression()', function () { assert.ok(res.write('', onError) === false) process.nextTick(function () { - assert.ok(onError.callCount > 0) + assert.ok(onErrorCalled) }) }) From bd4ff2b44b65255464e8b4342ee21dbd0b36bc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 22:34:07 -0300 Subject: [PATCH 19/29] remove deconstruct --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index bc105fc7..8d999eb3 100644 --- a/index.js +++ b/index.js @@ -22,7 +22,7 @@ var debug = require('debug')('compression') var onHeaders = require('on-headers') var vary = require('vary') var zlib = require('zlib') -var { ServerResponse } = require('http') +var ServerResponse = require('http').ServerResponse /** * Module exports. From 50aa251b1fc96513f71b9ce0e11d44029fa33fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 23:00:57 -0300 Subject: [PATCH 20/29] listen error event --- test/compression.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/compression.js b/test/compression.js index c8bfd12b..5433bd83 100644 --- a/test/compression.js +++ b/test/compression.js @@ -155,8 +155,9 @@ describe('compression()', function () { } var server = createServer({ threshold: 0 }, function (req, res) { + res.on('error', onError) res.setHeader('Content-Type', 'text/plain') - res.end() + res.end('hello, world') res.write('hello, world', onError) From 1ecf4da6f99880275ba7786165f41ba2a8737bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Fri, 5 Aug 2022 23:40:21 -0300 Subject: [PATCH 21/29] fix res.write proxy --- index.js | 13 +++++++------ test/compression.js | 13 +++++-------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index 8d999eb3..d709edf5 100644 --- a/index.js +++ b/index.js @@ -106,13 +106,14 @@ function compression (options) { // HACK: node doesn't expose internal errors, // we need to fake response to throw underlying errors type var fakeRes = new ServerResponse({}) - if (!res.destroyed) { - fakeRes.destroyed = fakeRes.finished = true - } else { - fakeRes.destroyed = true - } + fakeRes.on('error', function (err) { + res.emit('error', err) + }) + fakeRes.destroyed = res.destroyed + fakeRes.finished = res.finished || ended // throw ERR_STREAM_DESTROYED or ERR_STREAM_WRITE_AFTER_END - return _write.call(fakeRes, chunk, encoding, callback) + _write.call(fakeRes, chunk, encoding, callback) + return false } if (!this._header) { diff --git a/test/compression.js b/test/compression.js index 5433bd83..c93541bd 100644 --- a/test/compression.js +++ b/test/compression.js @@ -59,7 +59,6 @@ describe('compression()', function () { res.write(1) } catch (err) { assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') - res.statusCode = 500 res.flush() res.end() } @@ -68,7 +67,7 @@ describe('compression()', function () { request(server) .get('/') .set('Accept-Encoding', 'gzip') - .expect(500, done) + .expect(200, done) }) it('res.write({}) should fire ERR_INVALID_ARG_TYPE', function (done) { @@ -78,7 +77,6 @@ describe('compression()', function () { res.write({}) } catch (err) { assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') - res.statusCode = 500 res.flush() res.end() } @@ -87,17 +85,16 @@ describe('compression()', function () { request(server) .get('/') .set('Accept-Encoding', 'gzip') - .expect(500, done) + .expect(200, done) }) - it('res.write(null) should fire ERR_STREAM_NULL_VALUES', function (done) { + it('res.write(null) should fire ERR_INVALID_ARG_TYPE or ERR_STREAM_NULL_VALUES', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') try { res.write(null) } catch (err) { - assert.ok(err.code === 'ERR_STREAM_NULL_VALUES') - res.statusCode = 500 + assert.ok(err.code === 'ERR_INVALID_ARG_TYPE' || err.code === 'ERR_STREAM_NULL_VALUES') res.flush() res.end() } @@ -106,7 +103,7 @@ describe('compression()', function () { request(server) .get('/') .set('Accept-Encoding', 'gzip') - .expect(500, done) + .expect(200, done) }) }) From 088b23cd6e327a72f9c84e84e2cc7094e179a813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sat, 6 Aug 2022 00:48:18 -0300 Subject: [PATCH 22/29] emit stream error on res --- index.js | 4 ++++ test/compression.js | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index d709edf5..5172a983 100644 --- a/index.js +++ b/index.js @@ -254,6 +254,10 @@ function compression (options) { res.removeHeader('Content-Length') // compression + stream.on('error', function (err) { + res.emit('error', err) + }) + stream.on('data', function onStreamData (chunk) { if (_write.call(res, chunk) === false) { stream.pause() diff --git a/test/compression.js b/test/compression.js index c93541bd..f718e8aa 100644 --- a/test/compression.js +++ b/test/compression.js @@ -147,7 +147,7 @@ describe('compression()', function () { it('res.write() should call callback with error after end', function (done) { var onErrorCalled = false var onError = function (err) { - assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') + assert.ok(err.message === 'write after end' || err.code === 'ERR_STREAM_WRITE_AFTER_END') onErrorCalled = true } @@ -598,7 +598,7 @@ describe('compression()', function () { it('should return false writing after end', function (done) { var onErrorCalled = false var onError = function (err) { - assert.ok(err.code === 'ERR_STREAM_WRITE_AFTER_END') + assert.ok(err.message === 'write after end' || err.code === 'ERR_STREAM_WRITE_AFTER_END') onErrorCalled = true } From 3c6959709668325322c5957ad20e1eef8f3c4d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sat, 6 Aug 2022 11:51:07 -0300 Subject: [PATCH 23/29] fix node 0.8/0.10/0.12 issues --- index.js | 22 ++++++++++++++++++---- test/compression.js | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/index.js b/index.js index 5172a983..a0cf33e6 100644 --- a/index.js +++ b/index.js @@ -86,7 +86,7 @@ function compression (options) { if (chunk === null) { // throw ERR_STREAM_NULL_VALUES return _write.call(this, chunk, encoding, callback) - } else if (typeof chunk === 'string' || isUint8Array(chunk)) { + } else if (typeof chunk === 'string' || typeof chunk.fill === 'function' || isUint8Array(chunk)) { // noop } else { // throw ERR_INVALID_ARG_TYPE @@ -120,8 +120,15 @@ function compression (options) { this._implicitHeader() } + if (chunk) { + chunk = toBuffer(chunk, encoding) + if (/^v0\.8\./.test(process.version) && stream) { + encoding = callback + } + } + return stream - ? stream.write(toBuffer(chunk, encoding), encoding, callback) + ? stream.write(chunk, encoding, callback) : _write.call(this, chunk, encoding, callback) } @@ -162,10 +169,17 @@ function compression (options) { // mark ended ended = true + if (chunk) { + chunk = toBuffer(chunk, encoding) + if (/^v0\.8\./.test(process.version) && stream && chunk) { + encoding = callback + } + } + // write Buffer for Node.js 0.8 return chunk - ? stream.end(toBuffer(chunk, encoding), encoding, callback) - : stream.end(callback) + ? stream.end(chunk, encoding, callback) + : stream.end(chunk, callback) } res.on = function on (type, listener) { diff --git a/test/compression.js b/test/compression.js index f718e8aa..787b77ce 100644 --- a/test/compression.js +++ b/test/compression.js @@ -37,7 +37,8 @@ describe('compression()', function () { .expect(200, done) }) - it('res.write(Uint8Array)', function (done) { + var run = /^v0\.12\./.test(process.version) ? it : it.skip + run('res.write(Uint8Array)', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') res.end(new Uint8Array(1)) @@ -58,7 +59,7 @@ describe('compression()', function () { try { res.write(1) } catch (err) { - assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') + assert.ok(err.toString().indexOf('TypeError') > -1 || err.code === 'ERR_INVALID_ARG_TYPE') res.flush() res.end() } @@ -76,7 +77,7 @@ describe('compression()', function () { try { res.write({}) } catch (err) { - assert.ok(err.code === 'ERR_INVALID_ARG_TYPE') + assert.ok(err.toString().indexOf('TypeError') > -1 || err.code === 'ERR_INVALID_ARG_TYPE') res.flush() res.end() } @@ -94,7 +95,7 @@ describe('compression()', function () { try { res.write(null) } catch (err) { - assert.ok(err.code === 'ERR_INVALID_ARG_TYPE' || err.code === 'ERR_STREAM_NULL_VALUES') + assert.ok(err.toString().indexOf('TypeError') > -1 || err.code === 'ERR_INVALID_ARG_TYPE' || err.code === 'ERR_STREAM_NULL_VALUES') res.flush() res.end() } @@ -107,16 +108,20 @@ describe('compression()', function () { }) }) - it('res.write() should throw ERR_STREAM_ALREADY_FINISHED when stream is already finished', function (done) { + it('res.write() should return false or throw ERR_STREAM_ALREADY_FINISHED when stream is already finished', function (done) { + var onError = function (err) { + assert.ok(err.toString().indexOf('write after end') > -1 || err.code === 'ERR_STREAM_WRITE_AFTER_END') + } var server = createServer({ threshold: 0 }, function (req, res) { + res.on('error', onError) res.setHeader('Content-Type', 'text/plain') res.end('hello world') - server.on('close', function () { - res.end(function (err) { - assert.ok(err.code === 'ERR_STREAM_ALREADY_FINISHED') - }) + var canWrite = res.write('hola', function (err) { + assert.ok(err.toString().indexOf('write after end') > -1 || err.code === 'ERR_STREAM_ALREADY_FINISHED') }) + + assert.ok(!canWrite) }) request(server) @@ -124,10 +129,14 @@ describe('compression()', function () { .set('Accept-Encoding', 'gzip') .expect(shouldHaveHeader('Content-Encoding')) .expect(shouldHaveBodyLength('hello world'.length)) - .expect(200, done) + .expect(200, function (err) { + console.log(1) + done(err) + }) }) - it('res.write() should call callback if passsed', function (done) { + var run = /^v0\.12\./.test(process.version) ? it : it.skip + run('res.write() should call callback if passsed', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain') @@ -144,10 +153,11 @@ describe('compression()', function () { .expect(200, done) }) - it('res.write() should call callback with error after end', function (done) { + var run = /^v0\.12\./.test(process.version) ? it : it.skip + run('res.write() should call callback with error after end', function (done) { var onErrorCalled = false var onError = function (err) { - assert.ok(err.message === 'write after end' || err.code === 'ERR_STREAM_WRITE_AFTER_END') + assert.ok(err.toString().indexOf('write after end') > -1 || err.code === 'ERR_STREAM_WRITE_AFTER_END') onErrorCalled = true } @@ -598,7 +608,7 @@ describe('compression()', function () { it('should return false writing after end', function (done) { var onErrorCalled = false var onError = function (err) { - assert.ok(err.message === 'write after end' || err.code === 'ERR_STREAM_WRITE_AFTER_END') + assert.ok(err.toString().indexOf('write after end') > -1 || err.code === 'ERR_STREAM_WRITE_AFTER_END') onErrorCalled = true } @@ -611,6 +621,8 @@ describe('compression()', function () { assert.ok(res.write('', onError) === false) process.nextTick(function () { + var run = /^v0\.12\./.test(process.version) + if (!run) return assert.ok(onErrorCalled) }) }) From 5ed9a90572d5430d8a583679c7f80ad2264285e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sat, 6 Aug 2022 11:53:21 -0300 Subject: [PATCH 24/29] fix lint error --- test/compression.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/compression.js b/test/compression.js index 787b77ce..072169e6 100644 --- a/test/compression.js +++ b/test/compression.js @@ -153,7 +153,7 @@ describe('compression()', function () { .expect(200, done) }) - var run = /^v0\.12\./.test(process.version) ? it : it.skip + run = /^v0\.12\./.test(process.version) ? it : it.skip run('res.write() should call callback with error after end', function (done) { var onErrorCalled = false var onError = function (err) { From 8d9fb6c163f149a723d11380b14d291ee0844605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sat, 6 Aug 2022 12:10:41 -0300 Subject: [PATCH 25/29] remove console.log --- test/compression.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/compression.js b/test/compression.js index 072169e6..db783d11 100644 --- a/test/compression.js +++ b/test/compression.js @@ -129,10 +129,7 @@ describe('compression()', function () { .set('Accept-Encoding', 'gzip') .expect(shouldHaveHeader('Content-Encoding')) .expect(shouldHaveBodyLength('hello world'.length)) - .expect(200, function (err) { - console.log(1) - done(err) - }) + .expect(200, done) }) var run = /^v0\.12\./.test(process.version) ? it : it.skip From 17e693372261c03e2ef2d9d1b064d411c1aa4d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Tue, 16 Aug 2022 09:48:30 -0300 Subject: [PATCH 26/29] fix(test): add code coverage --- index.js | 2 +- test/compression.js | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index a0cf33e6..54cd3be7 100644 --- a/index.js +++ b/index.js @@ -171,7 +171,7 @@ function compression (options) { if (chunk) { chunk = toBuffer(chunk, encoding) - if (/^v0\.8\./.test(process.version) && stream && chunk) { + if (/^v0\.8\./.test(process.version) && stream) { encoding = callback } } diff --git a/test/compression.js b/test/compression.js index db783d11..a43ed668 100644 --- a/test/compression.js +++ b/test/compression.js @@ -37,6 +37,47 @@ describe('compression()', function () { .expect(200, done) }) + it('res.end(cb)', function (done) { + var callbackCalled = false + + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.write(Buffer.from('hello world')) + res.end(function () { + callbackCalled = true + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, function () { + assert.ok(callbackCalled) + done() + }) + }) + + it('res.end(string, cb)', function (done) { + var callbackCalled = false + + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.end(Buffer.from('hello world'), function () { + callbackCalled = true + }) + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, function () { + assert.ok(callbackCalled) + done() + }) + }) + var run = /^v0\.12\./.test(process.version) ? it : it.skip run('res.write(Uint8Array)', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { From 68ee9805c9b1f05faed37e729336d01800f4d035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Tue, 11 Apr 2023 07:03:30 -0300 Subject: [PATCH 27/29] fix: ask for runtime version once --- index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 54cd3be7..65ab6ae6 100644 --- a/index.js +++ b/index.js @@ -24,6 +24,8 @@ var vary = require('vary') var zlib = require('zlib') var ServerResponse = require('http').ServerResponse +var isOldRuntime = /^v0\.8\./.test(process.version) + /** * Module exports. */ @@ -122,7 +124,7 @@ function compression (options) { if (chunk) { chunk = toBuffer(chunk, encoding) - if (/^v0\.8\./.test(process.version) && stream) { + if (isOldRuntime && stream) { encoding = callback } } @@ -171,7 +173,7 @@ function compression (options) { if (chunk) { chunk = toBuffer(chunk, encoding) - if (/^v0\.8\./.test(process.version) && stream) { + if (isOldRuntime && stream) { encoding = callback } } From 696e58f47b7fd6c21ec01a207b792e016603f6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 3 Mar 2024 14:00:21 -0300 Subject: [PATCH 28/29] chore(ci):added new node versions --- .github/workflows/ci.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ce4a443..4d36fc45 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,10 @@ jobs: - Node.js 15.x - Node.js 16.x - Node.js 17.x + - Node.js 18.x + - Node.js 19.x + - Node.js 20.x + include: - name: Node.js 0.8 @@ -107,6 +111,14 @@ jobs: - name: Node.js 17.x node-version: "17.9" + - name: Node.js 18.x + node-version: "18.19.1" + + - name: Node.js 19.x + node-version: "19.9.0" + + - name: Node.js 20.x + node-version: "20.11" steps: - uses: actions/checkout@v2 @@ -123,7 +135,12 @@ jobs: dirname "$(nvm which ${{ matrix.node-version }})" >> "$GITHUB_PATH" - name: Configure npm - run: npm config set shrinkwrap false + run: | + if [[ "$(cut -d. -f1 <<< "${{ matrix.node-version }}")" -le 17 ]]; then + npm config set shrinkwrap false + else + npm config set package-lock false + fi - name: Remove npm module(s) ${{ matrix.npm-rm }} run: npm rm --silent --save-dev ${{ matrix.npm-rm }} From 3a98b98a7d0ff58fd5119e6c82ddb56dd47212cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Lo=CC=81pez=20Guevara?= Date: Sun, 3 Mar 2024 17:12:33 -0300 Subject: [PATCH 29/29] chore(ci): bring back node 8/9 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d36fc45..4b0c86f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,11 +79,11 @@ jobs: - name: Node.js 8.x node-version: "8.16" - npm-i: mocha@7.2.0 + npm-i: mocha@7.2.0 nyc@14.1.1 supertest@6.1.6 - name: Node.js 9.x node-version: "9.11" - npm-i: mocha@7.2.0 + npm-i: mocha@7.2.0 nyc@14.1.1 supertest@6.1.6 - name: Node.js 10.x node-version: "10.16"