Merge pull request #307 from alibaba/brotli-content-encoding

fix 302, enhance content encoding
This commit is contained in:
Otto Mao 2017-12-29 10:14:18 +08:00 committed by GitHub
commit 8c3727e9c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 15 deletions

View File

@ -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;

View File

@ -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",