diff --git a/HISTORY.md b/HISTORY.md index 0678bf2a..5b90a7bc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,8 @@ +unreleased +========== + + * Skip compression for `206 Partial Content` responses + 1.8.1 / 2025-07-17 ========== diff --git a/README.md b/README.md index 98c5f38c..39610a29 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ the middleware, based on the given `options`. This middleware will never compress responses that include a `Cache-Control` header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4), -as compressing will transform the body. +as compressing will transform the body. It will also never compress +[`206 Partial Content`](https://www.rfc-editor.org/rfc/rfc9110#section-15.3.7) +responses, as the `Content-Range` header describes the uncompressed body. #### Options diff --git a/index.js b/index.js index c0638e08..05d66328 100644 --- a/index.js +++ b/index.js @@ -171,6 +171,12 @@ function compression (options) { return } + // response is partial content + if (res.statusCode === 206) { + nocompress('partial content') + return + } + // vary vary(res, 'Accept-Encoding') diff --git a/test/compression.js b/test/compression.js index 8107def0..6a39df99 100644 --- a/test/compression.js +++ b/test/compression.js @@ -67,6 +67,43 @@ describe('compression()', function () { .expect(200, 'hello, world', done) }) + it('should skip partial content responses', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.statusCode = 206 + res.setHeader('Content-Type', 'text/plain') + res.setHeader('Content-Range', 'bytes 0-4/12') + res.setHeader('Content-Length', '5') + res.end('hello') + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldNotHaveHeader('Content-Encoding')) + .expect(shouldNotHaveHeader('Vary')) + .expect('Content-Range', 'bytes 0-4/12') + .expect('Content-Length', '5') + .expect(206, 'hello', done) + }) + + it('should skip partial content responses set via writeHead', function (done) { + var server = createServer({ threshold: 0 }, function (req, res) { + res.writeHead(206, { + 'Content-Type': 'text/plain', + 'Content-Range': 'bytes 0-4/12', + 'Content-Length': '5' + }) + res.end('hello') + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldNotHaveHeader('Content-Encoding')) + .expect('Content-Range', 'bytes 0-4/12') + .expect(206, 'hello', done) + }) + it('should set Vary', function (done) { var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain')