diff --git a/index.js b/index.js index 3d31fbc..aed91cd 100644 --- a/index.js +++ b/index.js @@ -85,9 +85,14 @@ function requestAsEventEmitter(opts) { } setImmediate(() => { - const response = typeof decompressResponse === 'function' && + const response = opts.decompress === true && + typeof decompressResponse === 'function' && req.method !== 'HEAD' ? decompressResponse(res) : res; + if (!opts.decompress && ['gzip', 'deflate'].indexOf(res.headers['content-encoding']) !== -1) { + opts.encoding = null; + } + response.redirectUrls = redirects; ee.emit('response', response); @@ -280,6 +285,7 @@ function normalizeArguments(url, opts) { { path: '', retries: 2, + decompress: true, useElectronNet: true }, url, diff --git a/readme.md b/readme.md index e3219f1..bdff9c6 100644 --- a/readme.md +++ b/readme.md @@ -152,6 +152,15 @@ Defines if redirect responses should be followed automatically. Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), got will automatically request the resource pointed to in the location header via `GET`. This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4). +###### decompress + +Type: `boolean`
+Default: `true` + +Decompress the response automatically. + +If this is disabled, a compressed response is returned as a `Buffer`. This may be useful if you want to handle decompression yourself or stream the raw compressed data. + ###### useElectronNet Type: `boolean`
diff --git a/test/gzip.js b/test/gzip.js index 1ec90b5..5033509 100644 --- a/test/gzip.js +++ b/test/gzip.js @@ -1,15 +1,19 @@ import zlib from 'zlib'; import test from 'ava'; import getStream from 'get-stream'; +import pify from 'pify'; import got from '..'; import {createServer} from './helpers/server'; const testContent = 'Compressible response content.\n'; +const testContentUncompressed = 'Uncompressed response content.\n'; let s; +let gzipData; test.before('setup', async () => { s = await createServer(); + gzipData = await pify(zlib.gzip)(testContent); s.on('/', (req, res) => { res.statusCode = 200; @@ -21,7 +25,7 @@ test.before('setup', async () => { return; } - zlib.gzip(testContent, (_, data) => res.end(data)); + res.end(gzipData); }); s.on('/corrupted', (req, res) => { @@ -35,7 +39,13 @@ test.before('setup', async () => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.setHeader('Content-Encoding', 'gzip'); - zlib.gzip(testContent, (_, data) => res.end(data.slice(0, -1))); + res.end(gzipData.slice(0, -1)); + }); + + s.on('/uncompressed', (req, res) => { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + res.end(testContentUncompressed); }); await s.listen(s.port); @@ -56,6 +66,16 @@ test('handles gzip error', async t => { t.is(err.name, 'ReadError'); }); +test('decompress option opts out of decompressing', async t => { + const response = await got(s.url, {decompress: false}); + t.true(Buffer.compare(response.body, gzipData) === 0); +}); + +test('decompress option doesn\'t alter encoding of uncompressed responses', async t => { + const response = await got(`${s.url}/uncompressed`, {decompress: false}); + t.is(response.body, testContentUncompressed); +}); + test('preserve headers property', async t => { t.truthy((await got(s.url)).headers); });