diff --git a/lib/parser.js b/lib/parser.js index 2852b5f9249a59adf8f51f3451181ac2c994bc54..e56d2c932b92424a0f43a77b57e575d90a634cc2 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -3,6 +3,7 @@ const http = require('http'); const https = require('https'); const xml2js = require('xml2js'); const url = require('url'); +const zlib = require('zlib'); const fields = require('./fields'); const utils = require('./utils'); @@ -88,14 +89,43 @@ class Parser { return reject(new Error("Status code " + res.statusCode)) } let encoding = utils.getEncodingFromContentType(res.headers['content-type']); - res.setEncoding(encoding); - res.on('data', (chunk) => { - xml += chunk; - }); - res.on('end', () => { - return this.parseString(xml).then(resolve, reject); - }); - }) + const contentEncoding = (res.headers['content-encoding'] || '').toLowerCase(); + let decompressStream; + switch (contentEncoding) { + case 'gzip': + decompressStream = zlib.createGunzip(); + break; + case 'deflate': + decompressStream = zlib.createInflate(); + break; + case 'br': + decompressStream = zlib.createBrotliDecompress(); + break; + case 'zstd': + if (zlib.createZstdDecompress) { + decompressStream = zlib.createZstdDecompress(); + } + break; + } + if (decompressStream) { + const chunks = []; + decompressStream.on('data', (chunk) => chunks.push(chunk)); + decompressStream.on('end', () => { + const decompressed = Buffer.concat(chunks).toString(encoding); + return this.parseString(decompressed).then(resolve, reject); + }); + decompressStream.on('error', reject); + res.pipe(decompressStream); + } else { + res.setEncoding(encoding); + res.on('data', (chunk) => { + xml += chunk; + }); + res.on('end', () => { + return this.parseString(xml).then(resolve, reject); + }); + } + }); req.on('error', reject); timeout = setTimeout(() => { return reject(new Error("Request timed out after " + this.options.timeout + "ms"));