Skip to content

Commit

Permalink
Skip compression when response has Cache-Control: no-transform
Browse files Browse the repository at this point in the history
closes #51
closes #53
  • Loading branch information
glenjamin authored and dougwilson committed Sep 30, 2015
1 parent 0bac653 commit dc81373
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
unreleased
==========

* Skip compression when response has `Cache-Control: no-transform`
* deps: accepts@~1.3.0
- deps: mime-types@~2.1.7
- deps: [email protected]
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Returns the compression middleware using the given `options`. The middleware
will attempt to compress response bodies for all request that traverse through
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.

#### Options

`compression()` accepts these properties in the options object. In addition to
Expand Down
27 changes: 27 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ var zlib = require('zlib')
module.exports = compression
module.exports.filter = shouldCompress

/**
* Module variables.
* @private
*/

var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/

/**
* Compress response data with gzip / deflate.
*
Expand Down Expand Up @@ -135,6 +142,12 @@ function compression(options) {
return
}

// determine if the entity should be transformed
if (!shouldTransform(req, res)) {
nocompress('no transform')
return
}

// vary
vary(res, 'Accept-Encoding')

Expand Down Expand Up @@ -246,3 +259,17 @@ function shouldCompress(req, res) {

return true
}

/**
* Determine if the entity should be transformed.
* @private
*/

function shouldTransform(req, res) {
var cacheControl = res.getHeader('Cache-Control')

// Don't compress for Cache-Control: no-transform
// https://tools.ietf.org/html/rfc7234#section-5.2.2.4
return !cacheControl
|| !cacheControlNoTransformRegExp.test(cacheControl)
}
32 changes: 32 additions & 0 deletions test/compression.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,38 @@ describe('compression()', function(){
})
})

describe('when "Cache-Control: no-transform" response header', function () {
it('should not compress response', function (done) {
var server = createServer({ threshold: 0 }, function (req, res) {
res.setHeader('Cache-Control', 'no-transform')
res.setHeader('Content-Type', 'text/plain')
res.end('hello, world')
})

request(server)
.get('/')
.set('Accept-Encoding', 'gzip')
.expect('Cache-Control', 'no-transform')
.expect(shouldNotHaveHeader('Content-Encoding'))
.expect(200, 'hello, world', done)
})

it('should not set Vary headerh', function (done) {
var server = createServer({ threshold: 0 }, function (req, res) {
res.setHeader('Cache-Control', 'no-transform')
res.setHeader('Content-Type', 'text/plain')
res.end('hello, world')
})

request(server)
.get('/')
.set('Accept-Encoding', 'gzip')
.expect('Cache-Control', 'no-transform')
.expect(shouldNotHaveHeader('Vary'))
.expect(200, done)
})
})

describe('.filter', function () {
it('should be a function', function () {
assert.equal(typeof compression.filter, 'function')
Expand Down

0 comments on commit dc81373

Please sign in to comment.