From ee0f285e78a5a754069ccb70a179074d58d61fb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=9A=E7=84=B6?= <yanran.wwj@alipay.com> Date: Thu, 28 Dec 2017 21:31:13 +0800 Subject: [PATCH 1/2] Only update the `content-header` when the content is handled by AnyProxy --- lib/requestHandler.js | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/requestHandler.js b/lib/requestHandler.js index ecde92b..2480102 100644 --- a/lib/requestHandler.js +++ b/lib/requestHandler.js @@ -94,11 +94,29 @@ 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); + + /** + * 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 +125,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); @@ -131,12 +150,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 +278,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 +285,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; From 63170983674a50b3d08ea3ee1f4cc55721add0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=9A=E7=84=B6?= <yanran.wwj@alipay.com> Date: Thu, 28 Dec 2017 21:57:10 +0800 Subject: [PATCH 2/2] Support to decompress the brotli content-encoding --- lib/requestHandler.js | 12 ++++++++++++ package.json | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/requestHandler.js b/lib/requestHandler.js index 2480102..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'); @@ -99,6 +100,7 @@ function fetchRemoteResponse(protocol, options, reqData, config) { 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 @@ -133,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); } 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",