Skip to content

Commit fc93110

Browse files
authored
Merge pull request #190 from AndrewBarba/main
Compression - Disable Brotli by Default
2 parents d762d86 + 4e13c52 commit fc93110

File tree

5 files changed

+30
-7
lines changed

5 files changed

+30
-7
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -1411,7 +1411,15 @@ const api = require('lambda-api')({
14111411
});
14121412
```
14131413

1414-
The response will automatically be compressed based on the `Accept-Encoding` header in the request. Supported compressions are Brotli, Gzip and Deflate - in that priority order.
1414+
The response will automatically be compressed based on the `Accept-Encoding` header in the request. Supported compressions are Gzip and Deflate, with opt-in support for Brotli:
1415+
1416+
```javascript
1417+
const api = require('lambda-api')({
1418+
compression: ['br', 'gzip'],
1419+
});
1420+
```
1421+
1422+
> Note: Brotli compression is significantly slower than Gzip due to its CPU intensive algorithm. Please test extensively before enabling on a production environment.
14151423
14161424
For full control over the response compression, instantiate the API with `isBase64` set to true, and a custom serializer that returns a compressed response as a base64 encoded string. Also, don't forget to set the correct `content-encoding` header:
14171425

__tests__/responses.unit.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const api4 = require('../index')({
2929
// Init API with compression
3030
const api5 = require('../index')({
3131
version: 'v1.0',
32-
compression: true
32+
compression: ['br', 'gzip', 'deflate']
3333
})
3434

3535
let event = {
@@ -312,6 +312,14 @@ describe('Response Tests:', function() {
312312
expect(result).toEqual({ multiValueHeaders: { 'content-encoding': ['deflate'], 'content-type': ['application/json'] }, statusCode: 200, body, isBase64Encoded: true })
313313
}) // end it
314314

315+
it('Compression (Unknown)', async function() {
316+
let _event = Object.assign({},event,{ path: '/testCompression'})
317+
_event.multiValueHeaders['Accept-Encoding'] = ['xxx']
318+
let result = await new Promise(r => api5.run(_event,{},(e,res) => { r(res) }))
319+
let body = `{"object":true}`
320+
expect(result).toEqual({ multiValueHeaders: { 'content-type': ['application/json'] }, statusCode: 200, body, isBase64Encoded: false })
321+
}) // end it
322+
315323
afterEach(function() {
316324
stub.restore()
317325
})

index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ class API {
4545
? props.headers
4646
: {};
4747
this._compression =
48-
props && typeof props.compression === 'boolean'
48+
props &&
49+
(typeof props.compression === 'boolean' ||
50+
Array.isArray(props.compression))
4951
? props.compression
5052
: false;
5153

lib/compression.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88

99
const zlib = require('zlib');
1010

11-
exports.compress = (input, headers) => {
11+
const defaultEnabledEcodings = ['gzip', 'deflate'];
12+
13+
exports.compress = (input, headers, _enabledEncodings) => {
14+
const enabledEncodings = new Set(_enabledEncodings || defaultEnabledEcodings);
1215
const acceptEncodingHeader = headers['accept-encoding'] || '';
1316
const acceptableEncodings = new Set(
1417
acceptEncodingHeader
@@ -20,6 +23,7 @@ exports.compress = (input, headers) => {
2023
// Handle Brotli compression (Only supported in Node v10 and later)
2124
if (
2225
acceptableEncodings.has('br') &&
26+
enabledEncodings.has('br') &&
2327
typeof zlib.brotliCompressSync === 'function'
2428
) {
2529
return {
@@ -29,15 +33,15 @@ exports.compress = (input, headers) => {
2933
}
3034

3135
// Handle Gzip compression
32-
if (acceptableEncodings.has('gzip')) {
36+
if (acceptableEncodings.has('gzip') && enabledEncodings.has('gzip')) {
3337
return {
3438
data: zlib.gzipSync(input),
3539
contentEncoding: 'gzip',
3640
};
3741
}
3842

3943
// Handle deflate compression
40-
if (acceptableEncodings.has('deflate')) {
44+
if (acceptableEncodings.has('deflate') && enabledEncodings.has('deflate')) {
4145
return {
4246
data: zlib.deflateSync(input),
4347
contentEncoding: 'deflate',

lib/response.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,8 @@ class RESPONSE {
566566
if (this._compression && this._response.body) {
567567
const { data, contentEncoding } = compression.compress(
568568
this._response.body,
569-
this._request.headers
569+
this._request.headers,
570+
Array.isArray(this._compression) ? this._compression : null
570571
);
571572
if (contentEncoding) {
572573
Object.assign(this._response, {

0 commit comments

Comments
 (0)