Skip to content

Commit

Permalink
Support compression based on accept-encoding header
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewBarba committed Mar 16, 2021
1 parent f0dd13b commit 209deee
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export declare interface Options {
version?: string;
errorHeaderWhitelist?: string[];
isBase64?: boolean;
compression?: boolean;
headers?: object;
}

Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class API {
this._errorHeaderWhitelist = props && Array.isArray(props.errorHeaderWhitelist) ? props.errorHeaderWhitelist.map(header => header.toLowerCase()) : []
this._isBase64 = props && typeof props.isBase64 === 'boolean' ? props.isBase64 : false
this._headers = props && props.headers && typeof props.headers === 'object' ? props.headers : {}
this._compression = props && typeof props.compression === 'boolean' ? props.compression : false

// Set sampling info
this._sampleCounts = {}
Expand Down
43 changes: 43 additions & 0 deletions lib/compression.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict'

/**
* Lightweight web framework for your serverless applications
* @author Jeremy Daly <jeremy@jeremydaly.com>
* @license MIT
*/

const zlib = require('zlib')

exports.compress = (input,headers) => {
const acceptEncodingHeader = headers['accept-encoding'] || ''
const acceptableEncodings = new Set(acceptEncodingHeader.split(',').map(str => str.trim()))

// Handle Brotli compression
if (acceptableEncodings.has('br')) {
return {
data: zlib.brotliCompressSync(input),
contentEncoding: 'br'
}
}

// Handle Gzip compression
if (acceptableEncodings.has('gzip')) {
return {
data: zlib.gzipSync(input),
contentEncoding: 'gzip'
}
}

// Handle deflate compression
if (acceptableEncodings.has('deflate')) {
return {
data: zlib.deflateSync(input),
contentEncoding: 'deflate'
}
}

return {
data: input,
contentEncoding: null
}
}
14 changes: 14 additions & 0 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const UTILS = require('./utils.js')

const fs = require('fs') // Require Node.js file system
const path = require('path') // Require Node.js path
const compression = require('./compression') // Require compression lib
const { ResponseError, FileError } = require('./errors') // Require custom errors

// Require AWS S3 service
Expand Down Expand Up @@ -47,6 +48,9 @@ class RESPONSE {
// base64 encoding flag
this._isBase64 = app._isBase64

// compression flag
this._compression = app._compression

// Default callback function
this._callback = 'callback'

Expand Down Expand Up @@ -465,6 +469,16 @@ class RESPONSE {
this._request.interface === 'alb' ? { statusDescription: `${this._statusCode} ${UTILS.statusLookup(this._statusCode)}` } : {}
)

// Compress the body
if (this._compression && this._response.body) {
const { data, contentEncoding } = compression.compress(this._response.body, this._request.headers)
if (contentEncoding) {
this._isBase64 = true
this._response.body = data.toString('base64')
this._response.headers['content-encoding'] = [contentEncoding]
}
}

// Trigger the callback function
this.app._callback(null, this._response, this)

Expand Down

0 comments on commit 209deee

Please sign in to comment.