Skip to content

Commit eed8fb8

Browse files
authored
Merge pull request #32 from tobinbradley/compress-types-option
make compressibleTypes user settable so custom types can be compressed
2 parents 4b5c744 + 34ec3ed commit eed8fb8

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ fastify.register(
6666
{ threshold: 2048 }
6767
)
6868
```
69+
### customTypes
70+
[mime-db](https://github.com/jshttp/mime-db) is used to determine if a `Content-Type` should be compressed. You can compress additional content types via regular expression.
71+
```javascript
72+
fastify.register(
73+
require('fastify-compress'),
74+
{ customTypes: /x-protobuf$/ }
75+
)
76+
```
6977
### Brotli
7078
Brotli compression is not enabled by default, if you need it we recommend to install [`iltorb`](https://www.npmjs.com/package/iltorb) and pass it as option.
7179
```javascript

index.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const zlib = require('zlib')
55
const pump = require('pump')
66
const sts = require('string-to-stream')
77
const mimedb = require('mime-db')
8-
const compressibleTypes = /^text\/|\+json$|\+text$|\+xml$/
98

109
function compressPlugin (fastify, opts, next) {
1110
fastify.decorateReply('compress', compress)
@@ -15,6 +14,7 @@ function compressPlugin (fastify, opts, next) {
1514
}
1615

1716
const threshold = typeof opts.threshold === 'number' ? opts.threshold : 1024
17+
const compressibleTypes = opts.customTypes instanceof RegExp ? opts.customTypes : /^text\/|\+json$|\+text$|\+xml$/
1818
const compressStream = {
1919
gzip: zlib.createGzip,
2020
deflate: zlib.createDeflate
@@ -40,7 +40,7 @@ function compressPlugin (fastify, opts, next) {
4040
}
4141

4242
var type = this.getHeader('Content-Type') || 'application/json'
43-
if (shouldCompress(type) === false) {
43+
if (shouldCompress(type, compressibleTypes) === false) {
4444
return this.send(payload)
4545
}
4646

@@ -86,7 +86,7 @@ function compressPlugin (fastify, opts, next) {
8686
}
8787

8888
var type = reply.getHeader('Content-Type') || 'application/json'
89-
if (shouldCompress(type) === false) {
89+
if (shouldCompress(type, compressibleTypes) === false) {
9090
return next()
9191
}
9292

@@ -150,7 +150,7 @@ function getEncodingHeader (supportedEncodings, request) {
150150
return null
151151
}
152152

153-
function shouldCompress (type) {
153+
function shouldCompress (type, compressibleTypes) {
154154
if (compressibleTypes.test(type)) return true
155155
var data = mimedb[type.split(';', 1)[0].trim().toLowerCase()]
156156
if (data === undefined) return false

test.js

+68
Original file line numberDiff line numberDiff line change
@@ -801,3 +801,71 @@ test('onSend hook should remove content-length', t => {
801801
t.strictEqual(payload.toString('utf-8'), file)
802802
})
803803
})
804+
805+
test('Should compress if customTypes is set and matches content type', t => {
806+
t.plan(3)
807+
const fastify = Fastify()
808+
fastify.register(compressPlugin, { customTypes: /x-user-header$/ })
809+
810+
fastify.get('/', (req, reply) => {
811+
reply.type('application/x-user-header').send(createReadStream('./package.json'))
812+
})
813+
814+
fastify.inject({
815+
url: '/',
816+
method: 'GET',
817+
headers: {
818+
'accept-encoding': 'gzip'
819+
}
820+
}, (err, res) => {
821+
t.error(err)
822+
t.strictEqual(res.headers['content-encoding'], 'gzip')
823+
const file = readFileSync('./package.json', 'utf8')
824+
const payload = zlib.gunzipSync(res.rawPayload)
825+
t.strictEqual(payload.toString('utf-8'), file)
826+
})
827+
})
828+
829+
test('Should not compress if customTypes is set and does not match content type or mime-db', t => {
830+
t.plan(3)
831+
const fastify = Fastify()
832+
fastify.register(compressPlugin, { customTypes: /x-user-header$/ })
833+
834+
fastify.get('/', (req, reply) => {
835+
reply.type('application/x-other-type').send(createReadStream('./package.json'))
836+
})
837+
838+
fastify.inject({
839+
url: '/',
840+
method: 'GET',
841+
headers: {
842+
'accept-encoding': 'gzip'
843+
}
844+
}, (err, res) => {
845+
t.error(err)
846+
t.notOk(res.headers['content-encoding'])
847+
t.strictEqual(res.statusCode, 200)
848+
})
849+
})
850+
851+
test('Should not apply customTypes if value passed is not RegExp', t => {
852+
t.plan(3)
853+
const fastify = Fastify()
854+
fastify.register(compressPlugin, { customTypes: 'x-user-header' })
855+
856+
fastify.get('/', (req, reply) => {
857+
reply.type('application/x-user-header').send(createReadStream('./package.json'))
858+
})
859+
860+
fastify.inject({
861+
url: '/',
862+
method: 'GET',
863+
headers: {
864+
'accept-encoding': 'gzip'
865+
}
866+
}, (err, res) => {
867+
t.error(err)
868+
t.notOk(res.headers['content-encoding'])
869+
t.strictEqual(res.statusCode, 200)
870+
})
871+
})

0 commit comments

Comments
 (0)