Skip to content

Commit dc81373

Browse files
glenjamindougwilson
authored andcommitted
Skip compression when response has Cache-Control: no-transform
closes #51 closes #53
1 parent 0bac653 commit dc81373

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

HISTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
unreleased
22
==========
33

4+
* Skip compression when response has `Cache-Control: no-transform`
45
* deps: accepts@~1.3.0
56
- deps: mime-types@~2.1.7
67

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ Returns the compression middleware using the given `options`. The middleware
3131
will attempt to compress response bodies for all request that traverse through
3232
the middleware, based on the given `options`.
3333

34+
This middleware will never compress responses that include a `Cache-Control`
35+
header with the [`no-transform` directive](https://tools.ietf.org/html/rfc7234#section-5.2.2.4),
36+
as compressing will transform the body.
37+
3438
#### Options
3539

3640
`compression()` accepts these properties in the options object. In addition to

index.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ var zlib = require('zlib')
2929
module.exports = compression
3030
module.exports.filter = shouldCompress
3131

32+
/**
33+
* Module variables.
34+
* @private
35+
*/
36+
37+
var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/
38+
3239
/**
3340
* Compress response data with gzip / deflate.
3441
*
@@ -135,6 +142,12 @@ function compression(options) {
135142
return
136143
}
137144

145+
// determine if the entity should be transformed
146+
if (!shouldTransform(req, res)) {
147+
nocompress('no transform')
148+
return
149+
}
150+
138151
// vary
139152
vary(res, 'Accept-Encoding')
140153

@@ -246,3 +259,17 @@ function shouldCompress(req, res) {
246259

247260
return true
248261
}
262+
263+
/**
264+
* Determine if the entity should be transformed.
265+
* @private
266+
*/
267+
268+
function shouldTransform(req, res) {
269+
var cacheControl = res.getHeader('Cache-Control')
270+
271+
// Don't compress for Cache-Control: no-transform
272+
// https://tools.ietf.org/html/rfc7234#section-5.2.2.4
273+
return !cacheControl
274+
|| !cacheControlNoTransformRegExp.test(cacheControl)
275+
}

test/compression.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,38 @@ describe('compression()', function(){
492492
})
493493
})
494494

495+
describe('when "Cache-Control: no-transform" response header', function () {
496+
it('should not compress response', function (done) {
497+
var server = createServer({ threshold: 0 }, function (req, res) {
498+
res.setHeader('Cache-Control', 'no-transform')
499+
res.setHeader('Content-Type', 'text/plain')
500+
res.end('hello, world')
501+
})
502+
503+
request(server)
504+
.get('/')
505+
.set('Accept-Encoding', 'gzip')
506+
.expect('Cache-Control', 'no-transform')
507+
.expect(shouldNotHaveHeader('Content-Encoding'))
508+
.expect(200, 'hello, world', done)
509+
})
510+
511+
it('should not set Vary headerh', function (done) {
512+
var server = createServer({ threshold: 0 }, function (req, res) {
513+
res.setHeader('Cache-Control', 'no-transform')
514+
res.setHeader('Content-Type', 'text/plain')
515+
res.end('hello, world')
516+
})
517+
518+
request(server)
519+
.get('/')
520+
.set('Accept-Encoding', 'gzip')
521+
.expect('Cache-Control', 'no-transform')
522+
.expect(shouldNotHaveHeader('Vary'))
523+
.expect(200, done)
524+
})
525+
})
526+
495527
describe('.filter', function () {
496528
it('should be a function', function () {
497529
assert.equal(typeof compression.filter, 'function')

0 commit comments

Comments
 (0)