Skip to content
This repository was archived by the owner on Aug 18, 2022. It is now read-only.

Commit a1e76b9

Browse files
gregory90TimothyGu
authored andcommitted
1 parent 047799b commit a1e76b9

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

src/index.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,18 @@ export default function fetch(url, opts) {
141141
return;
142142
}
143143

144+
// Be less strict when decoding compressed responses, since sometimes
145+
// servers send slightly invalid responses that are still accepted
146+
// by common browsers.
147+
// Always using Z_SYNC_FLUSH is what cURL does.
148+
const zlibOptions = {
149+
flush: zlib.Z_SYNC_FLUSH,
150+
finishFlush: zlib.Z_SYNC_FLUSH
151+
};
152+
144153
// for gzip
145154
if (codings == 'gzip' || codings == 'x-gzip') {
146-
body = body.pipe(zlib.createGunzip());
155+
body = body.pipe(zlib.createGunzip(zlibOptions));
147156
resolve(new Response(body, response_options));
148157
return;
149158
}
@@ -156,9 +165,9 @@ export default function fetch(url, opts) {
156165
raw.once('data', chunk => {
157166
// see http://stackoverflow.com/questions/37519828
158167
if ((chunk[0] & 0x0F) === 0x08) {
159-
body = body.pipe(zlib.createInflate());
168+
body = body.pipe(zlib.createInflate(zlibOptions));
160169
} else {
161-
body = body.pipe(zlib.createInflateRaw());
170+
body = body.pipe(zlib.createInflateRaw(zlibOptions));
162171
}
163172
resolve(new Response(body, response_options));
164173
});

test/server.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ export default class TestServer {
7070
});
7171
}
7272

73+
if (p === '/gzip-truncated') {
74+
res.statusCode = 200;
75+
res.setHeader('Content-Type', 'text/plain');
76+
res.setHeader('Content-Encoding', 'gzip');
77+
zlib.gzip('hello world', function(err, buffer) {
78+
// truncate the CRC checksum and size check at the end of the stream
79+
res.end(buffer.slice(0, buffer.length - 8));
80+
});
81+
}
82+
7383
if (p === '/deflate') {
7484
res.statusCode = 200;
7585
res.setHeader('Content-Type', 'text/plain');

test/test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,17 @@ describe('node-fetch', () => {
513513
});
514514
});
515515

516+
it('should decompress slightly invalid gzip response', function() {
517+
url = `${base}gzip-truncated`;
518+
return fetch(url).then(res => {
519+
expect(res.headers.get('content-type')).to.equal('text/plain');
520+
return res.text().then(result => {
521+
expect(result).to.be.a('string');
522+
expect(result).to.equal('hello world');
523+
});
524+
});
525+
});
526+
516527
it('should decompress deflate response', function() {
517528
url = `${base}deflate`;
518529
return fetch(url).then(res => {

0 commit comments

Comments
 (0)