diff --git a/lib/requestHandler.js b/lib/requestHandler.js index ecde92b..bba6b7f 100644 --- a/lib/requestHandler.js +++ b/lib/requestHandler.js @@ -12,6 +12,7 @@ const http = require('http'), logUtil = require('./log'), co = require('co'), HttpsServerMgr = require('./httpsServerMgr'), + brotliTorb = require('iltorb'), Readable = require('stream').Readable; const requestErrorHandler = require('./requestErrorHandler'); @@ -94,11 +95,30 @@ function fetchRemoteResponse(protocol, options, reqData, config) { } else { const serverResData = Buffer.concat(resDataChunks); const originContentLen = util.getByteSize(serverResData); + // remove gzip related header, and ungzip the content + // note there are other compression types like deflate + const contentEncoding = resHeader['content-encoding'] || resHeader['Content-Encoding']; + const ifServerGzipped = /gzip/i.test(contentEncoding); + const isServerDeflated = /deflate/i.test(contentEncoding); + const isBrotlied = /br/i.test(contentEncoding); + + /** + * when the content is unzipped, update the header content + */ + const refactContentEncoding = () => { + if (contentEncoding) { + resHeader['x-anyproxy-origin-content-encoding'] = contentEncoding; + delete resHeader['content-encoding']; + delete resHeader['Content-Encoding']; + } + } + // set origin content length into header resHeader['x-anyproxy-origin-content-length'] = originContentLen; - + // only do unzip when there is res data if (ifServerGzipped && originContentLen) { + refactContentEncoding(); zlib.gunzip(serverResData, (err, buff) => { // TODO test case to cover if (err) { rejectParsing(err); @@ -107,6 +127,7 @@ function fetchRemoteResponse(protocol, options, reqData, config) { } }); } else if (isServerDeflated && originContentLen) { + refactContentEncoding(); zlib.inflateRaw(serverResData, (err, buff) => { // TODO test case to cover if (err) { rejectParsing(err); @@ -114,6 +135,16 @@ function fetchRemoteResponse(protocol, options, reqData, config) { fulfill(buff); } }); + } else if (isBrotlied && originContentLen) { + refactContentEncoding(); + + brotliTorb.decompress(serverResData, (err, buff) => { + if (err) { + rejectParsing(err); + } else { + fulfill(buff); + } + }); } else { fulfill(serverResData); } @@ -131,12 +162,6 @@ function fetchRemoteResponse(protocol, options, reqData, config) { }); }; - // remove gzip related header, and ungzip the content - // note there are other compression types like deflate - const contentEncoding = resHeader['content-encoding'] || resHeader['Content-Encoding']; - const ifServerGzipped = /gzip/i.test(contentEncoding); - const isServerDeflated = /deflate/i.test(contentEncoding); - //deal response data res.on('data', (chunk) => { rawResChunks.push(chunk); @@ -265,7 +290,6 @@ function getUserReqHandler(userRule, recorder) { const responseBody = responseInfo.body || ''; const transferEncoding = resHeader['transfer-encoding'] || resHeader['Transfer-Encoding'] || ''; - const contentEncoding = resHeader['content-encoding'] || resHeader['Content-Encoding']; const contentLength = resHeader['content-length'] || resHeader['Content-Length']; const connection = resHeader.Connection || resHeader.connection; if (contentLength) { @@ -273,12 +297,6 @@ function getUserReqHandler(userRule, recorder) { delete resHeader['Content-Length']; } - if (contentEncoding) { - resHeader['x-anyproxy-origin-content-encoding'] = contentEncoding; - delete resHeader['content-encoding']; - delete resHeader['Content-Encoding']; - } - // set proxy-connection if (connection) { resHeader['x-anyproxy-origin-connection'] = connection; diff --git a/package.json b/package.json index e2008d5..37bdea5 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "es6-promise": "^3.3.1", "express": "^4.8.5", "iconv-lite": "^0.4.6", + "iltorb": "^2.0.3", "inquirer": "^3.0.1", "ip": "^0.3.2", "juicer": "^0.6.6-stable", @@ -92,7 +93,7 @@ "worker-loader": "^0.7.1" }, "scripts": { - "prepublish":"npm run buildweb", + "prepublish": "npm run buildweb", "test": "node test.js", "lint": "eslint .", "testserver": "node test/server/startServer.js",