12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- 'use strict';
- const {Transform, PassThrough} = require('stream');
- const zlib = require('zlib');
- const mimicResponse = require('mimic-response');
-
- module.exports = response => {
- const contentEncoding = (response.headers['content-encoding'] || '').toLowerCase();
-
- if (!['gzip', 'deflate', 'br'].includes(contentEncoding)) {
- return response;
- }
-
- // TODO: Remove this when targeting Node.js 12.
- const isBrotli = contentEncoding === 'br';
- if (isBrotli && typeof zlib.createBrotliDecompress !== 'function') {
- response.destroy(new Error('Brotli is not supported on Node.js < 12'));
- return response;
- }
-
- let isEmpty = true;
-
- const checker = new Transform({
- transform(data, _encoding, callback) {
- isEmpty = false;
-
- callback(null, data);
- },
-
- flush(callback) {
- callback();
- }
- });
-
- const finalStream = new PassThrough({
- autoDestroy: false,
- destroy(error, callback) {
- response.destroy();
-
- callback(error);
- }
- });
-
- const decompressStream = isBrotli ? zlib.createBrotliDecompress() : zlib.createUnzip();
-
- decompressStream.once('error', error => {
- if (isEmpty && !response.readable) {
- finalStream.end();
- return;
- }
-
- finalStream.destroy(error);
- });
-
- mimicResponse(response, finalStream);
- response.pipe(checker).pipe(decompressStream).pipe(finalStream);
-
- return finalStream;
- };
|