Skip to content

Commit d33f32f

Browse files
authored
fix brotli responses being double-compressed (#167)
* fix brotli responses being double-compressed * fix test failure
1 parent 1430057 commit d33f32f

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

index.js

+5
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ function buildRouteCompress (fastify, params, routeOptions, decorateOnly) {
223223
if (payload == null) {
224224
return next()
225225
}
226+
const responseEncoding = reply.getHeader('Content-Encoding')
227+
if (responseEncoding && responseEncoding !== 'identity') {
228+
// response is already compressed
229+
return next()
230+
}
226231
setVaryHeader(reply)
227232

228233
let stream, encoding

test/test-global-compress.js

+46-8
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,21 @@ test('should support quality syntax', t => {
195195
})
196196
})
197197

198-
test('onSend hook should not double-compress Stream if already zipped', t => {
199-
t.plan(3)
198+
test('onSend hook should not double-compress Stream if already gzipped', t => {
199+
t.plan(4)
200200
const fastify = Fastify()
201-
fastify.register(compressPlugin, { global: true })
201+
fastify.register(compressPlugin, {
202+
global: true,
203+
threshold: 0
204+
})
202205

206+
const file = readFileSync('./package.json', 'utf8')
203207
fastify.get('/', (req, reply) => {
204-
reply.type('text/plain').compress(
205-
createReadStream('./package.json')
206-
.pipe(zlib.createGzip())
207-
)
208+
const payload = zlib.gzipSync(file)
209+
reply.type('application/json')
210+
.header('content-encoding', 'gzip')
211+
.header('content-length', payload.length)
212+
.send(payload)
208213
})
209214

210215
fastify.inject({
@@ -216,12 +221,44 @@ test('onSend hook should not double-compress Stream if already zipped', t => {
216221
}, (err, res) => {
217222
t.error(err)
218223
t.equal(res.headers['content-encoding'], 'gzip')
219-
const file = readFileSync('./package.json', 'utf8')
224+
t.equal(res.headers['content-length'], res.rawPayload.length)
220225
const payload = zlib.gunzipSync(res.rawPayload)
221226
t.equal(payload.toString('utf-8'), file)
222227
})
223228
})
224229

230+
test('onSend hook should not double-compress Stream if already brotli compressed', t => {
231+
t.plan(4)
232+
const fastify = Fastify()
233+
fastify.register(compressPlugin, {
234+
global: true,
235+
threshold: 0
236+
})
237+
238+
const file = readFileSync('./package.json', 'utf8')
239+
fastify.get('/', (req, reply) => {
240+
const payload = zlib.brotliCompressSync(file)
241+
reply.type('application/json')
242+
.header('content-encoding', 'br')
243+
.header('content-length', payload.length)
244+
.send(payload)
245+
})
246+
247+
fastify.inject({
248+
url: '/',
249+
method: 'GET',
250+
headers: {
251+
'accept-encoding': 'br,gzip,deflate'
252+
}
253+
}, (err, res) => {
254+
t.error(err)
255+
t.equal(res.headers['content-encoding'], 'br')
256+
t.equal(res.headers['content-length'], res.rawPayload.length)
257+
const payload = zlib.brotliDecompressSync(res.rawPayload)
258+
t.equal(payload.toString('utf-8'), file)
259+
})
260+
})
261+
225262
test('should send a gzipped data for * header', t => {
226263
t.plan(3)
227264
const fastify = Fastify()
@@ -1732,6 +1769,7 @@ test('stream onEnd handler should log an error if exists', t => {
17321769
const logger = new Writable({
17331770
write (chunk, encoding, callback) {
17341771
actual = JSON.parse(chunk.toString())
1772+
callback()
17351773
}
17361774
})
17371775

0 commit comments

Comments
 (0)