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,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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user