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