From 2a2d4384afd601d8697277b0e737466418db53c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muhammet=20=C3=96zt=C3=BCrk?= Date: Fri, 26 Apr 2019 19:20:15 +0300 Subject: [PATCH] Adding Brotli Support (#598) * adding brotli support * support old node versions * better test --- .gitignore | 3 +++ src/index.js | 8 ++++++++ test/server.js | 18 ++++++++++++++++++ test/test.js | 28 ++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/.gitignore b/.gitignore index 97fd1c6..839eff4 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ lib # Ignore package manager lock files package-lock.json yarn.lock + +# Ignore IDE +.idea diff --git a/src/index.js b/src/index.js index e227998..6d2132a 100644 --- a/src/index.js +++ b/src/index.js @@ -244,6 +244,14 @@ export default function fetch(url, opts) { return; } + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + // otherwise, use response as-is response = new Response(body, response_options); resolve(response); diff --git a/test/server.js b/test/server.js index e672a6e..524208f 100644 --- a/test/server.js +++ b/test/server.js @@ -94,6 +94,18 @@ export default class TestServer { }); } + if (p === '/brotli') { + res.statusCode = 200; + res.setHeader('Content-Type', 'text/plain'); + if (typeof zlib.createBrotliDecompress === 'function') { + res.setHeader('Content-Encoding', 'br'); + zlib.brotliCompress('hello world', function (err, buffer) { + res.end(buffer); + }); + } + } + + if (p === '/deflate-raw') { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); @@ -308,6 +320,12 @@ export default class TestServer { res.end(); } + if (p === '/no-content/brotli') { + res.statusCode = 204; + res.setHeader('Content-Encoding', 'br'); + res.end(); + } + if (p === '/not-modified') { res.statusCode = 304; res.end(); diff --git a/test/test.js b/test/test.js index 9384abd..019ba73 100644 --- a/test/test.js +++ b/test/test.js @@ -50,6 +50,7 @@ import RequestOrig from '../src/request.js'; import ResponseOrig from '../src/response.js'; import Body from '../src/body.js'; import Blob from '../src/blob.js'; +import zlib from "zlib"; const supportToString = ({ [Symbol.toStringTag]: 'z' @@ -664,6 +665,33 @@ describe('node-fetch', () => { }); }); + it('should decompress brotli response', function() { + if(typeof zlib.createBrotliDecompress !== 'function') this.skip(); + const url = `${base}brotli`; + return fetch(url).then(res => { + expect(res.headers.get('content-type')).to.equal('text/plain'); + return res.text().then(result => { + expect(result).to.be.a('string'); + expect(result).to.equal('hello world'); + }); + }); + }); + + it('should handle no content response with brotli encoding', function() { + if(typeof zlib.createBrotliDecompress !== 'function') this.skip(); + const url = `${base}no-content/brotli`; + return fetch(url).then(res => { + expect(res.status).to.equal(204); + expect(res.statusText).to.equal('No Content'); + expect(res.headers.get('content-encoding')).to.equal('br'); + expect(res.ok).to.be.true; + return res.text().then(result => { + expect(result).to.be.a('string'); + expect(result).to.be.empty; + }); + }); + }); + it('should skip decompression if unsupported', function() { const url = `${base}sdch`; return fetch(url).then(res => {