mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-08-04 21:39:04 +00:00
update to 4.0
This commit is contained in:
@@ -1 +0,0 @@
|
||||
ab -X 127.0.0.1:8001 -n $1 -c $2 -H "HOST:127.0.0.1" http://127.0.0.1:8080/
|
||||
@@ -1 +0,0 @@
|
||||
ab -X 127.0.0.1:8001 -n $1 -c $2 -H "HOST:www.taobao.com" http://www.taobao.com/
|
||||
@@ -6,23 +6,24 @@
|
||||
// Get 和 Post共有的header信息
|
||||
/*eslint max-len: ["off"]*/
|
||||
const CommonRequestHeader = {
|
||||
Accept: 'application/json;charset=utf-8,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Charset': 'utf-8',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Accept-Language': 'zh-CN',
|
||||
'Accept-Datetime': 'Thu, 31 May 2007 20:35:00 GMT',
|
||||
'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Connection': 'keep-alive',
|
||||
'Cookie': 'testCookie1=cookie1; testCookie2=cookie2',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Date': 'Tue, 15 Nov 1994 08:12:31 GMT',
|
||||
'Origin': 'http://localhost',
|
||||
'Pragma': 'no-cache',
|
||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
|
||||
Accept: 'application/json;charset=utf-8,text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Charset': 'utf-8',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Accept-Language': 'zh-CN',
|
||||
'Accept-Datetime': 'Thu, 31 May 2007 20:35:00 GMT',
|
||||
Authorization: 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
|
||||
'Cache-Control': 'no-cache',
|
||||
Connection: 'keep-alive',
|
||||
Cookie: 'testCookie1=cookie1; testCookie2=cookie2',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
Date: 'Tue, 15 Nov 1994 08:12:31 GMT',
|
||||
Origin: 'http://localhost',
|
||||
Pragma: 'no-cache',
|
||||
some_thing: 'only_to_test_letter_case',
|
||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
CommonRequestHeader
|
||||
CommonRequestHeader
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
function test () {
|
||||
console.info('This is nothing but a js file, to test the js download');
|
||||
}
|
||||
function test() {
|
||||
console.info('This is nothing but a js file, to test the js download');
|
||||
}
|
||||
test();
|
||||
|
||||
13
test/jasmine.json
Normal file
13
test/jasmine.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"spec_dir": "test",
|
||||
"spec_files": [
|
||||
"spec_lib/*.js",
|
||||
"spec_rule/*.js"
|
||||
],
|
||||
"helpers": [
|
||||
"../node_modules/babel-register/lib/node.js",
|
||||
"../node_modules/babel-polyfill/dist/polyfill.js"
|
||||
],
|
||||
"stopSpecOnExpectationFailure": true,
|
||||
"random": false
|
||||
}
|
||||
@@ -1,37 +1,35 @@
|
||||
var proxy = require("../proxy.js"),
|
||||
proxyTester = require("proxy-eval"),
|
||||
WebSocket = require("ws"),
|
||||
Buffer = require("buffer").Buffer,
|
||||
express = require("express");
|
||||
const proxyTester = require('proxy-eval'),
|
||||
Buffer = require('buffer').Buffer,
|
||||
express = require('express');
|
||||
|
||||
var app = express()
|
||||
const app = express();
|
||||
|
||||
app.post('/', function (req, res) {
|
||||
var bigBody = new Buffer(1024 * 1024 * 10);
|
||||
res.send( bigBody ); //10 mb
|
||||
app.post('/', (req, res) => {
|
||||
const bigBody = new Buffer(1024 * 1024 * 10);
|
||||
res.send(bigBody); //10 mb
|
||||
});
|
||||
app.listen(3000);
|
||||
|
||||
function test(){
|
||||
//test the basic availibility of proxy server
|
||||
setTimeout(function(){
|
||||
var testParam = {
|
||||
proxy : 'http://127.0.0.1:8001/',
|
||||
reqTimeout : 4500,
|
||||
httpGetUrl : "",
|
||||
httpPostUrl : "http://127.0.0.1:3000/",
|
||||
httpPostBody : "123",
|
||||
httpsGetUrl : "",
|
||||
httpsPostUrl : "",
|
||||
httpsPostBody : ""
|
||||
};
|
||||
proxyTester.test(testParam ,function(results){
|
||||
process.exit();
|
||||
});
|
||||
},1000);
|
||||
};
|
||||
function test() {
|
||||
//test the basic availibility of proxy server
|
||||
setTimeout(() => {
|
||||
const testParam = {
|
||||
proxy: 'http://127.0.0.1:8001/',
|
||||
reqTimeout: 4500,
|
||||
httpGetUrl: '',
|
||||
httpPostUrl: 'http://127.0.0.1:3000/',
|
||||
httpPostBody: '123',
|
||||
httpsGetUrl: '',
|
||||
httpsPostUrl: '',
|
||||
httpsPostBody: ''
|
||||
};
|
||||
proxyTester.test(testParam, (results) => {
|
||||
process.exit();
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
setTimeout(function(){
|
||||
test();
|
||||
},3000);
|
||||
setTimeout(() => {
|
||||
test();
|
||||
}, 3000);
|
||||
|
||||
|
||||
@@ -1,459 +0,0 @@
|
||||
const http = require('http');
|
||||
const querystring = require('querystring');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const Buffer = require('buffer').Buffer;
|
||||
const Server = require('./server/server.js');
|
||||
const
|
||||
{
|
||||
proxyGet,
|
||||
proxyPost,
|
||||
directGet,
|
||||
directPost,
|
||||
directUpload,
|
||||
proxyUpload,
|
||||
generateUrl,
|
||||
proxyPut,
|
||||
directPut,
|
||||
proxyDelete,
|
||||
directDelete,
|
||||
directHead,
|
||||
proxyHead,
|
||||
directOptions,
|
||||
proxyOptions,
|
||||
proxyPutUpload,
|
||||
directPutUpload
|
||||
} = require('./util/HttpUtil.js');
|
||||
const { CommonRequestHeader } = require('./data/headers.js');
|
||||
const { isCommonResHeaderEqual, isCommonReqEqual, printLog } = require('./util/CommonUtil.js');
|
||||
const color = require('colorful');
|
||||
const streamEqual = require('stream-equal');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
const ProxyServerUtil = require('./util/ProxyServerUtil.js');
|
||||
|
||||
const wsHost = 'ws://localhost:3000/test/socket';
|
||||
|
||||
testRequest('http');
|
||||
testRequest('https');
|
||||
|
||||
// Test suites for http and https request
|
||||
function testRequest(protocol = 'http') {
|
||||
|
||||
function constructUrl(urlPath) {
|
||||
return generateUrl(protocol, urlPath);
|
||||
}
|
||||
|
||||
describe('Test request without proxy rules in protocol ' + protocol, () => {
|
||||
let proxyServer ;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for no_rule_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
proxyServer = ProxyServerUtil.defaultProxyServer();
|
||||
setTimeout(function() {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for no_rule_spec');
|
||||
});
|
||||
|
||||
|
||||
it('Get should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test');
|
||||
const getParam = {
|
||||
param: 'nothing'
|
||||
};
|
||||
|
||||
proxyGet(url, getParam, CommonRequestHeader).then((proxyRes) => {
|
||||
directGet(url, getParam, CommonRequestHeader).then(directRes => {
|
||||
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happend in direct get:', error);
|
||||
done.fail('error happend in direct get');
|
||||
});
|
||||
|
||||
}, error => {
|
||||
console.log('error happened in proxy get:', error);
|
||||
done.fail('error happend in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Post should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/getuser');
|
||||
const param = {
|
||||
param: 'postnothing'
|
||||
};
|
||||
|
||||
proxyPost(url, param, CommonRequestHeader).then(proxyRes => {
|
||||
directPost(url, param, CommonRequestHeader).then(directRes => {
|
||||
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in direct post:', error);
|
||||
done.fail('error happend in direct post');
|
||||
});
|
||||
|
||||
}, error => {
|
||||
console.log('error happened in proxy post,', error);
|
||||
done.fail('error happend in proxy post');
|
||||
});
|
||||
});
|
||||
|
||||
it('PUT should work as direct without proxy rules', done => {
|
||||
const url = constructUrl('/test/put');
|
||||
const param = {
|
||||
param: 'putsomething'
|
||||
};
|
||||
proxyPut(url, param, CommonRequestHeader).then(proxyRes => {
|
||||
directPut(url, param, CommonRequestHeader).then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct put', error);
|
||||
done.fail('error happened in direct put');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy put', error);
|
||||
done.fail('error happened in proxy put');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('DELETE rquest should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/delete/123456');
|
||||
|
||||
proxyDelete(url, {}, CommonRequestHeader).then(proxyRes => {
|
||||
directDelete(url, {}, CommonRequestHeader).then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct delete :', error);
|
||||
done.fail('error happened in direct delete');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy delete :', error);
|
||||
done.fail('error happened in proxy delete');
|
||||
});
|
||||
});
|
||||
|
||||
it('HEAD request should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/head');
|
||||
|
||||
proxyHead(url, CommonRequestHeader)
|
||||
.then(proxyRes => {
|
||||
directHead(url, CommonRequestHeader)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('');
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct head request:', error);
|
||||
done.fail('error happened in direct head request');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy head request:', error);
|
||||
done.fail('error happened in proxy head request');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('OPTIONS request should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/options');
|
||||
|
||||
proxyOptions(url, CommonRequestHeader)
|
||||
.then(proxyRes => {
|
||||
directOptions(url, CommonRequestHeader)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('could_be_empty');
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct options request:', error);
|
||||
done.fail('error happened in direct options request');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy options request:', error);
|
||||
done.fail('error happened in proxy options request');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Response code should be honored as direct without proxy rules', () => {
|
||||
[301, 302, 303].forEach(code => {
|
||||
testRedirect(code);
|
||||
});
|
||||
|
||||
function testRedirect (redirectCode) {
|
||||
it(`${redirectCode} response should work as direct without proxy rules`, (done) => {
|
||||
const url = constructUrl(`/test/response/${redirectCode}`);
|
||||
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
const redirects = directRes.request._redirect.redirects || [];
|
||||
const proxyRedirects = proxyRes.request._redirect.redirects || [];
|
||||
expect(redirects.length).toEqual(1);
|
||||
expect(proxyRedirects.length).toEqual(1);
|
||||
|
||||
expect(redirects[0].statusCode).toEqual(redirectCode);
|
||||
expect(redirects[0].redirectUri).toEqual(proxyRedirects[0].redirectUri);
|
||||
expect(redirects[0].statusCode).toEqual(proxyRedirects[0].statusCode);
|
||||
if (protocol === 'https') {
|
||||
expect(redirects[0].redirectUri).toEqual('https://localhost:3001/test');
|
||||
} else {
|
||||
expect(redirects[0].redirectUri).toEqual('http://localhost:3000/test');
|
||||
}
|
||||
done();
|
||||
}, error => {
|
||||
console.log(`error happened in direct ${redirectCode}:`, error);
|
||||
done.fail(`error happened in direct ${redirectCode}`);
|
||||
});
|
||||
|
||||
}, error => {
|
||||
console.log(`error happened in proxy ${redirectCode}:`, error);
|
||||
done.fail(`error happened in proxy ${redirectCode}`);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
describe('Test file download ', () => {
|
||||
const testArray = [
|
||||
{
|
||||
url: constructUrl('/test/download/png'),
|
||||
type: 'png',
|
||||
contentType: 'image/png'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/webp'),
|
||||
type: 'WEBP',
|
||||
contentType: 'image/webp'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/json'),
|
||||
type: 'JSON',
|
||||
contentType: 'application/json; charset=utf-8'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/css'),
|
||||
type: 'CSS',
|
||||
contentType: 'text/css; charset=utf-8'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/ttf'),
|
||||
type: 'TTF',
|
||||
contentType: 'application/x-font-ttf'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/eot'),
|
||||
type: 'EOT',
|
||||
contentType: 'application/vnd.ms-fontobject'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/svg'),
|
||||
type: 'SVG',
|
||||
contentType: 'image/svg+xml'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/woff'),
|
||||
type: 'WOFF',
|
||||
contentType: 'application/font-woff'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/woff2'),
|
||||
type: 'WOFF2',
|
||||
contentType: 'application/font-woff2'
|
||||
}
|
||||
];
|
||||
|
||||
testArray.forEach(item => {
|
||||
testFileDownload(item.url, item.type, item.contentType);
|
||||
});
|
||||
|
||||
// 封装测试文件下载的测试工具类
|
||||
function testFileDownload (url, filetype, contentType) {
|
||||
const describe = `${filetype} file download without rules should be work as direct download`;
|
||||
const param = {};
|
||||
|
||||
it(describe, (done) => {
|
||||
|
||||
proxyGet(url, param).then(proxyRes => {
|
||||
directGet(url, param).then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(proxyRes.body).toEqual(directRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in direct get :', filetype, error);
|
||||
done.fail(`error happend in direct get ${filetype}`);
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy get :', filetype, error);
|
||||
done.fail(`error happend in proxy get ${filetype}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
describe('Test file upload', () => {
|
||||
const formParams = {
|
||||
param1: 'param_1',
|
||||
param2: 'param2'
|
||||
};
|
||||
it('POST upload should be working', (done) => {
|
||||
const url = constructUrl('/test/upload/png');
|
||||
const filePath = path.resolve('./test/data/test.png');
|
||||
|
||||
proxyUpload(url, filePath, formParams)
|
||||
.then(proxyRes => {
|
||||
directUpload(url, filePath, formParams)
|
||||
.then((directRes) => {
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
assertReponse(proxyRes, directRes, filePath, done);
|
||||
}, error => {
|
||||
console.error('error in direct upload:', error);
|
||||
done.fail('error in direct upload');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy upload:', error);
|
||||
done.fail('error in proxy upload:');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('PUT upload should be working', (done) => {
|
||||
const url = constructUrl('/test/upload/putpng');
|
||||
const filePath = path.resolve('./test/data/test.png');
|
||||
proxyPutUpload(url, filePath, formParams)
|
||||
.then(proxyRes => {
|
||||
directPutUpload(url, filePath, formParams)
|
||||
.then((directRes) => {
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
|
||||
assertReponse(proxyRes, directRes, filePath, done);
|
||||
}, error => {
|
||||
console.error('error in direct upload:', error);
|
||||
done.fail('error in direct upload');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy upload:', error);
|
||||
done.fail('error in proxy upload:');
|
||||
});
|
||||
});
|
||||
|
||||
function assertReponse (proxyRes, directRes, originFilePath, done) {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
// expect(proxyRes.headers.reqbody).toEqual(directRes.headers.reqbody);
|
||||
|
||||
// the body will be the file path
|
||||
const directUploadedStream = fs.createReadStream(directRes.body);
|
||||
const proxyUploadedStream = fs.createReadStream(proxyRes.body);
|
||||
const localFileStream = fs.createReadStream(originFilePath);
|
||||
streamEqual(directUploadedStream, localFileStream)
|
||||
.then(isLocalEqual => {
|
||||
expect(isLocalEqual).toBe(true);
|
||||
streamEqual(directUploadedStream, proxyUploadedStream)
|
||||
.then(isUploadedEqual => {
|
||||
expect(isUploadedEqual).toBe(true);
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in comparing directUpload with proxy:\n',error);
|
||||
done.fail('error in comparing directUpload with proxy');
|
||||
});
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in comparing directUpload with local:\n',error);
|
||||
done.fail('error in comparing directUpload with local');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// describe('Test Big file download', () => {
|
||||
// // const url = '/test/download/bigfile';
|
||||
// const url = 'http://yunpan.alibaba-inc.com/downloadService.do?token=pZWiXMXUguIUQDvR098qnUVqVAWhNVY6';
|
||||
// const contentType = 'application/octet-stream';
|
||||
// const param = {};
|
||||
// it('BIG file downlaod should be working', (done) => {
|
||||
// directGet(url, param, CommonRequestHeader).then(proxyRes => {
|
||||
// console.info('proxyRes body:', proxyRes.body);
|
||||
|
||||
// directGet(url, param, CommonRequestHeader).then(directRes => {
|
||||
// expect(proxyRes.statusCode).toEqual(200);
|
||||
// expect(proxyRes.headers['content-type']).toEqual(contentType);
|
||||
|
||||
// expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
// expect(proxyRes.headers['content-type']).toEqual(directRes.headers['content-type']);
|
||||
// expect(proxyRes.body).toEqual(directRes.body);
|
||||
// done();
|
||||
// }, error => {
|
||||
// console.error('error in direct get bigfile :', error);
|
||||
// done.fail(`error happend in direct get bigfile`);
|
||||
// });
|
||||
// }, error => {
|
||||
// console.error('error in proxy get bigfile :', error);
|
||||
// done.fail(`error happend in proxy get bigfile`);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Test suites for WebSocket.
|
||||
* ONLY TO ENSURE THE REQUEST WILL BE BYPASSED SUCCESSFULLY, WE HAVEN'T SUPPORTTED WEBSOCKET YET.
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('./util/ProxyServerUtil.js');
|
||||
const { generateWsUrl, directWs, proxyWs } = require('./util/HttpUtil.js');
|
||||
const Server = require('./server/server.js');
|
||||
const { printLog } = require('./util/CommonUtil.js');
|
||||
|
||||
const wsHost = 'ws://localhost:3000/test/socket';
|
||||
|
||||
testWebsocket('ws');
|
||||
testWebsocket('wss');
|
||||
|
||||
function testWebsocket(protocol) {
|
||||
describe('Test WebSocket in protocol : ' + protocol , () =>{
|
||||
const url = generateWsUrl(protocol, '/test/socket');
|
||||
let serverInstance ;
|
||||
let proxyServer ;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for no_rule_websocket_spec');
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithoutHttpsIntercept();
|
||||
|
||||
setTimeout(function() {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for no_rule_websocket_spec');
|
||||
});
|
||||
|
||||
it('Default websocket option', done => {
|
||||
const sendMessage = 'Send the message with default option';
|
||||
let directMessage ; // set the flag for direct message, compare when both direct and proxy got message
|
||||
let proxyMessage;
|
||||
|
||||
const ws = directWs(url);
|
||||
const porxyWsRef = proxyWs(url);
|
||||
ws.on('open', () => {
|
||||
ws.send(sendMessage);
|
||||
});
|
||||
|
||||
porxyWsRef.on('open', () => {
|
||||
porxyWsRef.send(sendMessage);
|
||||
});
|
||||
|
||||
ws.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
directMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
porxyWsRef.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
proxyMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', error => {
|
||||
console.error('error happened in direct websocket:', error);
|
||||
done.fail('Error happened in direct websocket');
|
||||
});
|
||||
|
||||
porxyWsRef.on('error', error => {
|
||||
console.error('error happened in proxy websocket:', error);
|
||||
done.fail('Error happened in proxy websocket');
|
||||
});
|
||||
|
||||
function compareMessageIfReady () {
|
||||
if (directMessage && proxyMessage) {
|
||||
expect(directMessage).toEqual(proxyMessage);
|
||||
expect(directMessage).toEqual(sendMessage);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('masked:true', done => {
|
||||
const sendMessage = 'Send the message with option masked:true';
|
||||
let directMessage ; // set the flag for direct message, compare when both direct and proxy got message
|
||||
let proxyMessage;
|
||||
|
||||
const ws = directWs(url);
|
||||
const porxyWsRef = proxyWs(url);
|
||||
ws.on('open', () => {
|
||||
ws.send(sendMessage, { masked: true });
|
||||
});
|
||||
|
||||
porxyWsRef.on('open', () => {
|
||||
porxyWsRef.send(sendMessage, { masked: true });
|
||||
});
|
||||
|
||||
ws.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
directMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
porxyWsRef.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
proxyMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', error => {
|
||||
console.error('error happened in direct websocket:', error);
|
||||
done.fail('Error happened in direct websocket');
|
||||
});
|
||||
|
||||
porxyWsRef.on('error', error => {
|
||||
console.error('error happened in proxy websocket:', error);
|
||||
|
||||
done.fail('Error happened in proxy websocket');
|
||||
});
|
||||
|
||||
function compareMessageIfReady () {
|
||||
if (directMessage && proxyMessage) {
|
||||
expect(directMessage).toEqual(proxyMessage);
|
||||
expect(directMessage).toEqual(sendMessage);
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
1
test/report/README
Normal file
1
test/report/README
Normal file
@@ -0,0 +1 @@
|
||||
* this is a folder to save test reports *
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* test for rule shouldUseLocal
|
||||
*
|
||||
*/
|
||||
|
||||
const ProxyServerUtil = require('./util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl } = require('./util/HttpUtil.js');
|
||||
const Server = require('./server/server.js');
|
||||
const { printLog } = require('./util/CommonUtil.js');
|
||||
|
||||
const rule = require('./test_rules/shouldUseLocalResponseRule.js');
|
||||
const expectedLocalBody = 'handled_in_local_response';
|
||||
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol, ) {
|
||||
describe('Rule shouldUseLocalResponse should be working in :' + protocol, () => {
|
||||
let proxyServer ;
|
||||
let serverInstance ;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000000;
|
||||
printLog('Start server for rule_shouldUseLocalResponse_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(function() {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_shouldUseLocalResponse_spec');
|
||||
|
||||
});
|
||||
|
||||
it('Should use local response if the assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/uselocal');
|
||||
proxyGet(url, {})
|
||||
.then(res => {
|
||||
expect(res.body).toEqual(expectedLocalBody);
|
||||
expect(res.headers['via-proxy-local']).toEqual('true');
|
||||
done();
|
||||
}, error => {
|
||||
console.log('error happened in proxy get for shouldUseLocal: ',error);
|
||||
done.fail('error happened when test shouldUseLocal rule');
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -4,271 +4,339 @@ const koaBody = require('koa-body');
|
||||
const send = require('koa-send');
|
||||
const path = require('path');
|
||||
const https = require('https');
|
||||
const certMgr = require("../../lib/certMgr");
|
||||
const certMgr = require('../../lib/certMgr');
|
||||
const fs = require('fs');
|
||||
const nurl = require('url');
|
||||
const websocket = require('koa-websocket');
|
||||
const wsRouter = require('koa-router')();
|
||||
const color = require('colorful');
|
||||
const WebSocketServer = require('ws').Server;
|
||||
const tls = require('tls');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const createSecureContext = tls.createSecureContext || crypto.createSecureContext;
|
||||
|
||||
const DEFAULT_PORT = 3000;
|
||||
const HTTPS_PORT = 3001;
|
||||
const UPLOAD_DIR = './test/temp';
|
||||
const HTTPS_PORT2 = 3002; // start multiple https server
|
||||
const UPLOAD_DIR = path.resolve(__dirname, '../temp');
|
||||
const PROXY_KEY_PREFIX = 'proxy-';
|
||||
|
||||
function KoaServer() {
|
||||
this.httpServer = null;
|
||||
this.httpsServer = null;
|
||||
this.requestRecordMap = {}; // store all request data to the map
|
||||
const self = this;
|
||||
function SNICertCallback(serverName, SNICallback) {
|
||||
certMgr.getCertificate(serverName, (err, key, crt) => {
|
||||
if (err) {
|
||||
console.error('error happend in sni callback', err);
|
||||
return;
|
||||
}
|
||||
const ctx = createSecureContext({
|
||||
key,
|
||||
cert: crt
|
||||
});
|
||||
|
||||
/**
|
||||
* log the request info, write as
|
||||
*/
|
||||
this.logRequest = function* (next) {
|
||||
const headers = this.request.headers;
|
||||
let key = this.request.host + this.request.url;
|
||||
|
||||
// take proxy data with 'proxy-' + url
|
||||
if (headers['via-proxy'] === 'true') {
|
||||
key = PROXY_KEY_PREFIX + key;
|
||||
}
|
||||
|
||||
let body = this.request.body;
|
||||
body = typeof body === 'object' ? JSON.stringify(body) : body;
|
||||
self.requestRecordMap[key] = {
|
||||
headers: headers,
|
||||
body: body
|
||||
};
|
||||
yield next;
|
||||
};
|
||||
|
||||
this.start();
|
||||
SNICallback(null, ctx);
|
||||
});
|
||||
}
|
||||
|
||||
KoaServer.prototype.constructRouter = function() {
|
||||
const router = KoaRouter();
|
||||
router.post('/test/getuser', this.logRequest, koaBody(), function*(next) {
|
||||
printLog('requesting post /test/getuser');
|
||||
this.response.set('reqbody', JSON.stringify(this.request.body));
|
||||
this.response.body = 'something in post';
|
||||
});
|
||||
function KoaServer() {
|
||||
this.httpServer = null;
|
||||
this.httpsServer = null;
|
||||
this.requestRecordMap = {}; // store all request data to the map
|
||||
const self = this;
|
||||
|
||||
router.get('/test', this.logRequest, function*(next) {
|
||||
printLog('request in get: ' + JSON.stringify(this.request));
|
||||
this.response.body = 'something';
|
||||
this.response.__req = this.request;
|
||||
printLog('response in get:' + JSON.stringify(this.response));
|
||||
});
|
||||
/**
|
||||
* log the request info, write as
|
||||
*/
|
||||
this.logRequest = function *(next) {
|
||||
const headers = this.request.headers;
|
||||
let key = this.request.protocol + '://' + this.request.host + nurl.parse(this.request.url).pathname; // remove param to get clean key
|
||||
|
||||
router.get('/test/uselocal', this.logRequest, function*(next) {
|
||||
printLog('request in get local:' + JSON.stringify(this.request));
|
||||
this.response.body = 'something should be in local';
|
||||
this.response.__req = this.request;
|
||||
printLog('response in get:' + JSON.stringify(this.response));
|
||||
});
|
||||
// take proxy data with 'proxy-' + url
|
||||
if (headers['via-proxy'] === 'true') {
|
||||
key = PROXY_KEY_PREFIX + key;
|
||||
}
|
||||
|
||||
['png', 'webp', 'json', 'js', 'css', 'ttf', 'eot', 'svg', 'woff', 'woff2'].forEach(item => {
|
||||
router.get(`/test/download/${item}`, this.logRequest, function* (next) {
|
||||
printLog(`now downloading the ${item}`);
|
||||
yield send(this, `test/data/test.${item}`);
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/test/response/303', function*(next) {
|
||||
printLog('now to redirect 303');
|
||||
this.redirect('/test');
|
||||
this.status = 303;
|
||||
});
|
||||
|
||||
router.get('/test/response/302', function*(next) {
|
||||
printLog('now to redirect 302');
|
||||
this.redirect('/test');
|
||||
});
|
||||
|
||||
router.get('/test/response/301', function*(next) {
|
||||
printLog('now to redirect permanently');
|
||||
this.redirect('/test');
|
||||
this.status = 301;
|
||||
});
|
||||
|
||||
const onFileBegin = function(name, file) {
|
||||
if (!fs.existsSync('./test/temp')) {
|
||||
try {
|
||||
fs.mkdirSync('./test/temp', '0777');
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
file.name = 'test_upload_' + Date.now() + '.png';
|
||||
var folder = path.dirname(file.path);
|
||||
file.path = path.join(folder, file.name);
|
||||
printLog('log request with key :' + key);
|
||||
let body = this.request.body;
|
||||
body = typeof body === 'object' ? JSON.stringify(body) : body;
|
||||
|
||||
self.requestRecordMap[key] = {
|
||||
headers,
|
||||
body
|
||||
};
|
||||
yield next;
|
||||
};
|
||||
|
||||
router.post('/test/upload/png',
|
||||
this.logRequest,
|
||||
koaBody({
|
||||
multipart: true,
|
||||
formidable: {
|
||||
uploadDir: UPLOAD_DIR,
|
||||
onFileBegin: onFileBegin
|
||||
}
|
||||
}),
|
||||
function*(next) {
|
||||
const file = this.request.body.files.file;
|
||||
this.response.set('reqbody', JSON.stringify(this.request.body.fields));
|
||||
this.response.body = file.path;
|
||||
}
|
||||
);
|
||||
this.start();
|
||||
}
|
||||
|
||||
router.put('/test/upload/putpng',
|
||||
this.logRequest,
|
||||
koaBody({
|
||||
multipart: true,
|
||||
formidable: {
|
||||
uploadDir: UPLOAD_DIR,
|
||||
onFileBegin: onFileBegin
|
||||
}
|
||||
}),
|
||||
function*(next) {
|
||||
const file = this.request.body.files.file;
|
||||
this.response.body = file.path;
|
||||
}
|
||||
);
|
||||
KoaServer.prototype.constructRouter = function () {
|
||||
const router = KoaRouter();
|
||||
router.post('/test/getuser', koaBody(), this.logRequest, function *(next) {
|
||||
printLog('requesting post /test/getuser');
|
||||
this.response.set('reqbody', JSON.stringify(this.request.body));
|
||||
this.response.body = 'body_post_getuser';
|
||||
});
|
||||
|
||||
router.put('/test/put', koaBody(), this.logRequest, function*(next) {
|
||||
printLog('requesting put /test/put' + JSON.stringify(this.request));
|
||||
this.response.body = 'something in put';
|
||||
router.get('/test', this.logRequest, function *(next) {
|
||||
printLog('request in get: ' + JSON.stringify(this.request));
|
||||
this.cookies.set('a1', 'a1value');
|
||||
this.cookies.set('a2', 'a2value');
|
||||
this.cookies.set('a3', 'a3value');
|
||||
this.response.set('header1', 'cookie2=headervalue2');
|
||||
|
||||
this.response.body = 'something';
|
||||
this.response.__req = this.request;
|
||||
printLog('response in get:' + JSON.stringify(this.response));
|
||||
});
|
||||
|
||||
router.get('/test/uselocal', this.logRequest, function *(next) {
|
||||
printLog('request in get local:' + JSON.stringify(this.request));
|
||||
this.response.body = 'something should be in local';
|
||||
// this.response.__req = this.request;
|
||||
printLog('response in get:' + JSON.stringify(this.response));
|
||||
});
|
||||
|
||||
['png', 'webp', 'json', 'js', 'css', 'ttf', 'eot', 'svg', 'woff', 'woff2'].forEach(item => {
|
||||
router.get(`/test/download/${item}`, this.logRequest, function *(next) {
|
||||
yield send(this, `./data/test.${item}`, {
|
||||
root: path.resolve(__dirname, '../')
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.delete('/test/delete/:id', this.logRequest, function*(next) {
|
||||
printLog('requesting delete /test/delete/:id'+ JSON.stringify(this.params));
|
||||
this.response.body = 'something in delete';
|
||||
});
|
||||
router.get('/test/response/303', function *(next) {
|
||||
printLog('now to redirect 303');
|
||||
this.redirect('/test');
|
||||
this.status = 303;
|
||||
});
|
||||
|
||||
router.head('/test/head', this.logRequest, function*(next) {
|
||||
printLog('requesting head /test/head');
|
||||
this.response.body = ''; // the body will not be passed to response, in HEAD request
|
||||
this.response.set('reqBody', 'head_request_contains_no_resbody');
|
||||
});
|
||||
router.get('/test/response/302', function *(next) {
|
||||
printLog('now to redirect 302');
|
||||
this.redirect('/test');
|
||||
});
|
||||
|
||||
router.options('/test/options', this.logRequest, function*(next) {
|
||||
printLog('requesting options /test/options');
|
||||
this.response.body = 'could_be_empty';
|
||||
this.response.set('Allow', 'GET, HEAD, POST, OPTIONS');
|
||||
});
|
||||
router.get('/test/response/301', function *(next) {
|
||||
printLog('now to redirect permanently');
|
||||
this.redirect('/test');
|
||||
this.status = 301;
|
||||
});
|
||||
|
||||
// router.connect('/test/connect', function *(next) {
|
||||
// printLog('requesting connect /test/connect');
|
||||
// this.response.body = 'connect_established_body';
|
||||
// });
|
||||
const onFileBegin = function (name, file) {
|
||||
if (!fs.existsSync(UPLOAD_DIR)) {
|
||||
try {
|
||||
fs.mkdirSync(UPLOAD_DIR, '0777');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return router;
|
||||
file.name = 'test_upload_' + Date.now() + '.png';
|
||||
const folder = path.dirname(file.path);
|
||||
file.path = path.join(folder, file.name);
|
||||
};
|
||||
|
||||
router.post('/test/upload/png',
|
||||
this.logRequest,
|
||||
koaBody({
|
||||
multipart: true,
|
||||
formidable: {
|
||||
uploadDir: UPLOAD_DIR,
|
||||
onFileBegin
|
||||
}
|
||||
}),
|
||||
function *(next) {
|
||||
const file = this.request.body.files.file;
|
||||
this.response.set('reqbody', JSON.stringify(this.request.body.fields));
|
||||
this.response.body = file.path;
|
||||
}
|
||||
);
|
||||
|
||||
router.put('/test/upload/putpng',
|
||||
this.logRequest,
|
||||
koaBody({
|
||||
multipart: true,
|
||||
formidable: {
|
||||
uploadDir: UPLOAD_DIR,
|
||||
onFileBegin
|
||||
}
|
||||
}),
|
||||
function *(next) {
|
||||
const file = this.request.body.files.file;
|
||||
this.response.body = file.path;
|
||||
}
|
||||
);
|
||||
|
||||
router.put('/test/put', koaBody(), this.logRequest, function *(next) {
|
||||
printLog('requesting put /test/put' + JSON.stringify(this.request));
|
||||
this.response.body = 'something in put';
|
||||
});
|
||||
|
||||
router.delete('/test/delete/:id', this.logRequest, function *(next) {
|
||||
printLog('requesting delete /test/delete/:id' + JSON.stringify(this.params));
|
||||
this.response.body = 'something in delete';
|
||||
});
|
||||
|
||||
router.head('/test/head', this.logRequest, function *(next) {
|
||||
printLog('requesting head /test/head');
|
||||
this.response.body = ''; // the body will not be passed to response, in HEAD request
|
||||
this.response.set('reqBody', 'head_request_contains_no_resbody');
|
||||
});
|
||||
|
||||
router.options('/test/options', this.logRequest, function *(next) {
|
||||
printLog('requesting options /test/options');
|
||||
this.response.body = 'could_be_empty';
|
||||
this.response.set('Allow', 'GET, HEAD, POST, OPTIONS');
|
||||
});
|
||||
|
||||
// router.connect('/test/connect', function *(next) {
|
||||
// printLog('requesting connect /test/connect');
|
||||
// this.response.body = 'connect_established_body';
|
||||
// });
|
||||
|
||||
router.get('/test/should_not_replace_option', this.logRequest, function *(next) {
|
||||
this.response.body = 'the_option_that_not_be_replaced';
|
||||
});
|
||||
|
||||
router.get('/test/should_replace_option', this.logRequest, function *(next) {
|
||||
this.response.body = 'the_request_that_has_not_be_replaced';
|
||||
});
|
||||
|
||||
router.get('/test/new_replace_option', this.logRequest, function *(next) {
|
||||
this.response.body = 'the_new_replaced_option_page_content';
|
||||
});
|
||||
|
||||
router.get('/test/normal_request1', this.logRequest, koaBody(), function *(next) {
|
||||
printLog('requesting get /test/normal_request1');
|
||||
this.response.body = 'body_normal_request1';
|
||||
});
|
||||
|
||||
router.get('/test/normal_request2', this.logRequest, koaBody(), function *(next) {
|
||||
printLog('requesting get /test/normal_request2');
|
||||
this.response.body = 'body_normal_request2';
|
||||
});
|
||||
|
||||
router.post('/test/normal_post_request1', koaBody(), this.logRequest, function *(next) {
|
||||
printLog('requesting post /test/normal_post_request1');
|
||||
this.response.body = 'body_normal_post_request1';
|
||||
});
|
||||
|
||||
router.get('/big_response', this.logRequest, function *(next) {
|
||||
const buf = new Buffer(1 * 1024 * 1024 * 1024); // 1GB
|
||||
buf.fill(1);
|
||||
printLog('request in get big response of 1GB');
|
||||
this.response.type = 'application/octet-stream';
|
||||
this.response.body = buf;
|
||||
});
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
KoaServer.prototype.constructWsRouter = function() {
|
||||
const wsRouter = KoaRouter();
|
||||
const self = this;
|
||||
wsRouter.get('/test/socket', function*(next) {
|
||||
const ws = this.websocket;
|
||||
const messageObj = {
|
||||
type: 'initial',
|
||||
content: 'default message'
|
||||
};
|
||||
KoaServer.prototype.constructWsRouter = function () {
|
||||
const wsRouter = KoaRouter();
|
||||
const self = this;
|
||||
wsRouter.get('/test/socket', function *(next) {
|
||||
const ws = this.websocket;
|
||||
const messageObj = {
|
||||
type: 'initial',
|
||||
content: 'default message'
|
||||
};
|
||||
|
||||
ws.send(JSON.stringify(messageObj));
|
||||
ws.on('message', message => {
|
||||
printLog('message from request socket: ' + message);
|
||||
self.handleRecievedMessage(ws, message);
|
||||
});
|
||||
yield next;
|
||||
ws.send(JSON.stringify(messageObj));
|
||||
ws.on('message', message => {
|
||||
printLog('message from request socket: ' + message);
|
||||
self.handleRecievedMessage(ws, message);
|
||||
});
|
||||
yield next;
|
||||
});
|
||||
|
||||
return wsRouter;
|
||||
return wsRouter;
|
||||
};
|
||||
|
||||
KoaServer.prototype.getRequestRecord = function (key) {
|
||||
return this.requestRecordMap[key] || {};
|
||||
return this.requestRecordMap[key] || null;
|
||||
};
|
||||
|
||||
KoaServer.prototype.getProxyRequestRecord = function (key) {
|
||||
key = PROXY_KEY_PREFIX + key;
|
||||
return this.requestRecordMap[key] || {};
|
||||
key = PROXY_KEY_PREFIX + key;
|
||||
return this.requestRecordMap[key] || null;
|
||||
};
|
||||
|
||||
KoaServer.prototype.handleRecievedMessage = function(ws, message) {
|
||||
const newMessage = {
|
||||
type: 'onMessage',
|
||||
content: message
|
||||
};
|
||||
ws.send(JSON.stringify(newMessage));
|
||||
KoaServer.prototype.handleRecievedMessage = function (ws, message) {
|
||||
const newMessage = {
|
||||
type: 'onMessage',
|
||||
content: message
|
||||
};
|
||||
ws.send(JSON.stringify(newMessage));
|
||||
};
|
||||
|
||||
KoaServer.prototype.start = function() {
|
||||
printLog('Starting the server...');
|
||||
const router = this.constructRouter();
|
||||
const wsRouter = this.constructWsRouter();
|
||||
const self = this;
|
||||
const app = Koa();
|
||||
websocket(app);
|
||||
KoaServer.prototype.start = function () {
|
||||
printLog('Starting the server...');
|
||||
const router = this.constructRouter();
|
||||
const wsRouter = this.constructWsRouter();
|
||||
const self = this;
|
||||
const app = Koa();
|
||||
websocket(app);
|
||||
|
||||
app.use(router.routes());
|
||||
app.ws.use(wsRouter.routes());
|
||||
this.httpServer = app.listen(DEFAULT_PORT);
|
||||
app.use(router.routes());
|
||||
app.ws.use(wsRouter.routes());
|
||||
this.httpServer = app.listen(DEFAULT_PORT);
|
||||
|
||||
printLog('HTTP is now listening on port :' + DEFAULT_PORT);
|
||||
printLog('HTTP is now listening on port :' + DEFAULT_PORT);
|
||||
|
||||
certMgr.getCertificate('localhost', function(error, keyContent, crtContent) {
|
||||
if (error) {
|
||||
console.error('failed to create https server:', error);
|
||||
} else {
|
||||
self.httpsServer = https.createServer({
|
||||
key: keyContent,
|
||||
cert: crtContent
|
||||
}, app.callback());
|
||||
certMgr.getCertificate('localhost', (error, keyContent, crtContent) => {
|
||||
if (error) {
|
||||
console.error('failed to create https server:', error);
|
||||
} else {
|
||||
self.httpsServer = https.createServer({
|
||||
SNICallback: SNICertCallback,
|
||||
key: keyContent,
|
||||
cert: crtContent
|
||||
}, app.callback());
|
||||
|
||||
// create wss server
|
||||
const wss = new WebSocketServer({
|
||||
server: self.httpsServer
|
||||
});
|
||||
// create wss server
|
||||
const wss = new WebSocketServer({
|
||||
server: self.httpsServer
|
||||
});
|
||||
|
||||
wss.on('connection', function connection(ws) {
|
||||
ws.on('message', function incoming(message) {
|
||||
printLog('received in wss: ' + message);
|
||||
self.handleRecievedMessage(ws, message);
|
||||
});
|
||||
wss.on('connection', (ws) => {
|
||||
ws.on('message', (message) => {
|
||||
printLog('received in wss: ' + message);
|
||||
self.handleRecievedMessage(ws, message);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
wss.on('error', e => console.error('erro happened in wss:%s', error));
|
||||
|
||||
wss.on('error', error => {
|
||||
console.error('erro happened in wss:%s', error);
|
||||
});
|
||||
self.httpsServer.listen(HTTPS_PORT);
|
||||
|
||||
self.httpsServer.listen(HTTPS_PORT);
|
||||
self.httpsServer2 = https.createServer({
|
||||
key: keyContent,
|
||||
cert: crtContent
|
||||
}, app.callback());
|
||||
|
||||
printLog('HTTPS is now listening on port :' + HTTPS_PORT);
|
||||
self.httpsServer2.listen(HTTPS_PORT2);
|
||||
|
||||
printLog('Server started successfully');
|
||||
}
|
||||
});
|
||||
printLog('HTTPS is now listening on port :' + HTTPS_PORT);
|
||||
|
||||
return this;
|
||||
printLog('Server started successfully');
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
KoaServer.prototype.close = function() {
|
||||
printLog('Closing server now...');
|
||||
this.httpServer && this.httpServer.close();
|
||||
this.httpsServer && this.httpsServer.close();
|
||||
this.requestRecordMap = {};
|
||||
printLog('Server closed successfully');
|
||||
KoaServer.prototype.close = function () {
|
||||
printLog('Closing server now...');
|
||||
this.httpServer && this.httpServer.close();
|
||||
this.httpsServer && this.httpsServer.close();
|
||||
this.httpsServer2 && this.httpsServer2.close();
|
||||
this.requestRecordMap = {};
|
||||
printLog('Server closed successfully');
|
||||
};
|
||||
|
||||
|
||||
function printLog(content) {
|
||||
console.log(color.cyan('===SERVER LOG===' + content));
|
||||
console.log(color.cyan('[SERVER LOG]: ' + content));
|
||||
}
|
||||
|
||||
|
||||
module.exports = KoaServer;
|
||||
module.exports = KoaServer;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
const Server = require('./server.js');
|
||||
|
||||
new Server();
|
||||
new Server();
|
||||
|
||||
93
test/spec_lib/proxyServerModule.js
Normal file
93
test/spec_lib/proxyServerModule.js
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* test for rule replaceOption rule
|
||||
*
|
||||
*/
|
||||
const ip = require('ip');
|
||||
const AnyProxy = require('../../proxy');
|
||||
const { proxyGet, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
|
||||
const OUT_BOUND_IP = ip.address();
|
||||
|
||||
describe('AnyProxy.proxyServer basic test', () => {
|
||||
it('should successfully start a proxy server', done => {
|
||||
const options = {
|
||||
port: 8001,
|
||||
rule: null,
|
||||
webInterface: {
|
||||
enable: true,
|
||||
webPort: 8002,
|
||||
wsPort: 8003,
|
||||
},
|
||||
throttle: 10000,
|
||||
forceProxyHttps: false,
|
||||
silent: false
|
||||
};
|
||||
const proxyServer = new AnyProxy.ProxyServer(options);
|
||||
proxyServer.on('ready', () => {
|
||||
proxyServer.close();
|
||||
done();
|
||||
});
|
||||
proxyServer.on('error', done.fail);
|
||||
proxyServer.start();
|
||||
});
|
||||
});
|
||||
|
||||
describe('AnyProxy.proxyServer high order test', () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
beforeAll(done => {
|
||||
// jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
serverInstance = new Server();
|
||||
|
||||
const options = {
|
||||
port: 8001,
|
||||
rule: null,
|
||||
webInterface: {
|
||||
enable: true,
|
||||
webPort: 8002,
|
||||
},
|
||||
throttle: 10000,
|
||||
forceProxyHttps: false,
|
||||
silent: false
|
||||
};
|
||||
proxyServer = new AnyProxy.ProxyServer(options);
|
||||
proxyServer.on('ready', done);
|
||||
proxyServer.start();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
proxyServer && proxyServer.close();
|
||||
serverInstance && serverInstance.close();
|
||||
});
|
||||
|
||||
it('should work as expected for domain host', done => {
|
||||
// test if proxy server works
|
||||
proxyGet('https://www.tmall.com', {}, {})
|
||||
.then(res => {
|
||||
expect(res && res.statusCode && res.statusCode === 200 && res.body.length > 300).toBe(true);
|
||||
done();
|
||||
})
|
||||
.catch(done)
|
||||
});
|
||||
|
||||
it('should work as expected for ip host', done => {
|
||||
// test if proxy server works
|
||||
proxyGet(`https://${OUT_BOUND_IP}:3001/test`, {}, {})
|
||||
.then(res => {
|
||||
expect(res && res.statusCode && res.statusCode === 200).toBe(true);
|
||||
done();
|
||||
})
|
||||
.catch(done)
|
||||
});
|
||||
|
||||
it('should start webinterface correctly', done => {
|
||||
// test web interface
|
||||
directGet('http://127.0.0.1:8002', {}, {})
|
||||
.then(res => {
|
||||
expect(res && res.statusCode && res.statusCode === 200 && res.body.length > 300).toBe(true);
|
||||
done();
|
||||
})
|
||||
.catch(done)
|
||||
});
|
||||
});
|
||||
51
test/spec_lib/ruleLoader.js
Normal file
51
test/spec_lib/ruleLoader.js
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* test for rule replaceOption rule
|
||||
*
|
||||
*/
|
||||
|
||||
const ruleLoader = require('../../lib/ruleLoader');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const localModulePath = path.join(__dirname, '../util/CommonUtil.js');
|
||||
describe('rule loader', () => {
|
||||
it('should successfully cache a remote file', done => {
|
||||
ruleLoader.cacheRemoteFile('https://cdn.bootcss.com/lodash.js/4.16.4/lodash.min.js')
|
||||
.then(filePath => {
|
||||
let content;
|
||||
if (filePath) {
|
||||
content = fs.readFileSync(filePath, { encoding: 'utf8' });
|
||||
}
|
||||
expect(content && content.length > 100).toBe(true);
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('should load a local module ../util/CommonUtil', done => {
|
||||
ruleLoader.loadLocalPath(localModulePath)
|
||||
.then(module => {
|
||||
expect(module.printLog).not.toBeUndefined();
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('should smart load a remote module', done => {
|
||||
ruleLoader.requireModule('https://cdn.bootcss.com/lodash.js/4.16.4/lodash.min.js')
|
||||
.then(module => {
|
||||
expect(module.VERSION).toEqual('4.16.4');
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('should smart load a local module', done => {
|
||||
ruleLoader.requireModule(localModulePath)
|
||||
.then(module => {
|
||||
expect(module.printLog).not.toBeUndefined();
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
26
test/spec_lib/util.js
Normal file
26
test/spec_lib/util.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* test for rule replaceOption rule
|
||||
*
|
||||
*/
|
||||
const util = require('../../lib/util');
|
||||
|
||||
describe('utils', () => {
|
||||
it('should get some free ports', done => {
|
||||
const count = 100;
|
||||
const tasks = [];
|
||||
for (let i = 1; i <= count; i++) {
|
||||
tasks.push(util.getFreePort());
|
||||
}
|
||||
Promise.all(tasks)
|
||||
.then((results) => {
|
||||
// ensure ports are unique
|
||||
const portMap = {};
|
||||
results.map((portNumber) => {
|
||||
portMap[portNumber] = true;
|
||||
});
|
||||
expect(Object.keys(portMap).length).toEqual(count);
|
||||
done();
|
||||
})
|
||||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
147
test/spec_outweb/test_realweb_spec.js
Normal file
147
test/spec_outweb/test_realweb_spec.js
Normal file
@@ -0,0 +1,147 @@
|
||||
|
||||
/**
|
||||
* use phantomjs to capture requests in real websites, then compare the directly-connected response with those through AnyProxy
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const HttpUtil = require('../util/HttpUtil.js');
|
||||
const path = require('path');
|
||||
const { printLog, printError, printHilite, stringSimilarity } = require('../util/CommonUtil.js');
|
||||
|
||||
const reportPath = path.join(__dirname, '../report/');
|
||||
|
||||
const testUrls = ['https://www.taobao.com', 'https://www.baidu.com', 'https://www.tmall.com'];
|
||||
|
||||
let direcrtResponseSampleA = [];
|
||||
let direcrtResponseSampleB = [];
|
||||
let proxyResponse = [];
|
||||
|
||||
function test(url, requestHeaders = {}) {
|
||||
fdescribe('Test requests in real broswer', () => {
|
||||
let proxyServer;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for ' + url);
|
||||
|
||||
proxyServer = ProxyServerUtil.defaultProxyServer();
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for ' + url);
|
||||
});
|
||||
|
||||
it(`Request towards ${url}`, (done) => {
|
||||
HttpUtil.getRequestListFromPage(url).then((arr) => {
|
||||
const directPromisesA = [];
|
||||
const directPromisesB = [];
|
||||
const proxyPromises = [];
|
||||
arr.forEach((data, i) => {
|
||||
const requestPath = data.url;
|
||||
const headers = data.headers;
|
||||
const method = data.method;
|
||||
const params = data.method === 'POST' ? JSON.parse(data.postData) : {};
|
||||
if (HttpUtil.isSupportedProtocol(requestPath)) {
|
||||
directPromisesA.push(HttpUtil.directRequest(method, requestPath, params, headers));
|
||||
directPromisesB.push(HttpUtil.directRequest(method, requestPath, params, headers));
|
||||
proxyPromises.push(HttpUtil.proxyRequest(method, requestPath, params, headers));
|
||||
}
|
||||
});
|
||||
Promise.all(directPromisesA).then(responseArr => { direcrtResponseSampleA = responseArr }).then(() => {
|
||||
Promise.all(directPromisesB).then(responseArr => { direcrtResponseSampleB = responseArr }).then(() => {
|
||||
Promise.all(proxyPromises).then(responseArr => { proxyResponse = responseArr }).then(() => {
|
||||
showResponseResult();
|
||||
const { compareResult: TESTRESULT, errRecord } = compareResponses(url);
|
||||
const reportFile = dealLogFile(errRecord, url, () => {
|
||||
printHilite('====== COMPARE RESULT: ' + TESTRESULT.toString().toUpperCase() + ' ======');
|
||||
!TESTRESULT && printHilite(`Check more details in ${reportFile}`);
|
||||
// expect(TESTRESULT).toBe(true);
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
printError(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
printError(err);
|
||||
done();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
printError(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function compareResponses(curUrl) {
|
||||
const errRecord = [];
|
||||
if (direcrtResponseSampleA.length !== direcrtResponseSampleB.length || direcrtResponseSampleA.length !== proxyResponse.length) {
|
||||
printError('compare fail: length not match');
|
||||
return {
|
||||
compareResult: false,
|
||||
errRecord
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < proxyResponse.length; i++) {
|
||||
const direcrtResponseInfoA = direcrtResponseSampleA[i];
|
||||
const direcrtResponseInfoB = direcrtResponseSampleB[i];
|
||||
const proxyResponseInfo = proxyResponse[i];
|
||||
const { similarity: similarity_direct } = stringSimilarity(stringify(direcrtResponseInfoA.body), stringify(direcrtResponseInfoB.body));
|
||||
const { similarity: similarity_proxy } = stringSimilarity(stringify(direcrtResponseInfoA.body), stringify(proxyResponseInfo.body));
|
||||
if (similarity_direct !== similarity_proxy) {
|
||||
let LogText = `Similarity from ${proxyResponseInfo.request.href} between direct samples and proxy is not equal : ${similarity_direct} | ${similarity_proxy}\n`;
|
||||
printError(LogText);
|
||||
LogText += `\n${stringify(direcrtResponseInfoA.body)}`;
|
||||
LogText += '\n=============================================\n';
|
||||
LogText += `${stringify(direcrtResponseInfoB.body)}`;
|
||||
LogText += '\n=============================================\n';
|
||||
LogText += `${stringify(proxyResponseInfo.body)}\n\n`;
|
||||
errRecord.push(LogText);
|
||||
}
|
||||
}
|
||||
return {
|
||||
compareResult: errRecord.length === 0,
|
||||
errRecord
|
||||
};
|
||||
}
|
||||
|
||||
function stringify(data) {
|
||||
return data ? data.replace(/\s+/g, '') : '';
|
||||
}
|
||||
|
||||
function showResponseResult() {
|
||||
if (direcrtResponseSampleA.length !== direcrtResponseSampleB.length || direcrtResponseSampleA.length !== proxyResponse.length) {
|
||||
printError('compare fail: length not match');
|
||||
}
|
||||
proxyResponse.forEach((dataObj, i) => {
|
||||
const direcrtResponseInfoA = direcrtResponseSampleA[i];
|
||||
const direcrtResponseInfoB = direcrtResponseSampleB[i];
|
||||
printLog(`Direct Sample A ${direcrtResponseInfoA.request.method}: ${direcrtResponseInfoA.request.href} ${direcrtResponseInfoA.statusCode}${direcrtResponseInfoA.statusMessage}`);
|
||||
printLog(`Direct Sample B ${direcrtResponseInfoB.request.method}: ${direcrtResponseInfoB.request.href} ${direcrtResponseInfoB.statusCode}${direcrtResponseInfoB.statusMessage}`);
|
||||
printLog(`PROXY ${dataObj.request.method}: ${dataObj.request.href} ${dataObj.statusCode}${dataObj.statusMessage}`);
|
||||
})
|
||||
console.log('\n');
|
||||
}
|
||||
|
||||
function dealLogFile(dataObj = 'Log', url, cb) {
|
||||
const filePath = reportPath + url.replace(/[^\u4E00-\u9FA5A-Za-z\s()()\d•·]/g, '_') + '.txt';
|
||||
fs.writeFile(filePath, dataObj, (err) => {
|
||||
if (err) throw err;
|
||||
console.log('Log is saved!');
|
||||
cb && cb();
|
||||
});
|
||||
return filePath;
|
||||
}
|
||||
|
||||
testUrls.forEach((link) => {
|
||||
test(link);
|
||||
});
|
||||
42
test/spec_rule/no_rule_big_response_spec.js
Normal file
42
test/spec_rule/no_rule_big_response_spec.js
Normal file
@@ -0,0 +1,42 @@
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
const spawn = require('child_process').spawn;
|
||||
const Server = require('../server/server.js');
|
||||
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
|
||||
describe('Test request with big body', () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for no_rule_big_response');
|
||||
|
||||
serverInstance = new Server();
|
||||
proxyServer = ProxyServerUtil.defaultProxyServer();
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for no_rule_spec');
|
||||
});
|
||||
|
||||
it('should successfully get file', (done) => {
|
||||
const isWin = /^win/.test(process.platform);
|
||||
if (isWin) {
|
||||
done();
|
||||
} else {
|
||||
const curl = spawn('curl', ['http://localhost:3000/big_response', '--proxy', 'http://127.0.0.1:8001', '-o', '/dev/null']);
|
||||
curl.on('close', (code) => {
|
||||
expect(code).toEqual(0);
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
400
test/spec_rule/no_rule_spec.js
Normal file
400
test/spec_rule/no_rule_spec.js
Normal file
@@ -0,0 +1,400 @@
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const Server = require('../server/server.js');
|
||||
const
|
||||
{
|
||||
proxyGet,
|
||||
proxyPost,
|
||||
directGet,
|
||||
directPost,
|
||||
directUpload,
|
||||
proxyUpload,
|
||||
generateUrl,
|
||||
proxyPut,
|
||||
directPut,
|
||||
proxyDelete,
|
||||
directDelete,
|
||||
directHead,
|
||||
proxyHead,
|
||||
directOptions,
|
||||
proxyOptions,
|
||||
proxyPutUpload,
|
||||
directPutUpload
|
||||
} = require('../util/HttpUtil.js');
|
||||
const { CommonRequestHeader } = require('../data/headers.js');
|
||||
const { isCommonResHeaderEqual, isCommonReqEqual, printLog } = require('../util/CommonUtil.js');
|
||||
const streamEqual = require('stream-equal');
|
||||
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
|
||||
testRequest('http');
|
||||
testRequest('https');
|
||||
|
||||
// Test suites for http and https request
|
||||
function testRequest(protocol = 'http') {
|
||||
function constructUrl(urlPath) {
|
||||
return generateUrl(protocol, urlPath);
|
||||
}
|
||||
|
||||
describe('Test request without proxy rules in protocol ' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for no_rule_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
proxyServer = ProxyServerUtil.defaultProxyServer();
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for no_rule_spec');
|
||||
});
|
||||
|
||||
|
||||
it('Get should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test');
|
||||
const getParam = {
|
||||
param: 'nothing'
|
||||
};
|
||||
|
||||
proxyGet(url, getParam, CommonRequestHeader).then((proxyRes) => {
|
||||
directGet(url, getParam, CommonRequestHeader).then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happend in direct get:', error);
|
||||
done.fail('error happend in direct get');
|
||||
});
|
||||
}, error => {
|
||||
console.log('error happened in proxy get:', error);
|
||||
done.fail('error happend in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Post should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/getuser');
|
||||
const param = {
|
||||
param: 'postnothing'
|
||||
};
|
||||
|
||||
proxyPost(url, param, CommonRequestHeader).then(proxyRes => {
|
||||
directPost(url, param, CommonRequestHeader).then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in direct post:', error);
|
||||
done.fail('error happend in direct post');
|
||||
});
|
||||
}, error => {
|
||||
console.log('error happened in proxy post,', error);
|
||||
done.fail('error happend in proxy post');
|
||||
});
|
||||
});
|
||||
|
||||
it('PUT should work as direct without proxy rules', done => {
|
||||
const url = constructUrl('/test/put');
|
||||
const param = {
|
||||
param: 'putsomething'
|
||||
};
|
||||
proxyPut(url, param, CommonRequestHeader).then(proxyRes => {
|
||||
directPut(url, param, CommonRequestHeader).then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct put', error);
|
||||
done.fail('error happened in direct put');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy put', error);
|
||||
done.fail('error happened in proxy put');
|
||||
});
|
||||
});
|
||||
|
||||
it('DELETE rquest should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/delete/123456');
|
||||
|
||||
proxyDelete(url, {}, CommonRequestHeader).then(proxyRes => {
|
||||
directDelete(url, {}, CommonRequestHeader).then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct delete :', error);
|
||||
done.fail('error happened in direct delete');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy delete :', error);
|
||||
done.fail('error happened in proxy delete');
|
||||
});
|
||||
});
|
||||
|
||||
it('HEAD request should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/head');
|
||||
|
||||
proxyHead(url, CommonRequestHeader)
|
||||
.then(proxyRes => {
|
||||
directHead(url, CommonRequestHeader)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('');
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct head request:', error);
|
||||
done.fail('error happened in direct head request');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy head request:', error);
|
||||
done.fail('error happened in proxy head request');
|
||||
});
|
||||
});
|
||||
|
||||
it('OPTIONS request should work as direct without proxy rules', (done) => {
|
||||
const url = constructUrl('/test/options');
|
||||
|
||||
proxyOptions(url, CommonRequestHeader)
|
||||
.then(proxyRes => {
|
||||
directOptions(url, CommonRequestHeader)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('could_be_empty');
|
||||
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in direct options request:', error);
|
||||
done.fail('error happened in direct options request');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error happened in proxy options request:', error);
|
||||
done.fail('error happened in proxy options request');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Response code should be honored as direct without proxy rules', () => {
|
||||
[301, 302, 303].forEach(code => {
|
||||
testRedirect(code);
|
||||
});
|
||||
|
||||
function testRedirect(redirectCode) {
|
||||
it(`${redirectCode} response should work as direct without proxy rules`, (done) => {
|
||||
const url = constructUrl(`/test/response/${redirectCode}`);
|
||||
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(redirectCode);
|
||||
expect(directRes.headers.location).toEqual(proxyRes.headers.location);
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(directRes.headers.location).toEqual('/test');
|
||||
done();
|
||||
}).catch(error => {
|
||||
console.log(`error happened in direct ${redirectCode}:`, error);
|
||||
done.fail(`error happened in direct ${redirectCode}`);
|
||||
});
|
||||
}).catch(error => {
|
||||
console.log(`error happened in proxy ${redirectCode}:`, error);
|
||||
done.fail(`error happened in proxy ${redirectCode}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Test file download ', () => {
|
||||
const testArray = [
|
||||
{
|
||||
url: constructUrl('/test/download/png'),
|
||||
type: 'png',
|
||||
contentType: 'image/png'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/webp'),
|
||||
type: 'WEBP',
|
||||
contentType: 'image/webp'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/json'),
|
||||
type: 'JSON',
|
||||
contentType: 'application/json; charset=utf-8'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/css'),
|
||||
type: 'CSS',
|
||||
contentType: 'text/css; charset=utf-8'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/ttf'),
|
||||
type: 'TTF',
|
||||
contentType: 'application/x-font-ttf'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/eot'),
|
||||
type: 'EOT',
|
||||
contentType: 'application/vnd.ms-fontobject'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/svg'),
|
||||
type: 'SVG',
|
||||
contentType: 'image/svg+xml'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/woff'),
|
||||
type: 'WOFF',
|
||||
contentType: 'application/font-woff'
|
||||
},
|
||||
{
|
||||
url: constructUrl('/test/download/woff2'),
|
||||
type: 'WOFF2',
|
||||
contentType: 'application/font-woff2'
|
||||
}
|
||||
];
|
||||
|
||||
testArray.forEach(item => {
|
||||
testFileDownload(item.url, item.type, item.contentType);
|
||||
});
|
||||
|
||||
// 封装测试文件下载的测试工具类
|
||||
function testFileDownload(url, filetype, contentType) {
|
||||
const describe = `${filetype} file download without rules should be work as direct download`;
|
||||
const param = {};
|
||||
|
||||
it(describe, (done) => {
|
||||
proxyGet(url, param).then(proxyRes => {
|
||||
directGet(url, param).then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
expect(proxyRes.body).toEqual(directRes.body);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in direct get :', filetype, error);
|
||||
done.fail(`error happend in direct get ${filetype}`);
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy get :', filetype, error);
|
||||
done.fail(`error happend in proxy get ${filetype}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Test file upload', () => {
|
||||
const formParams = {
|
||||
param1: 'param_1',
|
||||
param2: 'param2'
|
||||
};
|
||||
it('POST upload should be working', (done) => {
|
||||
const url = constructUrl('/test/upload/png');
|
||||
const filePath = path.resolve(__dirname, '../data/test.png');
|
||||
|
||||
proxyUpload(url, filePath, formParams)
|
||||
.then(proxyRes => {
|
||||
directUpload(url, filePath, formParams)
|
||||
.then((directRes) => {
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
expect(isCommonReqEqual(url, serverInstance)).toBe(true);
|
||||
assertReponse(proxyRes, directRes, filePath, done);
|
||||
}, error => {
|
||||
console.error('error in direct upload:', error);
|
||||
done.fail('error in direct upload');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy upload:', error);
|
||||
done.fail('error in proxy upload:');
|
||||
});
|
||||
});
|
||||
|
||||
it('PUT upload should be working', (done) => {
|
||||
const url = constructUrl('/test/upload/putpng');
|
||||
const filePath = path.resolve(__dirname, '../data/test.png');
|
||||
proxyPutUpload(url, filePath, formParams)
|
||||
.then(proxyRes => {
|
||||
directPutUpload(url, filePath, formParams)
|
||||
.then((directRes) => {
|
||||
expect(isCommonResHeaderEqual(directRes.headers, proxyRes.headers, url)).toBe(true);
|
||||
|
||||
assertReponse(proxyRes, directRes, filePath, done);
|
||||
}, error => {
|
||||
console.error('error in direct upload:', error);
|
||||
done.fail('error in direct upload');
|
||||
});
|
||||
}, error => {
|
||||
console.error('error in proxy upload:', error);
|
||||
done.fail('error in proxy upload:');
|
||||
});
|
||||
});
|
||||
|
||||
function assertReponse(proxyRes, directRes, originFilePath, done) {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(proxyRes.statusCode).toEqual(directRes.statusCode);
|
||||
// expect(proxyRes.headers.reqbody).toEqual(directRes.headers.reqbody);
|
||||
|
||||
// the body will be the file path
|
||||
const directUploadedStream = fs.createReadStream(directRes.body);
|
||||
const proxyUploadedStream = fs.createReadStream(proxyRes.body);
|
||||
const localFileStream = fs.createReadStream(originFilePath);
|
||||
streamEqual(directUploadedStream, localFileStream)
|
||||
.then(isLocalEqual => {
|
||||
expect(isLocalEqual).toBe(true);
|
||||
streamEqual(directUploadedStream, proxyUploadedStream)
|
||||
.then(isUploadedEqual => {
|
||||
expect(isUploadedEqual).toBe(true);
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in comparing directUpload with proxy:\n', error);
|
||||
done.fail('error in comparing directUpload with proxy');
|
||||
});
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error in comparing directUpload with local:\n', error);
|
||||
done.fail('error in comparing directUpload with local');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
140
test/spec_rule/no_rule_websocket_spec.js
Normal file
140
test/spec_rule/no_rule_websocket_spec.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Test suites for WebSocket.
|
||||
* ONLY TO ENSURE THE REQUEST WILL BE BYPASSED SUCCESSFULLY, WE HAVEN'T SUPPORTTED WEBSOCKET YET.
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { generateWsUrl, directWs, proxyWs } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
testWebsocket('ws');
|
||||
testWebsocket('wss');
|
||||
|
||||
function testWebsocket(protocol) {
|
||||
describe('Test WebSocket in protocol : ' + protocol, () => {
|
||||
const url = generateWsUrl(protocol, '/test/socket');
|
||||
let serverInstance;
|
||||
let proxyServer;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 200000;
|
||||
printLog('Start server for no_rule_websocket_spec');
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithoutHttpsIntercept();
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Closed server for no_rule_websocket_spec');
|
||||
});
|
||||
|
||||
it('Default websocket option', done => {
|
||||
const sendMessage = 'Send the message with default option';
|
||||
let directMessage; // set the flag for direct message, compare when both direct and proxy got message
|
||||
let proxyMessage;
|
||||
|
||||
const ws = directWs(url);
|
||||
const porxyWsRef = proxyWs(url);
|
||||
ws.on('open', () => {
|
||||
ws.send(sendMessage);
|
||||
});
|
||||
|
||||
porxyWsRef.on('open', () => {
|
||||
porxyWsRef.send(sendMessage);
|
||||
});
|
||||
|
||||
ws.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
directMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
porxyWsRef.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
proxyMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', error => {
|
||||
console.error('error happened in direct websocket:', error);
|
||||
done.fail('Error happened in direct websocket');
|
||||
});
|
||||
|
||||
porxyWsRef.on('error', error => {
|
||||
console.error('error happened in proxy websocket:', error);
|
||||
done.fail('Error happened in proxy websocket');
|
||||
});
|
||||
|
||||
function compareMessageIfReady() {
|
||||
if (directMessage && proxyMessage) {
|
||||
expect(directMessage).toEqual(proxyMessage);
|
||||
expect(directMessage).toEqual(sendMessage);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('masked:true', done => {
|
||||
const sendMessage = 'Send the message with option masked:true';
|
||||
let directMessage; // set the flag for direct message, compare when both direct and proxy got message
|
||||
let proxyMessage;
|
||||
|
||||
const ws = directWs(url);
|
||||
const porxyWsRef = proxyWs(url);
|
||||
ws.on('open', () => {
|
||||
ws.send(sendMessage, { masked: true });
|
||||
});
|
||||
|
||||
porxyWsRef.on('open', () => {
|
||||
porxyWsRef.send(sendMessage, { masked: true });
|
||||
});
|
||||
|
||||
ws.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
directMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
porxyWsRef.on('message', (data, flag) => {
|
||||
const message = JSON.parse(data);
|
||||
if (message.type === 'onMessage') {
|
||||
proxyMessage = message.content;
|
||||
compareMessageIfReady();
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('error', error => {
|
||||
console.error('error happened in direct websocket:', error);
|
||||
done.fail('Error happened in direct websocket');
|
||||
});
|
||||
|
||||
porxyWsRef.on('error', error => {
|
||||
console.error('error happened in proxy websocket:', error);
|
||||
|
||||
done.fail('Error happened in proxy websocket');
|
||||
});
|
||||
|
||||
function compareMessageIfReady() {
|
||||
if (directMessage && proxyMessage) {
|
||||
expect(directMessage).toEqual(proxyMessage);
|
||||
expect(directMessage).toEqual(sendMessage);
|
||||
done();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
22
test/spec_rule/rule/rule_replace_request_data.js
Normal file
22
test/spec_rule/rule/rule_replace_request_data.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* add authToken parameter to the request data
|
||||
*
|
||||
*/
|
||||
module.exports = {
|
||||
*beforeSendRequest(requestDetail) {
|
||||
if (requestDetail.url.indexOf('/getuser') >= 0) {
|
||||
let requestStr = requestDetail.requestData.toString();
|
||||
try {
|
||||
requestStr = JSON.stringify(Object.assign(JSON.parse(requestStr), {
|
||||
authToken: 'auth_token_inrule'
|
||||
}))
|
||||
} catch (e) {
|
||||
requestStr += '&authToken=auth_token_inrule';
|
||||
}
|
||||
return {
|
||||
requestOptions: requestDetail.requestOptions,
|
||||
requestData: requestStr
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
13
test/spec_rule/rule/rule_replace_request_option.js
Normal file
13
test/spec_rule/rule/rule_replace_request_option.js
Normal file
@@ -0,0 +1,13 @@
|
||||
//rule scheme :
|
||||
module.exports = {
|
||||
|
||||
*beforeSendRequest(requestDetail) {
|
||||
const newOption = requestDetail.requestOptions;
|
||||
if (newOption.hostname === 'localhost' && newOption.path === '/test/should_replace_option') {
|
||||
newOption.path = '/test/new_replace_option';
|
||||
return {
|
||||
requestOptions: newOption
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
15
test/spec_rule/rule/rule_replace_request_protocol.js
Normal file
15
test/spec_rule/rule/rule_replace_request_protocol.js
Normal file
@@ -0,0 +1,15 @@
|
||||
//rule scheme :
|
||||
module.exports = {
|
||||
*summary() {
|
||||
return 'The rule to replace request protocol';
|
||||
},
|
||||
|
||||
*beforeSendRequest(requestDetail) {
|
||||
const newConfig = {
|
||||
protocol: 'http',
|
||||
requestOptions: requestDetail.requestOptions
|
||||
};
|
||||
newConfig.requestOptions.port = 3000;
|
||||
return newConfig;
|
||||
}
|
||||
};
|
||||
17
test/spec_rule/rule/rule_replace_response_data.js
Normal file
17
test/spec_rule/rule/rule_replace_response_data.js
Normal file
@@ -0,0 +1,17 @@
|
||||
//rule scheme : replace the reponse data
|
||||
|
||||
module.exports = {
|
||||
|
||||
*beforeSendResponse(requestDetail, responseDetail) {
|
||||
if (requestDetail.url.indexOf('/test/normal_request1') > -1) {
|
||||
const newResponse = responseDetail.response;
|
||||
|
||||
const newDataStr = newResponse.body.toString() + '_hello_world!';
|
||||
newResponse.body = newDataStr;
|
||||
|
||||
return {
|
||||
response: newResponse
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
30
test/spec_rule/rule/rule_replace_response_header.js
Normal file
30
test/spec_rule/rule/rule_replace_response_header.js
Normal file
@@ -0,0 +1,30 @@
|
||||
//rule scheme : remove the cache headers in response headers
|
||||
module.exports = {
|
||||
*summary() {
|
||||
return 'The rule to remove the cache headers in response';
|
||||
},
|
||||
|
||||
*beforeSendResponse(requestDetail, responseDetail) {
|
||||
if (requestDetail.url.indexOf('/test/normal_request1') >= 0) {
|
||||
const newResponse = responseDetail.response;
|
||||
newResponse.header.replacedheaderkey = 'replacedHeader_value_in_rule';
|
||||
|
||||
return {
|
||||
response: newResponse
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// replaceResponseHeader(req, res, header) {
|
||||
// const d = Q.defer();
|
||||
|
||||
// header = Object.assign({}, header);
|
||||
// if (req.url.indexOf('test/normal_request1') > -1) {
|
||||
// header.replacedheaderkey = 'replacedHeader_value_in_rule';
|
||||
// }
|
||||
|
||||
// d.resolve(header);
|
||||
|
||||
// return d.promise;
|
||||
// }
|
||||
};
|
||||
20
test/spec_rule/rule/rule_replace_response_status_code.js
Normal file
20
test/spec_rule/rule/rule_replace_response_status_code.js
Normal file
@@ -0,0 +1,20 @@
|
||||
//replace all the images with local one
|
||||
module.exports = {
|
||||
|
||||
*summary() {
|
||||
return 'replace the response status code.';
|
||||
},
|
||||
|
||||
*beforeSendResponse(requestDetail, responseDetail) {
|
||||
if (requestDetail.url.indexOf('/test/normal_request1') >= 0) {
|
||||
const newResponse = responseDetail.response;
|
||||
newResponse.statusCode = 302;
|
||||
newResponse.header.location = 'www.taobao.com';
|
||||
|
||||
return {
|
||||
response: newResponse
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
19
test/spec_rule/rule/rule_should_intercept_https_req.js
Normal file
19
test/spec_rule/rule/rule_should_intercept_https_req.js
Normal file
@@ -0,0 +1,19 @@
|
||||
//rule scheme :
|
||||
|
||||
module.exports = {
|
||||
*summary() {
|
||||
return 'Rule to intercept https request';
|
||||
},
|
||||
|
||||
*beforeSendResponse(requestDetail, responseDetail) {
|
||||
const newResponse = responseDetail.response;
|
||||
newResponse.body = newResponse.body.toString() + '_hello_world';
|
||||
return {
|
||||
response: newResponse
|
||||
};
|
||||
},
|
||||
|
||||
*beforeDealHttpsRequest(requestDetail) {
|
||||
return requestDetail.host.indexOf('localhost:3001') > -1;
|
||||
}
|
||||
};
|
||||
21
test/spec_rule/rule/rule_should_use_local_response.js
Normal file
21
test/spec_rule/rule/rule_should_use_local_response.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Rule defination for shouldUseLocalResponse
|
||||
*
|
||||
*/
|
||||
const localData = 'handled_in_local_response';
|
||||
|
||||
module.exports = {
|
||||
*beforeSendRequest(requestDetail) {
|
||||
if (requestDetail.url.indexOf('uselocal') > -1) {
|
||||
return {
|
||||
response: {
|
||||
statusCode: 200,
|
||||
header: {
|
||||
'Via-Proxy-Local': 'true'
|
||||
},
|
||||
body: localData
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
154
test/spec_rule/rule_deal_error_spec.js
Normal file
154
test/spec_rule/rule_deal_error_spec.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* test for rule replaceResponseStatus rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet } = require('../util/HttpUtil.js');
|
||||
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
let errorInRule = null;
|
||||
const ruleNotDealError = {
|
||||
*onError(requestDetail, error) {
|
||||
errorInRule = error;
|
||||
}
|
||||
};
|
||||
|
||||
let errorInConnect = null;
|
||||
const ruleDealConnectError = {
|
||||
*onConnectError(requestDetail, error) {
|
||||
errorInConnect = error;
|
||||
}
|
||||
};
|
||||
|
||||
const ERROR_PAGE_IN_RULE = 'this is my error page';
|
||||
const ruleReturnAnErrorPage = {
|
||||
*onError(requestDetail, error) {
|
||||
return {
|
||||
response: {
|
||||
statusCode: '200',
|
||||
header: {},
|
||||
body: ERROR_PAGE_IN_RULE,
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
testHttpsConnect();
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule should get an error in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
// let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_deal_error_spec');
|
||||
errorInRule = null;
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(ruleNotDealError);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_deal_error_spec');
|
||||
});
|
||||
|
||||
it('Should get a request error', done => {
|
||||
const url = protocol + '://not_exist_url.anyproxy.io';
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(500);
|
||||
expect(proxyRes.headers['proxy-error']).toEqual('true');
|
||||
expect(errorInRule).not.toBe(null);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rule should return a custom error page in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
// let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_deal_error_custom_error_page');
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(ruleReturnAnErrorPage);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
// serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_deal_error_custom_error_page');
|
||||
});
|
||||
|
||||
it('Should get a request error', done => {
|
||||
const url = protocol + '://not_exist_url.anyproxy.io';
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.headers['proxy-error']).toBe(undefined);
|
||||
expect(proxyRes.body).toEqual(ERROR_PAGE_IN_RULE);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testHttpsConnect() {
|
||||
describe('Rule should get a connect error', () => {
|
||||
let proxyServer;
|
||||
// let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
errorInConnect = null;
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_deal_error_custom_error_page');
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(ruleDealConnectError, {
|
||||
forceProxyHttps: false
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_deal_error_custom_error_page');
|
||||
});
|
||||
|
||||
it('Should get a request error', done => {
|
||||
const url = 'https://not_exist_url.anyproxy.io';
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
done.fail('should throw an error when requesting');
|
||||
})
|
||||
.catch(error => {
|
||||
expect(errorInConnect).not.toBe(null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
120
test/spec_rule/rule_replace_request_data_spec.js
Normal file
120
test/spec_rule/rule_replace_request_data_spec.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* test for rule replaceRequestData rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyPost, generateUrl, directPost, isViaProxy } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog, isObjectEqual } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_request_data.js');
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule replaceRequestData should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_request_data_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_request_data_spec');
|
||||
});
|
||||
|
||||
it('Should replace the request data in proxy if the assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/getuser');
|
||||
const userName = 'username_test';
|
||||
const param = {
|
||||
username: userName
|
||||
};
|
||||
|
||||
proxyPost(url, param)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('body_post_getuser');
|
||||
const proxyRequest = serverInstance.getProxyRequestRecord(url);
|
||||
const proxyReqBodyObj = JSON.parse(proxyRequest.body.toString());
|
||||
|
||||
expect(isViaProxy(proxyRequest)).toBe(true);
|
||||
|
||||
expect(proxyReqBodyObj.username).toEqual(userName);
|
||||
expect(proxyReqBodyObj.authToken).toEqual('auth_token_inrule');
|
||||
|
||||
directPost(url, param)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
|
||||
|
||||
const directRequest = serverInstance.getRequestRecord(url);
|
||||
const directReqBodyObj = JSON.parse(directRequest.body.toString());
|
||||
expect(isViaProxy(directRequest)).toBe(false);
|
||||
|
||||
expect(directReqBodyObj.username).toEqual(userName);
|
||||
expect(directReqBodyObj.authToken).toBeUndefined();
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct post: ', error);
|
||||
done.fail('error happened in direct post');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy post: ', error);
|
||||
console.error(error);
|
||||
console.error(error.stack);
|
||||
done.fail('error happened in proxy post');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace the request data in proxy if the assertion is false', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_post_request1');
|
||||
const userName = 'normal_username_test';
|
||||
|
||||
const param = {
|
||||
username: userName
|
||||
};
|
||||
|
||||
proxyPost(url, param)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('body_normal_post_request1');
|
||||
const proxyReqRecord = serverInstance.getProxyRequestRecord(url);
|
||||
const proxyReqBody = JSON.parse(proxyReqRecord.body);
|
||||
expect(isObjectEqual(proxyReqBody, param, url)).toBe(true);
|
||||
|
||||
directPost(url, param)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(proxyRes.statusCode);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
const directReqRecord = serverInstance.getRequestRecord(url);
|
||||
const directReqBody = JSON.parse(directReqRecord.body);
|
||||
expect(isObjectEqual(directReqBody, proxyReqBody, url)).toBe(true);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct post:', error);
|
||||
done.fail('error happened in direct post');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy post:', error);
|
||||
done.fail('error happened in proxy post');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
89
test/spec_rule/rule_replace_request_option_spec.js
Normal file
89
test/spec_rule/rule_replace_request_option_spec.js
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* test for rule replaceOption rule
|
||||
*
|
||||
*/
|
||||
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_request_option.js');
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule replaceRequestOption should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll(done => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_request_option_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_request_option_spec');
|
||||
});
|
||||
|
||||
it('Should replace request option if the assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/should_replace_option');
|
||||
const replacedUrl = generateUrl(protocol, '/test/new_replace_option');
|
||||
|
||||
const token = 'replacedOption' + Date.now();
|
||||
const directToken = 'notRepacedOption' + Date.now();
|
||||
proxyGet(url, {}, { token })
|
||||
.then(proxyRes => {
|
||||
directGet(url, {}, { token: directToken })
|
||||
.then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('the_new_replaced_option_page_content');
|
||||
|
||||
const proxyRequestObj = serverInstance.getProxyRequestRecord(replacedUrl);
|
||||
expect(proxyRequestObj.headers.token).toEqual(token);
|
||||
expect(proxyRequestObj.headers['via-proxy']).toEqual('true');
|
||||
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('the_request_that_has_not_be_replaced');
|
||||
|
||||
const directRequestObj = serverInstance.getRequestRecord(url);
|
||||
expect(directRequestObj.headers.token).toEqual(directToken);
|
||||
|
||||
done();
|
||||
}).catch(error => {
|
||||
console.error('error happened in direct get for replaceOption rule: ', error);
|
||||
done.fail('error happened when direct test replaceOption rule ');
|
||||
});
|
||||
}).catch(error => {
|
||||
console.error('error happened in proxy get for replaceOption rule: ', error);
|
||||
done.fail('error happened when proxy test replaceOption rule ');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace request option if the assertion is false', done => {
|
||||
const url = generateUrl(protocol, '/test/should_not_replace_option');
|
||||
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
done();
|
||||
}, error => {
|
||||
console.error('error happened in proxy get:', error);
|
||||
done.fail('error happened in proxy get');
|
||||
}).catch(error => {
|
||||
console.error('error happend in syntax:', error);
|
||||
done.fail('error happend in syntax');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
112
test/spec_rule/rule_replace_request_protocol_spec.js
Normal file
112
test/spec_rule/rule_replace_request_protocol_spec.js
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* test for rule replaceOption rule
|
||||
*
|
||||
*/
|
||||
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_request_protocol.js');
|
||||
|
||||
testWrapper();
|
||||
|
||||
function testWrapper() {
|
||||
describe('Rule replaceRequestProtocol should be working', () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_request_protocol');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_request_protocol');
|
||||
});
|
||||
|
||||
it('Should replace request protocol in PROXY https request', done => {
|
||||
const url = generateUrl('https', '/test/normal_request1');
|
||||
const httpUrl = url.replace('https', 'http');
|
||||
const token = 'proxy_request1_token_' + Date.now();
|
||||
proxyGet(url, {}, { token })
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.body).toEqual('body_normal_request1');
|
||||
|
||||
// there should be no https url be requested in proxy, it should be http request
|
||||
expect(serverInstance.getProxyRequestRecord(url)).toBe(null);
|
||||
const httpRecord = serverInstance.getProxyRequestRecord(httpUrl);
|
||||
expect(httpRecord.headers.token).toEqual(token);
|
||||
expect(httpRecord.headers['via-proxy']).toEqual('true');
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error happened in proxy the https request: ', error);
|
||||
done.fail('error happened in proxy the https request');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace protocol in PROXY http request', done => {
|
||||
const url = generateUrl('http', '/test/normal_request2');
|
||||
const token = 'proxy_request2_token_' + Date.now();
|
||||
proxyGet(url, {}, { token })
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.body).toEqual('body_normal_request2');
|
||||
const requestRecord = serverInstance.getProxyRequestRecord(url);
|
||||
expect(requestRecord).not.toBe(null);
|
||||
expect(requestRecord.headers.token).toEqual(token);
|
||||
expect(requestRecord.headers['via-proxy']).toEqual('true');
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy the http request: ', error);
|
||||
done.fail('error happend in proxy the http request');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should the direct request still be working with https', done => {
|
||||
const url = generateUrl('https', '/test/normal_request1');
|
||||
const token = 'direct_request1_token_' + Date.now();
|
||||
directGet(url, {}, { token })
|
||||
.then(directRes => {
|
||||
expect(directRes.body).toEqual('body_normal_request1');
|
||||
const requestRecord = serverInstance.getRequestRecord(url);
|
||||
expect(requestRecord.headers.token).toEqual(token);
|
||||
expect(requestRecord.headers['via-proxy']).toBeUndefined();
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct https get:', error);
|
||||
done.fail('error happened in direct https get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should the direct request still be working with http', done => {
|
||||
const url = generateUrl('http', '/test/normal_request2');
|
||||
const token = 'direct_request1_token_' + Date.now();
|
||||
directGet(url, {}, { token })
|
||||
.then(directRes => {
|
||||
expect(directRes.body).toEqual('body_normal_request2');
|
||||
const requestRecord = serverInstance.getRequestRecord(url);
|
||||
expect(requestRecord.headers.token).toEqual(token);
|
||||
expect(requestRecord.headers['via-proxy']).toBeUndefined();
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct http get:', error);
|
||||
done.fail('error happened in direct http get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
87
test/spec_rule/rule_replace_response_data_spec.js
Normal file
87
test/spec_rule/rule_replace_response_data_spec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* test for rule replaceResponseData rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_response_data.js');
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule replaceResponseData should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_response_data');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_response_data');
|
||||
});
|
||||
|
||||
it('Should replace the header in proxy if assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request1');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('body_normal_request1_hello_world!');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('body_normal_request1');
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace the header in proxy if assertion is false', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request2');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('body_normal_request2');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
91
test/spec_rule/rule_replace_response_header_spec.js
Normal file
91
test/spec_rule/rule_replace_response_header_spec.js
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* test for rule replaceResponseHeader rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_response_header.js');
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule replaceResponseHeader should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_response_header_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_response_header_spec');
|
||||
});
|
||||
|
||||
it('Should replace the header in proxy if assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request1');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.headers.replacedheaderkey).toEqual('replacedHeader_value_in_rule');
|
||||
expect(proxyRes.body).toEqual('body_normal_request1');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.headers.replacedheaderkey).toBeUndefined();
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace the header in proxy if the assertion is false', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request2');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.headers.replacedheaderkey).toBeUndefined();
|
||||
expect(proxyRes.body).toEqual('body_normal_request2');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.headers.replacedheaderkey).toBeUndefined();
|
||||
expect(directRes.body).toEqual(proxyRes.body);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
87
test/spec_rule/rule_replace_response_status_code_spec.js
Normal file
87
test/spec_rule/rule_replace_response_status_code_spec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* test for rule replaceResponseStatus rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_replace_response_status_code.js');
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule replaceResponseStatus should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_replace_response_status_code');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_replace_response_status_code');
|
||||
});
|
||||
|
||||
it('Should replace the status code in proxy if assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request1');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(302);
|
||||
expect(proxyRes.headers.location).toEqual('www.taobao.com');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('body_normal_request1');
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace the status code in proxy if assertion is false', done => {
|
||||
const url = generateUrl(protocol, '/test/normal_request2');
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
expect(proxyRes.body).toEqual('body_normal_request2');
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body).toEqual('body_normal_request2');
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
87
test/spec_rule/rule_should_intercept_https_req_spec.js
Normal file
87
test/spec_rule/rule_should_intercept_https_req_spec.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* test for rule shouldInterceptHttpsReq rule
|
||||
*
|
||||
*/
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, directGet } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_should_intercept_https_req.js');
|
||||
|
||||
testWrapper();
|
||||
|
||||
function testWrapper() {
|
||||
describe('Rule shouldInterceptHttpsReq should be working', () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll(done => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for test_rule_should_intercept_https_req_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule, {
|
||||
forceProxyHttps: false
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for test_rule_should_intercept_https_req_spec');
|
||||
});
|
||||
|
||||
it('Should replace the header in proxy if assertion is true', done => {
|
||||
const url = 'https://localhost:3001/test';
|
||||
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body + '_hello_world').toEqual(proxyRes.body);
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
|
||||
it('Should not replace the header in proxy if assertion is false', done => {
|
||||
const url = 'https://localhost:3002/test';
|
||||
proxyGet(url)
|
||||
.then(proxyRes => {
|
||||
expect(proxyRes.statusCode).toEqual(200);
|
||||
|
||||
directGet(url)
|
||||
.then(directRes => {
|
||||
expect(directRes.statusCode).toEqual(200);
|
||||
expect(directRes.body.replace(/\s/g, '')).toEqual(proxyRes.body.replace(/\s/g, ''));
|
||||
done();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in direct get: ', error);
|
||||
done.fail('error happened in direct get');
|
||||
});
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error happened in proxy get: ', error);
|
||||
done.fail('error happened in proxy get');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
55
test/spec_rule/rule_should_use_local_response_spec.js
Normal file
55
test/spec_rule/rule_should_use_local_response_spec.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* test for rule shouldUseLocal
|
||||
*
|
||||
*/
|
||||
|
||||
const ProxyServerUtil = require('../util/ProxyServerUtil.js');
|
||||
const { proxyGet, generateUrl } = require('../util/HttpUtil.js');
|
||||
const Server = require('../server/server.js');
|
||||
const { printLog } = require('../util/CommonUtil.js');
|
||||
|
||||
const rule = require('./rule/rule_should_use_local_response.js');
|
||||
|
||||
const expectedLocalBody = 'handled_in_local_response';
|
||||
|
||||
testWrapper('http');
|
||||
testWrapper('https');
|
||||
|
||||
function testWrapper(protocol) {
|
||||
describe('Rule shouldUseLocalResponse should be working in :' + protocol, () => {
|
||||
let proxyServer;
|
||||
let serverInstance;
|
||||
|
||||
beforeAll((done) => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000;
|
||||
printLog('Start server for rule_shouldUseLocalResponse_spec');
|
||||
|
||||
serverInstance = new Server();
|
||||
|
||||
proxyServer = ProxyServerUtil.proxyServerWithRule(rule);
|
||||
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
serverInstance && serverInstance.close();
|
||||
proxyServer && proxyServer.close();
|
||||
printLog('Close server for rule_shouldUseLocalResponse_spec');
|
||||
});
|
||||
|
||||
it('Should use local response if the assertion is true', done => {
|
||||
const url = generateUrl(protocol, '/test/uselocal');
|
||||
proxyGet(url, {})
|
||||
.then(res => {
|
||||
expect(res.body).toEqual(expectedLocalBody);
|
||||
expect(res.headers['via-proxy-local']).toEqual('true');
|
||||
done();
|
||||
}).catch((error) => {
|
||||
console.log('error happened in proxy get for shouldUseLocal: ', error);
|
||||
done.fail('error happened when test shouldUseLocal rule');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
60
test/test.js
60
test/test.js
@@ -1,60 +0,0 @@
|
||||
var proxy = require("../proxy.js"),
|
||||
proxyTester = require("proxy-eval"),
|
||||
WebSocket = require("ws");
|
||||
|
||||
//start a new proxy at port 8995, with websocket port 8996
|
||||
var SOCKET_PORT = 8996,
|
||||
PROXY_PORT = 8995;
|
||||
|
||||
new proxy.proxyServer({
|
||||
type :"http",
|
||||
port :PROXY_PORT,
|
||||
socketPort :SOCKET_PORT,
|
||||
silent :true
|
||||
});
|
||||
|
||||
|
||||
exports.avalibility = function(test){
|
||||
test.expect(2);
|
||||
var updateCount = 0;
|
||||
|
||||
//test web socket
|
||||
setTimeout(function(){
|
||||
var ws = new WebSocket('ws://127.0.0.1:' + SOCKET_PORT , {
|
||||
protocolVersion: 8
|
||||
});
|
||||
|
||||
ws.on('open', function open(){});
|
||||
ws.on('close', function close(){});
|
||||
ws.on('message', function message(data, flags) {
|
||||
try{
|
||||
var jsonData = JSON.parse(data);
|
||||
jsonData.type == "update" && ++updateCount;
|
||||
}catch(e){}
|
||||
});
|
||||
setTimeout(function(){
|
||||
test.ok(updateCount >= 4,"web socket message count of type 'update' ");
|
||||
test.done();
|
||||
setTimeout(function(){
|
||||
process.exit();
|
||||
},1000);
|
||||
},10*1000);
|
||||
|
||||
},1000);
|
||||
|
||||
//test the basic availibility of proxy server
|
||||
setTimeout(function(){
|
||||
proxyTester.test({proxy : 'http://127.0.0.1:8995',reqTimeout:4500} ,function(results){
|
||||
var successCount = 0;
|
||||
results.map(function(item){
|
||||
item.success && ++successCount;
|
||||
});
|
||||
|
||||
var ifPassed = (true || results.length == successCount);
|
||||
if(!ifPassed){
|
||||
proxyTester.printResult(results);
|
||||
}
|
||||
test.ok(ifPassed, "availibility test failed");
|
||||
});
|
||||
},1000);
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Begin to run the test suites, JASMINE is required.\n"
|
||||
echo "Removing test temp directory before running"
|
||||
rm -rf ./test/temp/*
|
||||
echo "Removing done, test cases now running"
|
||||
node -v
|
||||
jasmine JASMINE_CONFIG_PATH=./jasmine.json
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Rule defination for shouldUseLocalResponse
|
||||
*
|
||||
*/
|
||||
|
||||
const dealLocalBody = 'handled_in_local_response';
|
||||
|
||||
module.exports = {
|
||||
shouldUseLocalResponse: function (req, reqBody) {
|
||||
return req.url.indexOf('uselocal') > -1;
|
||||
},
|
||||
shouldInterceptHttpsReq: function () {
|
||||
return true;
|
||||
},
|
||||
dealLocalResponse: function (req, reqBody, callback) {
|
||||
const header = {
|
||||
'Via-Proxy-Local': 'true'
|
||||
};
|
||||
|
||||
callback(200, header, dealLocalBody);
|
||||
}
|
||||
};
|
||||
@@ -2,87 +2,117 @@
|
||||
*
|
||||
* The utility class for test
|
||||
*/
|
||||
const zlib = require('zlib');
|
||||
const color = require('colorful');
|
||||
|
||||
function _isDeepEqual(source, target) {
|
||||
// if the objects are Array
|
||||
if (source.constructor === Array && target.constructor === Array) {
|
||||
if (source.length !== target.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let _isEqual = true;
|
||||
for (let i = 0; i < source.length; i++) {
|
||||
if (!_isDeepEqual(source[i], target[i])) {
|
||||
_isEqual = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _isEqual;
|
||||
}
|
||||
|
||||
// if the source and target are just object
|
||||
if (typeof source === 'object' && typeof target === 'object') {
|
||||
let _isEqual = true;
|
||||
for (const key in source) {
|
||||
if (!_isDeepEqual(source[key], target[key])) {
|
||||
_isEqual = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _isEqual;
|
||||
}
|
||||
|
||||
return source === target;
|
||||
}
|
||||
/*
|
||||
* Compare whether tow object are equal
|
||||
*/
|
||||
function isObjectEqual (source = {} , target = {}, url = '') {
|
||||
source = Object.assign({}, source);
|
||||
target = Object.assign({}, target);
|
||||
let isEqual = true;
|
||||
function isObjectEqual(source = {}, target = {}, url = '') {
|
||||
source = Object.assign({}, source);
|
||||
target = Object.assign({}, target);
|
||||
let isEqual = true;
|
||||
|
||||
for(const key in source) {
|
||||
isEqual = isEqual && source[key] === target[key];
|
||||
for (const key in source) {
|
||||
isEqual = isEqual && _isDeepEqual(source[key], target[key]);
|
||||
|
||||
if (!isEqual) {
|
||||
console.info('source object :', source);
|
||||
console.info('target object :', target);
|
||||
printError(`different key in isObjectEqual is: "${key}", source is "${source[key]}",
|
||||
target is "${target[key]}" the url is ${url}`);
|
||||
break;
|
||||
}
|
||||
|
||||
delete source[key];
|
||||
delete target[key];
|
||||
if (!isEqual) {
|
||||
console.info('source object :', source);
|
||||
console.info('target object :', target);
|
||||
printError(`different key in isObjectEqual is: "${key}", source is "${source[key]}",
|
||||
target is "${target[key]}" the url is ${url}`);
|
||||
break;
|
||||
}
|
||||
|
||||
for(const key in target) {
|
||||
isEqual = isEqual && source[key] === target[key];
|
||||
delete source[key];
|
||||
delete target[key];
|
||||
}
|
||||
|
||||
if (!isEqual) {
|
||||
console.info('source object :', source);
|
||||
console.info('target object :', target);
|
||||
printError(`different key in isObjectEqual is: "${key}", source is "${source[key]}",
|
||||
target is "${target[key]}" the url is ${url}`);
|
||||
break;
|
||||
}
|
||||
for (const key in target) {
|
||||
isEqual = isEqual && source[key] === target[key];
|
||||
|
||||
delete source[key];
|
||||
delete target[key];
|
||||
if (!isEqual) {
|
||||
console.info('source object :', source);
|
||||
console.info('target object :', target);
|
||||
printError(`different key in isObjectEqual is: "${key}", source is "${source[key]}",
|
||||
target is "${target[key]}" the url is ${url}`);
|
||||
break;
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
delete source[key];
|
||||
delete target[key];
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the header between direct with proxy
|
||||
* Will exclude the header(s) which modified by proxy
|
||||
*/
|
||||
function isCommonResHeaderEqual (directHeaders, proxyHeaders, requestUrl) {
|
||||
directHeaders = Object.assign({}, directHeaders);
|
||||
proxyHeaders = Object.assign({}, proxyHeaders);
|
||||
let isEqual = true;
|
||||
const mustEqualFileds = []; // the fileds that have to be equal, or the assert will be failed
|
||||
function isCommonResHeaderEqual(directHeaders, proxyHeaders, requestUrl) {
|
||||
directHeaders = Object.assign({}, directHeaders);
|
||||
proxyHeaders = Object.assign({}, proxyHeaders);
|
||||
let isEqual = true;
|
||||
const mustEqualFileds = []; // the fileds that have to be equal, or the assert will be failed
|
||||
|
||||
if (!/gzip/i.test(directHeaders['content-encoding'])) {
|
||||
// if the content is gzipped, proxy will unzip and remove the header
|
||||
mustEqualFileds.push('content-encoding');
|
||||
mustEqualFileds.push('content-length');
|
||||
if (!/gzip/i.test(directHeaders['content-encoding'])) {
|
||||
// if the content is gzipped, proxy will unzip and remove the header
|
||||
mustEqualFileds.push('content-encoding');
|
||||
}
|
||||
mustEqualFileds.push('content-type');
|
||||
mustEqualFileds.push('cache-control');
|
||||
mustEqualFileds.push('allow');
|
||||
|
||||
// ensure the required fileds are same
|
||||
mustEqualFileds.forEach(filedName => {
|
||||
isEqual = directHeaders[filedName] === proxyHeaders[filedName];
|
||||
delete directHeaders[filedName];
|
||||
delete proxyHeaders[filedName];
|
||||
});
|
||||
|
||||
// remained filed are good to be same, but are allowed to be different
|
||||
// will warn out those different fileds
|
||||
for (const key in directHeaders) {
|
||||
if (!_isDeepEqual(directHeaders[key], proxyHeaders[key])) {
|
||||
printWarn(`key "${key}" of two response headers are different in request "${requestUrl}" :
|
||||
direct is: "${directHeaders[key]}", proxy is: "${proxyHeaders[key]}"`);
|
||||
}
|
||||
mustEqualFileds.push('content-type');
|
||||
mustEqualFileds.push('cache-control');
|
||||
mustEqualFileds.push('allow');
|
||||
}
|
||||
|
||||
// ensure the required fileds are same
|
||||
mustEqualFileds.forEach(filedName => {
|
||||
isEqual = directHeaders[filedName] === proxyHeaders[filedName];
|
||||
delete directHeaders[filedName];
|
||||
delete proxyHeaders[filedName];
|
||||
});
|
||||
|
||||
// remained filed are good to be same, but are allowed to be different
|
||||
// will warn out those different fileds
|
||||
for (const key in directHeaders) {
|
||||
if (directHeaders[key] !== proxyHeaders[key]) {
|
||||
printWarn(`key "${key}" of two response headers are different in request "${requestUrl}" :
|
||||
direct is: "${directHeaders[key]}", proxy is: "${proxyHeaders[key]}"`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
return isEqual;
|
||||
return isEqual;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -90,64 +120,156 @@ function isCommonResHeaderEqual (directHeaders, proxyHeaders, requestUrl) {
|
||||
*
|
||||
*/
|
||||
function isCommonReqEqual(url, serverInstance) {
|
||||
try{
|
||||
url = url.replace('https://', '').replace('http://', ''); // only the remained path is required
|
||||
let isEqual = true;
|
||||
try {
|
||||
let isEqual = true;
|
||||
|
||||
const directReqObj = serverInstance.getRequestRecord(url);
|
||||
const proxyReqObj = serverInstance.getProxyRequestRecord(url);
|
||||
const directReqObj = serverInstance.getRequestRecord(url);
|
||||
const proxyReqObj = serverInstance.getProxyRequestRecord(url);
|
||||
|
||||
// ensure the proxy header is correct
|
||||
isEqual = isEqual && proxyReqObj.headers['via-proxy'] === 'true';
|
||||
delete proxyReqObj.headers['via-proxy'];
|
||||
// ensure the proxy header is correct
|
||||
isEqual = isEqual && proxyReqObj.headers['via-proxy'] === 'true';
|
||||
delete proxyReqObj.headers['via-proxy'];
|
||||
|
||||
// exclued accept-encoding from comparing, since the proxy will remove it before sending it out
|
||||
delete directReqObj.headers['accept-encoding'];
|
||||
// exclued accept-encoding from comparing, since the proxy will remove it before sending it out
|
||||
delete directReqObj.headers['accept-encoding'];
|
||||
|
||||
// per undefined header, proxy will set it with 0, and an empty request body
|
||||
if (typeof directReqObj.headers['content-length'] === 'undefined') {
|
||||
// TODO: 我这里proxy出去的options里没有accept-encoding, 但node自己加上了。Why ?
|
||||
// By 加里 2017.1.31
|
||||
delete proxyReqObj.headers['accept-encoding'];
|
||||
|
||||
directReqObj.headers['content-length'] = "0";
|
||||
}
|
||||
directReqObj.headers['content-type'] = trimFormContentType(directReqObj.headers['content-type']);
|
||||
proxyReqObj.headers['content-type'] = trimFormContentType(proxyReqObj.headers['content-type']);
|
||||
|
||||
directReqObj.headers['content-type'] = trimFormContentType(directReqObj.headers['content-type']);
|
||||
proxyReqObj.headers['content-type'] = trimFormContentType(proxyReqObj.headers['content-type']);
|
||||
|
||||
isEqual = isEqual && directReqObj.url === proxyReqObj.url;
|
||||
isEqual = isEqual && isObjectEqual(directReqObj.headers, proxyReqObj.headers, url);
|
||||
isEqual = isEqual && directReqObj.body === proxyReqObj.body;
|
||||
return isEqual;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
// avoid compare content-length header via proxy
|
||||
delete directReqObj.headers['content-length'];
|
||||
delete proxyReqObj.headers['content-length'];
|
||||
delete directReqObj.headers['transfer-encoding'];
|
||||
delete proxyReqObj.headers['transfer-encoding'];
|
||||
|
||||
isEqual = isEqual && directReqObj.url === proxyReqObj.url;
|
||||
isEqual = isEqual && isObjectEqual(directReqObj.headers, proxyReqObj.headers, url);
|
||||
isEqual = isEqual && directReqObj.body === proxyReqObj.body;
|
||||
return isEqual;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* for multipart-form, the boundary will be different with each update, we trim it here
|
||||
*/
|
||||
function trimFormContentType (contentType = '') {
|
||||
return contentType.replace(/boundary.*/, '');
|
||||
function trimFormContentType(contentType = '') {
|
||||
return contentType.replace(/boundary.*/, '');
|
||||
}
|
||||
|
||||
|
||||
function printLog (content) {
|
||||
console.log(color.blue('==LOG==: ' + content));
|
||||
function printLog(content) {
|
||||
console.log(color.blue('==LOG==: ' + content));
|
||||
}
|
||||
|
||||
function printWarn(content) {
|
||||
console.log(color.magenta('==WARN==: ' + content));
|
||||
console.log(color.magenta('==WARN==: ' + content));
|
||||
}
|
||||
|
||||
function printError(content) {
|
||||
console.log(color.red('==ERROR==: ' + content));
|
||||
console.log(color.red('==ERROR==: ' + content));
|
||||
}
|
||||
|
||||
function printHilite(content) {
|
||||
console.log(color.yellow('==LOG==: ' + content));
|
||||
}
|
||||
|
||||
function parseUrlQuery(string = '') {
|
||||
const parameterArray = string.split('&');
|
||||
const parsedObj = {};
|
||||
parameterArray.forEach((parameter) => {
|
||||
// 获取等号的位置
|
||||
const indexOfEqual = parameter.indexOf('=');
|
||||
const name = parameter.substr(0, indexOfEqual);
|
||||
const value = parameter.substr(indexOfEqual + 1);
|
||||
parsedObj[name] = value;
|
||||
});
|
||||
return parsedObj;
|
||||
}
|
||||
|
||||
function stringSimilarity(a, b, precision = 2) {
|
||||
let similarity = '0%';
|
||||
let isCongruent = false;
|
||||
if (a && b) {
|
||||
const targetLen = Math.max(a.length, b.length);
|
||||
targetLen > 1000 ?
|
||||
similarity = simHasH(a, b) :
|
||||
similarity = LevenshteinSimilarity(a, b);
|
||||
isCongruent = similarity === 100;
|
||||
similarity = similarity.toFixed(precision) + '%';
|
||||
}
|
||||
return {
|
||||
isCongruent,
|
||||
similarity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* simhash similarity
|
||||
*/
|
||||
function simHasH(a, b) {
|
||||
const simhash = require('node-simhash');
|
||||
return (simhash.compare(a, b) * 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Levenshtein Distance
|
||||
*/
|
||||
function LevenshteinSimilarity(a, b) {
|
||||
let cost;
|
||||
const maxLen = Math.max(a.length, b.length);
|
||||
const minOfThree = (numa, numb, numc) => {
|
||||
if (numa > numb) {
|
||||
return numb > numc ? numc : numb;
|
||||
} else {
|
||||
return numa > numc ? numc : numa;
|
||||
}
|
||||
}
|
||||
if (a.length === 0) cost = b.length;
|
||||
if (b.length === 0) cost = a.length;
|
||||
|
||||
if (a.length > b.length) {
|
||||
const tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
const row = [];
|
||||
for (let i = 0; i <= a.length; i++) {
|
||||
row[i] = i;
|
||||
}
|
||||
|
||||
for (let i = 1; i <= b.length; i++) {
|
||||
let prev = i;
|
||||
for (let j = 1; j <= a.length; j++) {
|
||||
let val;
|
||||
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
||||
val = row[j - 1];
|
||||
} else {
|
||||
val = minOfThree(row[j - 1] + 1, prev + 1, row[j] + 1);
|
||||
}
|
||||
row[j - 1] = prev;
|
||||
prev = val;
|
||||
}
|
||||
row[a.length] = prev;
|
||||
}
|
||||
cost = row[a.length];
|
||||
return ((maxLen - cost) / maxLen * 100);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isObjectEqual,
|
||||
isCommonResHeaderEqual,
|
||||
printLog,
|
||||
printWarn,
|
||||
printError,
|
||||
isCommonReqEqual
|
||||
isObjectEqual,
|
||||
isCommonResHeaderEqual,
|
||||
printLog,
|
||||
printWarn,
|
||||
printError,
|
||||
printHilite,
|
||||
isCommonReqEqual,
|
||||
parseUrlQuery,
|
||||
stringSimilarity
|
||||
};
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/* eslint prefer-arrow-callback: 0 */
|
||||
/**
|
||||
* An util to make the request out
|
||||
*
|
||||
*/
|
||||
const querystring = require('querystring');
|
||||
const http = require('http');
|
||||
const zlib = require('zlib');
|
||||
const Buffer = require('buffer').Buffer;
|
||||
const request = require('request');
|
||||
const fs = require('fs');
|
||||
const WebSocket = require('ws');
|
||||
const HttpsProxyAgent = require('https-proxy-agent');
|
||||
const stream = require('stream');
|
||||
|
||||
const DEFAULT_HOST = 'localhost';
|
||||
const PROXY_HOST = 'http://localhost:8001';
|
||||
const SOCKET_PROXY_HOST = 'http://localhost:8001';
|
||||
|
||||
@@ -20,243 +17,336 @@ const HTTP_SERVER_BASE = 'http://localhost:3000';
|
||||
const HTTPS_SERVER_BASE = 'https://localhost:3001';
|
||||
const WS_SERVER_BASE = 'ws://localhost:3000';
|
||||
const WSS_SERVER_BASE = 'wss://localhost:3001';
|
||||
const DEFAULT_CHUNK_COLLECT_THRESHOLD = 20 * 1024 * 1024; // about 20 mb
|
||||
|
||||
const DEFAULT_PROXY_OPTIONS = {
|
||||
port: 8001, // proxy的端口
|
||||
method: 'GET',
|
||||
host: 'localhost'
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
|
||||
};
|
||||
|
||||
function getHostFromUrl (url = '') {
|
||||
const hostReg = /^(https{0,1}:\/\/)(\w+)/;
|
||||
const match = url.match(hostReg);
|
||||
|
||||
return match && match[2] ? match[2] : '';
|
||||
class commonStream extends stream.Readable {
|
||||
constructor(config) {
|
||||
super({
|
||||
highWaterMark: DEFAULT_CHUNK_COLLECT_THRESHOLD * 5
|
||||
});
|
||||
}
|
||||
_read(size) {}
|
||||
}
|
||||
|
||||
function getPortFromUrl (url = '') {
|
||||
const portReg = /^https{0,1}:\/\/\w+(:(\d+)){0,1}/;
|
||||
const match = url.match(portReg);
|
||||
let port = match && match[2] ? match[2] : '';
|
||||
function getHostFromUrl(url = '') {
|
||||
const hostReg = /^(https{0,1}:\/\/)(\w+)/;
|
||||
const match = url.match(hostReg);
|
||||
|
||||
if (!port) {
|
||||
port = url.indexOf('https://') === 0 ? 443 : 80;
|
||||
}
|
||||
return port;
|
||||
return match && match[2] ? match[2] : '';
|
||||
}
|
||||
|
||||
function getPortFromUrl(url = '') {
|
||||
const portReg = /^https{0,1}:\/\/\w+(:(\d+)){0,1}/;
|
||||
const match = url.match(portReg);
|
||||
let port = match && match[2] ? match[2] : '';
|
||||
|
||||
if (!port) {
|
||||
port = url.indexOf('https://') === 0 ? 443 : 80;
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取url中的path
|
||||
*/
|
||||
function getPathFromUrl (url = '') {
|
||||
const pathReg = /^https{0,1}:\/\/\w+(:\d+){0,1}(.+)/;
|
||||
const match = url.match(pathReg);
|
||||
const path = match && match[3] ? match[2] : url;
|
||||
return path;
|
||||
function getPathFromUrl(url = '') {
|
||||
const pathReg = /^https{0,1}:\/\/\w+(:\d+){0,1}(.+)/;
|
||||
const match = url.match(pathReg);
|
||||
const path = match && match[3] ? match[2] : url;
|
||||
return path;
|
||||
}
|
||||
|
||||
function proxyRequest (method = 'GET', url, params, headers = {}) {
|
||||
return doRequest(method, url, params, headers, true);
|
||||
function proxyRequest(method = 'GET', url, params, headers = {}) {
|
||||
return doRequest(method, url, params, headers, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* 直接请求到真实服务器,不经过代理服务器
|
||||
*
|
||||
*/
|
||||
function directRequest (method = 'GET', url, params, headers = {}) {
|
||||
return doRequest(method, url, params, headers);
|
||||
function directRequest(method = 'GET', url, params, headers = {}) {
|
||||
return doRequest(method, url, params, headers);
|
||||
}
|
||||
|
||||
function directUpload (url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'POST', filepath, formParams, headers);
|
||||
function directUpload(url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'POST', filepath, formParams, headers);
|
||||
}
|
||||
|
||||
function proxyUpload (url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'POST', filepath, formParams, headers, true);
|
||||
function proxyUpload(url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'POST', filepath, formParams, headers, true);
|
||||
}
|
||||
|
||||
function directPutUpload (url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'PUT', filepath, formParams, headers);
|
||||
function directPutUpload(url, filepath, formParams = {}, headers = {}) {
|
||||
return doUpload(url, 'PUT', filepath, formParams, headers);
|
||||
}
|
||||
|
||||
function proxyPutUpload (url, filepath, headers = {}) {
|
||||
return doUpload(url, 'PUT', filepath, headers, true);
|
||||
function proxyPutUpload(url, filepath, headers = {}) {
|
||||
return doUpload(url, 'PUT', filepath, headers, true);
|
||||
}
|
||||
|
||||
function doRequest (method = 'GET', url, params, headers = {}, isProxy) {
|
||||
headers = Object.assign({}, headers);
|
||||
const requestData = {
|
||||
method: method,
|
||||
form: params,
|
||||
url: url,
|
||||
headers: headers,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
/**
|
||||
* @param params {String} json类型或file路径
|
||||
* {Object} key-value形式
|
||||
*/
|
||||
function doRequest(method = 'GET', url, params, headers = {}, isProxy) {
|
||||
headers = Object.assign({}, headers);
|
||||
|
||||
if (isProxy) {
|
||||
requestData.proxy = PROXY_HOST;
|
||||
requestData.headers['via-proxy'] = 'true';
|
||||
let reqStream = new commonStream();
|
||||
const requestData = {
|
||||
headers,
|
||||
followRedirect: false,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
if (isProxy) {
|
||||
requestData.proxy = PROXY_HOST;
|
||||
requestData.headers['via-proxy'] = 'true';
|
||||
}
|
||||
|
||||
const streamReq = (resolve, reject) => {
|
||||
requestData.headers['content-type'] = 'text/plain'; //otherwise, koa-body could not recognize
|
||||
if (typeof params === 'string') {
|
||||
fs.existsSync(params) ?
|
||||
reqStream = fs.createReadStream(params) :
|
||||
reqStream.push(params);
|
||||
} else if (typeof params === 'object') {
|
||||
reqStream.push(JSON.stringify(params));
|
||||
}
|
||||
|
||||
const requestTask = new Promise((resolve, reject) => {
|
||||
request(
|
||||
requestData,
|
||||
function (error, response, body) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(response);
|
||||
}
|
||||
);
|
||||
});
|
||||
return requestTask;
|
||||
reqStream.push(null);
|
||||
reqStream.pipe(request[method.toLowerCase()](
|
||||
url,
|
||||
requestData,
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(response);
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
const commonReq = (resolve, reject) => {
|
||||
requestData.url = url;
|
||||
requestData.method = method;
|
||||
requestData.qs = params;
|
||||
request(
|
||||
requestData,
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(response);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
const requestTask = new Promise((resolve, reject) => {
|
||||
if (method === 'POST' || method === 'PUT') {
|
||||
streamReq(resolve, reject);
|
||||
} else {
|
||||
commonReq(resolve, reject);
|
||||
}
|
||||
});
|
||||
return requestTask;
|
||||
}
|
||||
|
||||
function doUpload (url, method, filepath, formParams, headers = {}, isProxy) {
|
||||
let formData = {
|
||||
file: fs.createReadStream(filepath)
|
||||
};
|
||||
|
||||
formData = Object.assign({}, formData, formParams);
|
||||
headers = Object.assign({}, headers);
|
||||
function doUpload(url, method, filepath, formParams, headers = {}, isProxy) {
|
||||
let formData = {
|
||||
file: fs.createReadStream(filepath)
|
||||
};
|
||||
|
||||
const requestData = {
|
||||
formData: formData,
|
||||
url: url,
|
||||
method: method,
|
||||
headers: headers,
|
||||
json: true,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
formData = Object.assign({}, formData, formParams);
|
||||
headers = Object.assign({}, headers);
|
||||
|
||||
if (isProxy) {
|
||||
requestData.proxy = PROXY_HOST;
|
||||
requestData.headers['via-proxy'] = 'true';
|
||||
}
|
||||
const requestTask = new Promise((resolve, reject) => {
|
||||
request(
|
||||
requestData,
|
||||
function (error, response, body) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(response);
|
||||
}
|
||||
);
|
||||
});
|
||||
return requestTask;
|
||||
const requestData = {
|
||||
formData,
|
||||
url,
|
||||
method,
|
||||
headers,
|
||||
json: true,
|
||||
rejectUnauthorized: false
|
||||
};
|
||||
|
||||
if (isProxy) {
|
||||
requestData.proxy = PROXY_HOST;
|
||||
requestData.headers['via-proxy'] = 'true';
|
||||
}
|
||||
const requestTask = new Promise((resolve, reject) => {
|
||||
request(
|
||||
requestData,
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(response);
|
||||
}
|
||||
);
|
||||
});
|
||||
return requestTask;
|
||||
}
|
||||
|
||||
function doWebSocket(url, isProxy) {
|
||||
let ws;
|
||||
if (isProxy) {
|
||||
const agent = new HttpsProxyAgent(SOCKET_PROXY_HOST);
|
||||
ws = new WebSocket(url, {
|
||||
agent: agent,
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
} else {
|
||||
ws = new WebSocket(url, {
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
}
|
||||
let ws;
|
||||
if (isProxy) {
|
||||
const agent = new HttpsProxyAgent(SOCKET_PROXY_HOST);
|
||||
ws = new WebSocket(url, {
|
||||
agent,
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
} else {
|
||||
ws = new WebSocket(url, {
|
||||
rejectUnauthorized: false
|
||||
});
|
||||
}
|
||||
|
||||
return ws;
|
||||
return ws;
|
||||
}
|
||||
|
||||
function proxyGet (url, params, headers = {}) {
|
||||
return proxyRequest('GET', url, params, headers);
|
||||
function proxyGet(url, params, headers = {}) {
|
||||
return proxyRequest('GET', url, params, headers);
|
||||
}
|
||||
|
||||
function proxyPost (url, params, headers = {}) {
|
||||
return proxyRequest('POST', url, params, headers);
|
||||
function proxyPost(url, params, headers = {}) {
|
||||
return proxyRequest('POST', url, params, headers);
|
||||
}
|
||||
|
||||
function proxyPut (url, params, headers = {}) {
|
||||
return proxyRequest('PUT', url, params, headers);
|
||||
function proxyPut(url, params, headers = {}) {
|
||||
return proxyRequest('PUT', url, params, headers);
|
||||
}
|
||||
|
||||
function proxyDelete (url, params, headers = {}) {
|
||||
return proxyRequest('DELETE', url, params, headers);
|
||||
function proxyDelete(url, params, headers = {}) {
|
||||
return proxyRequest('DELETE', url, params, headers);
|
||||
}
|
||||
|
||||
function proxyHead(url, headers = {}) {
|
||||
return proxyRequest('HEAD', url, {}, headers);
|
||||
return proxyRequest('HEAD', url, {}, headers);
|
||||
}
|
||||
|
||||
function proxyOptions(url, headers = {}) {
|
||||
return proxyRequest('OPTIONS', url, {}, headers);
|
||||
return proxyRequest('OPTIONS', url, {}, headers);
|
||||
}
|
||||
|
||||
function directGet (url, params, headers = {}) {
|
||||
return directRequest('GET', url, params, headers);
|
||||
function directGet(url, params, headers = {}) {
|
||||
return directRequest('GET', url, params, headers);
|
||||
}
|
||||
|
||||
function directPost (url, params, headers = {}) {
|
||||
return directRequest('POST', url, params, headers);
|
||||
function directPost(url, params, headers = {}) {
|
||||
return directRequest('POST', url, params, headers);
|
||||
}
|
||||
|
||||
function directPut (url, params, headers = {}) {
|
||||
return directRequest('PUT', url, params, headers);
|
||||
function directPut(url, params, headers = {}) {
|
||||
return directRequest('PUT', url, params, headers);
|
||||
}
|
||||
|
||||
function directDelete (url, params, headers = {}) {
|
||||
return directRequest('DELETE', url, params, headers);
|
||||
function directDelete(url, params, headers = {}) {
|
||||
return directRequest('DELETE', url, params, headers);
|
||||
}
|
||||
|
||||
function directHead (url, headers = {}) {
|
||||
return directRequest('HEAD', url, {} , headers);
|
||||
function directHead(url, headers = {}) {
|
||||
return directRequest('HEAD', url, {}, headers);
|
||||
}
|
||||
|
||||
function directOptions (url, headers ={}) {
|
||||
return directRequest('OPTIONS', url, {}, headers);
|
||||
function directOptions(url, headers = {}) {
|
||||
return directRequest('OPTIONS', url, {}, headers);
|
||||
}
|
||||
|
||||
function proxyWs (url) {
|
||||
return doWebSocket(url, true);
|
||||
function proxyWs(url) {
|
||||
return doWebSocket(url, true);
|
||||
}
|
||||
|
||||
function directWs (url) {
|
||||
return doWebSocket(url);
|
||||
function directWs(url) {
|
||||
return doWebSocket(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* generate the final url based on protocol and path
|
||||
*
|
||||
*/
|
||||
function generateUrl (protocol, urlPath) {
|
||||
return protocol === 'http' ? HTTP_SERVER_BASE + urlPath : HTTPS_SERVER_BASE + urlPath;
|
||||
function generateUrl(protocol, urlPath) {
|
||||
return protocol === 'http' ? HTTP_SERVER_BASE + urlPath : HTTPS_SERVER_BASE + urlPath;
|
||||
}
|
||||
|
||||
function generateWsUrl (protocol, urlPath) {
|
||||
return protocol === 'wss' ? WSS_SERVER_BASE + urlPath : WS_SERVER_BASE + urlPath;
|
||||
function generateWsUrl(protocol, urlPath) {
|
||||
return protocol === 'wss' ? WSS_SERVER_BASE + urlPath : WS_SERVER_BASE + urlPath;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify if the request data is a valid proxy request, by checking specified header
|
||||
*/
|
||||
function isViaProxy(req) {
|
||||
return req.headers['via-proxy'] === 'true';
|
||||
}
|
||||
|
||||
/*
|
||||
* check if url is supported by request moudle
|
||||
*/
|
||||
function isSupportedProtocol(requestPath) {
|
||||
return requestPath.indexOf('http://') === 0 || requestPath.indexOf('https://') === 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* collect all request data in one url
|
||||
*/
|
||||
function getRequestListFromPage(pageUrl, cb) {
|
||||
let _ph;
|
||||
let _page;
|
||||
let _outObj;
|
||||
const phantom = require('phantom');
|
||||
console.log(`collecting requests from ${pageUrl}...`);
|
||||
return phantom.create().then(ph => {
|
||||
_ph = ph;
|
||||
return _ph.createPage();
|
||||
}).then(page => {
|
||||
_page = page;
|
||||
_outObj = _ph.createOutObject();
|
||||
_outObj.urls = [];
|
||||
page.property('onResourceRequested', function (requestData, networkRequest, out) {
|
||||
out.urls.push(requestData);
|
||||
}, _outObj);
|
||||
return _page.open(pageUrl);
|
||||
})
|
||||
.then(status => _outObj.property('urls'))
|
||||
.then(urls => {
|
||||
_page.close();
|
||||
_ph.exit();
|
||||
return urls;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(`failed to collecting requests from ${pageUrl}`);
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
proxyGet,
|
||||
proxyPost,
|
||||
directGet,
|
||||
directPost,
|
||||
directUpload,
|
||||
proxyUpload,
|
||||
generateUrl,
|
||||
proxyWs,
|
||||
directWs,
|
||||
generateWsUrl,
|
||||
directPut,
|
||||
proxyPut,
|
||||
directDelete,
|
||||
proxyDelete,
|
||||
directHead,
|
||||
proxyHead,
|
||||
directOptions,
|
||||
proxyOptions,
|
||||
directPutUpload,
|
||||
proxyPutUpload
|
||||
};
|
||||
getHostFromUrl,
|
||||
getPathFromUrl,
|
||||
getPortFromUrl,
|
||||
proxyGet,
|
||||
proxyPost,
|
||||
directGet,
|
||||
directPost,
|
||||
directUpload,
|
||||
proxyUpload,
|
||||
generateUrl,
|
||||
proxyWs,
|
||||
directWs,
|
||||
generateWsUrl,
|
||||
directPut,
|
||||
proxyPut,
|
||||
directDelete,
|
||||
proxyDelete,
|
||||
directHead,
|
||||
proxyHead,
|
||||
directOptions,
|
||||
proxyOptions,
|
||||
directPutUpload,
|
||||
proxyPutUpload,
|
||||
isViaProxy,
|
||||
getRequestListFromPage,
|
||||
directRequest,
|
||||
proxyRequest,
|
||||
isSupportedProtocol
|
||||
};
|
||||
|
||||
@@ -3,33 +3,36 @@
|
||||
*
|
||||
*/
|
||||
|
||||
let proxy = require('../../proxy.js');
|
||||
const util = require('../../lib/util.js');
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
type: "http",
|
||||
port: 8001,
|
||||
hostname: "localhost",
|
||||
dbFile: null, // optional, save request data to a specified file, will use in-memory db if not specified
|
||||
type: 'http',
|
||||
port: 8001,
|
||||
webInterface: {
|
||||
enable: true,
|
||||
webPort: 8002, // optional, port for web interface
|
||||
socketPort: 8003, // optional, internal port for web socket, replace this when it is conflict with your own service
|
||||
throttle: 10000, // optional, speed limit in kb/s
|
||||
disableWebInterface: false, //optional, set it when you don't want to use the web interface
|
||||
setAsGlobalProxy: false, //set anyproxy as your system proxy
|
||||
interceptHttps: true, // intercept https as well
|
||||
silent: false //optional, do not print anything into terminal. do not set it when you are still debugging.
|
||||
wsPort: 8003, // optional, internal port for web socket
|
||||
},
|
||||
throttle: 10000, // optional, speed limit in kb/s
|
||||
forceProxyHttps: true, // intercept https as well
|
||||
dangerouslyIgnoreUnauthorized: true,
|
||||
silent: false //optional, do not print anything into terminal. do not set it when you are still debugging.
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @return An instance of proxy, could be closed by calling `instance.close()`
|
||||
*/
|
||||
function defaultProxyServer () {
|
||||
proxy = util.freshRequire('../proxy.js');
|
||||
function defaultProxyServer() {
|
||||
const AnyProxy = util.freshRequire('../proxy.js');
|
||||
|
||||
const options = util.merge({}, DEFAULT_OPTIONS);
|
||||
options.rule = util.freshRequire('./rule_default.js');
|
||||
return new proxy.proxyServer(options);
|
||||
const options = util.merge({}, DEFAULT_OPTIONS);
|
||||
const instance = new AnyProxy.ProxyServer(options);
|
||||
instance.on('error', e => {
|
||||
console.log('server instance error', e);
|
||||
});
|
||||
instance.start();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -38,28 +41,40 @@ function defaultProxyServer () {
|
||||
Object, the rule object which contains required intercept method
|
||||
@return An instance of proxy, could be closed by calling `instance.close()`
|
||||
*/
|
||||
function proxyServerWithRule (rule) {
|
||||
proxy = util.freshRequire('../proxy.js');
|
||||
function proxyServerWithRule(rule, overrideConfig) {
|
||||
const AnyProxy = util.freshRequire('../proxy.js');
|
||||
|
||||
const options = util.merge({}, DEFAULT_OPTIONS);
|
||||
options.rule = rule;
|
||||
const options = Object.assign({}, DEFAULT_OPTIONS, overrideConfig);
|
||||
options.rule = rule;
|
||||
|
||||
return new proxy.proxyServer(options);
|
||||
const instance = new AnyProxy.ProxyServer(options);
|
||||
instance.on('error', e => {
|
||||
console.log('server instance error', e);
|
||||
});
|
||||
instance.start();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
function proxyServerWithoutHttpsIntercept (rule) {
|
||||
proxy = util.freshRequire('../proxy.js');
|
||||
function proxyServerWithoutHttpsIntercept(rule) {
|
||||
const AnyProxy = util.freshRequire('../proxy.js');
|
||||
|
||||
const options = util.merge({}, DEFAULT_OPTIONS);
|
||||
if (rule) {
|
||||
options.rule = rule;
|
||||
}
|
||||
options.interceptHttps = false;
|
||||
return new proxy.proxyServer(options);
|
||||
const options = util.merge({}, DEFAULT_OPTIONS);
|
||||
if (rule) {
|
||||
options.rule = rule;
|
||||
}
|
||||
options.forceProxyHttps = false;
|
||||
|
||||
const instance = new AnyProxy.ProxyServer(options);
|
||||
instance.on('error', e => {
|
||||
console.log('server instance error', e);
|
||||
});
|
||||
instance.start();
|
||||
return instance;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
defaultProxyServer,
|
||||
proxyServerWithoutHttpsIntercept,
|
||||
proxyServerWithRule
|
||||
};
|
||||
defaultProxyServer,
|
||||
proxyServerWithoutHttpsIntercept,
|
||||
proxyServerWithRule
|
||||
};
|
||||
|
||||
0
test/util/SimHash.js
Normal file
0
test/util/SimHash.js
Normal file
Reference in New Issue
Block a user