From 9d98c8b0461c88cd99de63d5185d3d3d6778ba40 Mon Sep 17 00:00:00 2001 From: Glen Mailer Date: Tue, 8 Sep 2015 22:22:36 +0100 Subject: [PATCH] Don't encode responses with Cache-Control: no-transform --- index.js | 17 +++++++++++++++++ test/compression.js | 46 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/index.js b/index.js index 8848294d..44ceaeb3 100644 --- a/index.js +++ b/index.js @@ -29,6 +29,11 @@ var zlib = require('zlib') module.exports = compression module.exports.filter = shouldCompress +/** + * Regex to match no-transform directive in a cache-control header + */ +var NO_TRANSFORM_REGEX = /(?:^|,)\s*?no-transform\s*?(?:,|$)/ + /** * Compress response data with gzip / deflate. * @@ -135,6 +140,18 @@ function compression(options) { return } + // Don't compress for Cache-Control: no-transform + // https://tools.ietf.org/html/rfc7234#section-5.2.1.6 + var cacheControl = res.getHeader('Cache-Control') + if (cacheControl) { + var noTransform = NO_TRANSFORM_REGEX.test(cacheControl) + if (noTransform) { + nocompress('no-transform') + return + } + } + + // vary vary(res, 'Accept-Encoding') diff --git a/test/compression.js b/test/compression.js index 1efd4334..365c6b1c 100644 --- a/test/compression.js +++ b/test/compression.js @@ -20,6 +20,52 @@ describe('compression()', function(){ .expect(200, done) }) + describe("Cache-Control", function() { + + [ + 'no-transform', + 'public, no-transform', + 'no-transform, private', + 'no-transform , max-age=1000', + 'max-age=1000 , no-transform' + ].forEach(function(headerValue) { + it('should skip Cache-Control: ' + headerValue, function(done){ + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.setHeader('Cache-Control', headerValue) + res.end('hello, world') + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect(shouldNotHaveHeader('Content-Encoding')) + .expect(200, done) + }) + }); + + [ + 'not-no-transform', + 'public', + 'no-transform-thingy' + ].forEach(function(headerValue) { + it('should not skip Cache-Control: ' + headerValue, function(done){ + var server = createServer({ threshold: 0 }, function (req, res) { + res.setHeader('Content-Type', 'text/plain') + res.setHeader('Cache-Control', headerValue) + res.end('hello, world') + }) + + request(server) + .get('/') + .set('Accept-Encoding', 'gzip') + .expect('Content-Encoding', 'gzip') + .expect(200, done) + }) + }); + + }) + it('should skip unknown accept-encoding', function(done){ var server = createServer({ threshold: 0 }, function (req, res) { res.setHeader('Content-Type', 'text/plain')