Skip to content

Commit 6d4ede8

Browse files
committed
WIP Brotli support
may be related to #243
1 parent 2f76f10 commit 6d4ede8

1 file changed

Lines changed: 28 additions & 13 deletions

File tree

lib/decompress.js

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,26 @@ var zlib = require("zlib");
55
var contentTypes = require("./content-types.js");
66
var debug = require("debug")("unblocker:decompress");
77

8+
const SUPPORTED_ENCODINGS = [
9+
'deflate',
10+
'gzip',
11+
'br' // brotli
12+
];
13+
14+
const REQUESTED_ENCODINGS = [
15+
// deflate is tricky, so we don't request it
16+
'gzip',
17+
'br'
18+
]
19+
820
module.exports = function (config) {
921
function acceptableCompression(data) {
10-
// deflate is tricky so we're only going to ask for gzip if the client allows it
11-
if (
12-
data.headers["accept-encoding"] &&
13-
data.headers["accept-encoding"].includes("gzip")
14-
) {
15-
data.headers["accept-encoding"] = "gzip";
22+
var encodings = (data.headers["accept-encoding"] || '')
23+
.split(',')
24+
.map(s => s.trim())
25+
.filter(s => REQUESTED_ENCODINGS.includes(s));
26+
if (encodings.length) {
27+
data.headers["accept-encoding"] = encodings.join(', ');
1628
} else {
1729
delete data.headers["accept-encoding"];
1830
}
@@ -31,11 +43,8 @@ module.exports = function (config) {
3143
return false;
3244
}
3345

34-
// decompress if it's gzipped or deflate'd
35-
return (
36-
headers["content-encoding"] == "gzip" ||
37-
headers["content-encoding"] == "deflate"
38-
);
46+
// decompress if it's in a supported encoding
47+
return SUPPORTED_ENCODINGS.includes(headers["content-encoding"]);
3948
}
4049

4150
function decompressResponse(data) {
@@ -54,6 +63,11 @@ module.exports = function (config) {
5463
var placeHolder = new PassThrough();
5564
data.stream = placeHolder;
5665

66+
const encoding = data.headers["content-encoding"];
67+
68+
// we're decoding it here, so this won't by the time it gets to the client
69+
delete data.headers["content-encoding"];
70+
5771
var handleData = function handleData() {
5872
var firstChunk = sourceStream.read();
5973

@@ -65,11 +79,13 @@ module.exports = function (config) {
6579
}
6680

6781
var decompressStream;
68-
if (data.headers["content-encoding"] == "deflate") {
82+
if (encoding == "deflate") {
6983
// https://github.com/nfriedly/node-unblocker/issues/12
7084
// inflateRaw seems to work here wheras inflate and unzip do not.
7185
// todo: validate this against other sites - if some require raw and others require non-raw, then maybe just rewrite the accept-encoding header to gzip only
7286
decompressStream = zlib.createInflateRaw();
87+
} else if (encoding == 'br') {
88+
decompressStream = zlib.createBrotliDecompress();
7389
} else {
7490
decompressStream = zlib.createUnzip();
7591
}
@@ -83,7 +99,6 @@ module.exports = function (config) {
8399
// if we do get data, create a decompression stream and pipe through it
84100
sourceStream.once("readable", handleData);
85101

86-
delete data.headers["content-encoding"];
87102
}
88103
}
89104

0 commit comments

Comments
 (0)