Skip to content

Commit

Permalink
Add support for Brotli encoding (#15)
Browse files Browse the repository at this point in the history
Fixes #12
  • Loading branch information
kevva authored and sindresorhus committed Jan 20, 2019
1 parent c58975a commit 9748dd9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
14 changes: 10 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ const mimicResponse = require('mimic-response');

module.exports = response => {
// TODO: Use Array#includes when targeting Node.js 6
if (['gzip', 'deflate'].indexOf(response.headers['content-encoding']) === -1) {
if (['gzip', 'deflate', 'br'].indexOf(response.headers['content-encoding']) === -1) {
return response;
}

const unzip = zlib.createUnzip();
const isBrotli = response.headers['content-encoding'] === 'br';

if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') {
return response;
}

const decompress = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
const stream = new PassThrough();

mimicResponse(response, stream);

unzip.on('error', err => {
decompress.on('error', err => {
// Ignore empty response
if (err.code === 'Z_BUF_ERROR') {
stream.end();
Expand All @@ -24,7 +30,7 @@ module.exports = response => {
stream.emit('error', err);
});

response.pipe(unzip).pipe(stream);
response.pipe(decompress).pipe(stream);

return stream;
};
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> Decompress a HTTP response if needed
Decompresses the [response](https://nodejs.org/api/http.html#http_class_http_incomingmessage) from [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) if it's gzipped or deflated, otherwise just passes it through.
Decompresses the [response](https://nodejs.org/api/http.html#http_class_http_incomingmessage) from [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) if it's gzipped, deflated or compressed with Brotli, otherwise just passes it through.

Used by [`got`](https://github.com/sindresorhus/got).

Expand Down
20 changes: 20 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ test.before('setup', async () => {
res.end(await zlibP.deflate(fixture));
});

s.on('/brotli', async (req, res) => {
res.statusCode = 200;
res.setHeader('content-type', 'text/plain');
res.setHeader('content-encoding', 'br');
res.end(await zlibP.brotliCompress(fixture));
});

s.on('/missing-data', async (req, res) => {
res.statusCode = 200;
res.setHeader('content-encoding-type', 'text/plain');
Expand Down Expand Up @@ -75,6 +82,19 @@ test('decompress deflated content', async t => {
t.is(await getStream(res), fixture);
});

if (typeof zlib.brotliCompress === 'function') {
test('decompress brotli content', async t => {
const res = m(await httpGetP(`${s.url}/brotli`));

t.is(typeof res.httpVersion, 'string');
t.truthy(res.headers);

res.setEncoding('utf8');

t.is(await getStream(res), fixture);
});
}

test('ignore missing data', async t => {
const res = m(await httpGetP(`${s.url}/missing-data`));

Expand Down

0 comments on commit 9748dd9

Please sign in to comment.