mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-05-10 06:48:26 +00:00
feat: refact the remaining files into TS
This commit is contained in:
parent
bcb7451579
commit
0385096857
@ -8,11 +8,13 @@ import util from './util';
|
|||||||
import logUtil from './log';
|
import logUtil from './log';
|
||||||
|
|
||||||
declare interface ICertMgr {
|
declare interface ICertMgr {
|
||||||
ifRootCAFileExists?: boolean;
|
|
||||||
generateRootCA?: ( cb: (error: boolean, keyPath: string, crtPath: string) => void ) => void;
|
generateRootCA?: ( cb: (error: boolean, keyPath: string, crtPath: string) => void ) => void;
|
||||||
getCAStatus?: () => Generator;
|
getCAStatus?: () => Generator;
|
||||||
trustRootCA?: () => Generator;
|
trustRootCA?: () => Generator;
|
||||||
getRootCAFilePath?: () => string;
|
getRootCAFilePath?: () => string;
|
||||||
|
ifRootCAFileExists?: () => boolean;
|
||||||
|
isRootCAFileExists?: () => boolean;
|
||||||
|
getRootDirPath?: () => string;
|
||||||
getCertificate?: (serverName: string, cb: (err: Error, key: string, crt: string) => void) => void;
|
getCertificate?: (serverName: string, cb: (err: Error, key: string, crt: string) => void) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
lib/proxy/index.ts
Normal file
15
lib/proxy/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import ProxyCore from './proxyCore';
|
||||||
|
import ProxyServer from './proxyServer';
|
||||||
|
import WebInterface from '../webInterface';
|
||||||
|
import Recorder from '../recorder';
|
||||||
|
import certMgr from '../certMgr';
|
||||||
|
|
||||||
|
|
||||||
|
module.exports.ProxyCore = ProxyCore;
|
||||||
|
module.exports.ProxyServer = ProxyServer;
|
||||||
|
module.exports.ProxyRecorder = Recorder;
|
||||||
|
module.exports.ProxyWebServer = WebInterface;
|
||||||
|
module.exports.utils = {
|
||||||
|
systemProxyMgr: require('../systemProxyMgr'),
|
||||||
|
certMgr,
|
||||||
|
};
|
@ -1,41 +1,28 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
/*tslint:disable:max-line-length */
|
||||||
|
|
||||||
const http = require('http'),
|
import * as http from 'http';
|
||||||
https = require('https'),
|
import * as https from 'https';
|
||||||
async = require('async'),
|
import * as async from 'async';
|
||||||
color = require('colorful'),
|
import * as color from 'colorful';
|
||||||
certMgr = require('./certMgr').default,
|
import * as events from 'events';
|
||||||
Recorder = require('./recorder').default,
|
import * as throttle from 'stream-throttle';
|
||||||
logUtil = require('./log').default,
|
import * as co from 'co';
|
||||||
util = require('./util').default,
|
import certMgr from '../certMgr';
|
||||||
events = require('events'),
|
import Recorder from '../recorder';
|
||||||
co = require('co'),
|
import logUtil from '../log';
|
||||||
WebInterface = require('./webInterface'),
|
import util from '../util';
|
||||||
wsServerMgr = require('./wsServerMgr').default,
|
import RequestHandler from '../requestHandler';
|
||||||
ThrottleGroup = require('stream-throttle').ThrottleGroup;
|
import wsServerMgr from '../wsServerMgr';
|
||||||
|
import WebInterface from '../webInterface';
|
||||||
|
|
||||||
// const memwatch = require('memwatch-next');
|
declare type TSyncTaskCb = (err: Error) => void;
|
||||||
|
|
||||||
// setInterval(() => {
|
const ThrottleGroup = throttle.ThrottleGroup;
|
||||||
// console.log(process.memoryUsage());
|
|
||||||
// const rss = Math.ceil(process.memoryUsage().rss / 1000 / 1000);
|
|
||||||
// console.log('Program is using ' + rss + ' mb of Heap.');
|
|
||||||
// }, 1000);
|
|
||||||
|
|
||||||
// memwatch.on('stats', (info) => {
|
const T_TYPE_HTTP = 'http';
|
||||||
// console.log('gc !!');
|
const T_TYPE_HTTPS = 'https';
|
||||||
// console.log(process.memoryUsage());
|
const DEFAULT_TYPE = T_TYPE_HTTP;
|
||||||
// const rss = Math.ceil(process.memoryUsage().rss / 1000 / 1000);
|
|
||||||
// console.log('GC !! Program is using ' + rss + ' mb of Heap.');
|
|
||||||
|
|
||||||
// // var heapUsed = Math.ceil(process.memoryUsage().heapUsed / 1000);
|
|
||||||
// // console.log("Program is using " + heapUsed + " kb of Heap.");
|
|
||||||
// // console.log(info);
|
|
||||||
// });
|
|
||||||
|
|
||||||
const T_TYPE_HTTP = 'http',
|
|
||||||
T_TYPE_HTTPS = 'https',
|
|
||||||
DEFAULT_TYPE = T_TYPE_HTTP;
|
|
||||||
|
|
||||||
const PROXY_STATUS_INIT = 'INIT';
|
const PROXY_STATUS_INIT = 'INIT';
|
||||||
const PROXY_STATUS_READY = 'READY';
|
const PROXY_STATUS_READY = 'READY';
|
||||||
@ -47,25 +34,24 @@ const PROXY_STATUS_CLOSED = 'CLOSED';
|
|||||||
* @extends {events.EventEmitter}
|
* @extends {events.EventEmitter}
|
||||||
*/
|
*/
|
||||||
class ProxyCore extends events.EventEmitter {
|
class ProxyCore extends events.EventEmitter {
|
||||||
|
private socketIndex: number;
|
||||||
|
private status: 'INIT' | 'READY' | 'CLOSED';
|
||||||
|
private proxyPort: string;
|
||||||
|
private proxyType: 'http' | 'https';
|
||||||
|
protected proxyHostName: string;
|
||||||
|
public recorder: Recorder;
|
||||||
|
private httpProxyServer: http.Server | https.Server;
|
||||||
|
protected webServerInstance: WebInterface;
|
||||||
|
private requestHandler: RequestHandler;
|
||||||
|
private proxyRule: AnyProxyRule;
|
||||||
|
private socketPool: {
|
||||||
|
[key: string]: http.IncomingMessage;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Creates an instance of ProxyCore.
|
* Creates an instance of ProxyCore.
|
||||||
*
|
|
||||||
* @param {object} config - configs
|
|
||||||
* @param {number} config.port - port of the proxy server
|
|
||||||
* @param {object} [config.rule=null] - rule module to use
|
|
||||||
* @param {string} [config.type=http] - type of the proxy server, could be 'http' or 'https'
|
|
||||||
* @param {strign} [config.hostname=localhost] - host name of the proxy server, required when this is an https proxy
|
|
||||||
* @param {number} [config.throttle] - speed limit in kb/s
|
|
||||||
* @param {boolean} [config.forceProxyHttps=false] - if proxy all https requests
|
|
||||||
* @param {boolean} [config.silent=false] - if keep the console silent
|
|
||||||
* @param {boolean} [config.dangerouslyIgnoreUnauthorized=false] - if ignore unauthorized server response
|
|
||||||
* @param {object} [config.recorder] - recorder to use
|
|
||||||
* @param {boolean} [config.wsIntercept] - whether intercept websocket
|
|
||||||
*
|
|
||||||
* @memberOf ProxyCore
|
* @memberOf ProxyCore
|
||||||
*/
|
*/
|
||||||
constructor(config) {
|
constructor(config: AnyProxyConfig) {
|
||||||
super();
|
super();
|
||||||
config = config || {};
|
config = config || {};
|
||||||
|
|
||||||
@ -114,12 +100,12 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
this.recorder = config.recorder;
|
this.recorder = config.recorder;
|
||||||
|
|
||||||
// init request handler
|
// init request handler
|
||||||
const RequestHandler = util.freshRequire('./requestHandler').default;
|
const RequestHandlerClass = (util.freshRequire('./requestHandler') as any).default;
|
||||||
this.requestHandler = new RequestHandler({
|
this.requestHandler = new RequestHandlerClass({
|
||||||
wsIntercept: config.wsIntercept,
|
wsIntercept: config.wsIntercept,
|
||||||
httpServerPort: config.port, // the http server port for http proxy
|
httpServerPort: config.port, // the http server port for http proxy
|
||||||
forceProxyHttps: !!config.forceProxyHttps,
|
forceProxyHttps: !!config.forceProxyHttps,
|
||||||
dangerouslyIgnoreUnauthorized: !!config.dangerouslyIgnoreUnauthorized
|
dangerouslyIgnoreUnauthorized: !!config.dangerouslyIgnoreUnauthorized,
|
||||||
}, this.proxyRule, this.recorder);
|
}, this.proxyRule, this.recorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +119,7 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
* @returns undefined
|
* @returns undefined
|
||||||
* @memberOf ProxyCore
|
* @memberOf ProxyCore
|
||||||
*/
|
*/
|
||||||
handleExistConnections(socket) {
|
private handleExistConnections(socket: http.IncomingMessage): void {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.socketIndex ++;
|
self.socketIndex ++;
|
||||||
const key = `socketIndex_${self.socketIndex}`;
|
const key = `socketIndex_${self.socketIndex}`;
|
||||||
@ -151,7 +137,7 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
*
|
*
|
||||||
* @memberOf ProxyCore
|
* @memberOf ProxyCore
|
||||||
*/
|
*/
|
||||||
start() {
|
public start(): ProxyCore {
|
||||||
const self = this;
|
const self = this;
|
||||||
self.socketIndex = 0;
|
self.socketIndex = 0;
|
||||||
self.socketPool = {};
|
self.socketPool = {};
|
||||||
@ -161,8 +147,8 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
}
|
}
|
||||||
async.series(
|
async.series(
|
||||||
[
|
[
|
||||||
//creat proxy server
|
// creat proxy server
|
||||||
function (callback) {
|
function(callback: TSyncTaskCb): void {
|
||||||
if (self.proxyType === T_TYPE_HTTPS) {
|
if (self.proxyType === T_TYPE_HTTPS) {
|
||||||
certMgr.getCertificate(self.proxyHostName, (err, keyContent, crtContent) => {
|
certMgr.getCertificate(self.proxyHostName, (err, keyContent, crtContent) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -170,7 +156,7 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
} else {
|
} else {
|
||||||
self.httpProxyServer = https.createServer({
|
self.httpProxyServer = https.createServer({
|
||||||
key: keyContent,
|
key: keyContent,
|
||||||
cert: crtContent
|
cert: crtContent,
|
||||||
}, self.requestHandler.userRequestHandler);
|
}, self.requestHandler.userRequestHandler);
|
||||||
callback(null);
|
callback(null);
|
||||||
}
|
}
|
||||||
@ -181,17 +167,17 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
//handle CONNECT request for https over http
|
// handle CONNECT request for https over http
|
||||||
function (callback) {
|
function(callback: TSyncTaskCb): void {
|
||||||
self.httpProxyServer.on('connect', self.requestHandler.connectReqHandler);
|
self.httpProxyServer.on('connect', self.requestHandler.connectReqHandler);
|
||||||
|
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
function (callback) {
|
function(callback: TSyncTaskCb): void {
|
||||||
wsServerMgr.getWsServer({
|
wsServerMgr.getWsServer({
|
||||||
server: self.httpProxyServer,
|
server: self.httpProxyServer,
|
||||||
connHandler: self.requestHandler.wsHandler
|
connHandler: self.requestHandler.wsHandler,
|
||||||
});
|
});
|
||||||
// remember all sockets, so we can destory them when call the method 'close';
|
// remember all sockets, so we can destory them when call the method 'close';
|
||||||
self.httpProxyServer.on('connection', (socket) => {
|
self.httpProxyServer.on('connection', (socket) => {
|
||||||
@ -200,14 +186,14 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
//start proxy server
|
// start proxy server
|
||||||
function (callback) {
|
function(callback: TSyncTaskCb): void {
|
||||||
self.httpProxyServer.listen(self.proxyPort);
|
self.httpProxyServer.listen(self.proxyPort);
|
||||||
callback(null);
|
callback(null);
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
//final callback
|
// final callback
|
||||||
(err, result) => {
|
(err, result) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
const tipText = (self.proxyType === T_TYPE_HTTP ? 'Http' : 'Https') + ' proxy started on port ' + self.proxyPort;
|
const tipText = (self.proxyType === T_TYPE_HTTP ? 'Http' : 'Https') + ' proxy started on port ' + self.proxyPort;
|
||||||
@ -221,7 +207,7 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
let ruleSummaryString = '';
|
let ruleSummaryString = '';
|
||||||
const ruleSummary = this.proxyRule.summary;
|
const ruleSummary = this.proxyRule.summary;
|
||||||
if (ruleSummary) {
|
if (ruleSummary) {
|
||||||
co(function *() {
|
co(function *(): Generator {
|
||||||
if (typeof ruleSummary === 'string') {
|
if (typeof ruleSummary === 'string') {
|
||||||
ruleSummaryString = ruleSummary;
|
ruleSummaryString = ruleSummary;
|
||||||
} else {
|
} else {
|
||||||
@ -239,10 +225,10 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
logUtil.printLog(color.red(tipText), logUtil.T_ERR);
|
logUtil.printLog(color.red(tipText), logUtil.T_ERR);
|
||||||
logUtil.printLog(err, logUtil.T_ERR);
|
logUtil.printLog(err, logUtil.T_ERR);
|
||||||
self.emit('error', {
|
self.emit('error', {
|
||||||
error: err
|
error: err,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@ -256,24 +242,34 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
*
|
*
|
||||||
* @memberOf ProxyCore
|
* @memberOf ProxyCore
|
||||||
*/
|
*/
|
||||||
close() {
|
public close(): Promise<Error> {
|
||||||
// clear recorder cache
|
// clear recorder cache
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
if (this.httpProxyServer) {
|
if (this.httpProxyServer) {
|
||||||
// destroy conns & cltSockets when closing proxy server
|
// destroy conns & cltSockets when closing proxy server
|
||||||
for (const connItem of this.requestHandler.conns) {
|
this.requestHandler.conns.forEach((conn, key) => {
|
||||||
const key = connItem[0];
|
|
||||||
const conn = connItem[1];
|
|
||||||
logUtil.printLog(`destorying https connection : ${key}`);
|
logUtil.printLog(`destorying https connection : ${key}`);
|
||||||
conn.end();
|
conn.end();
|
||||||
}
|
});
|
||||||
|
|
||||||
for (const cltSocketItem of this.requestHandler.cltSockets) {
|
this.requestHandler.cltSockets.forEach((cltSocket, key) => {
|
||||||
const key = cltSocketItem[0];
|
|
||||||
const cltSocket = cltSocketItem[1];
|
|
||||||
logUtil.printLog(`endding https cltSocket : ${key}`);
|
logUtil.printLog(`endding https cltSocket : ${key}`);
|
||||||
cltSocket.end();
|
cltSocket.end();
|
||||||
}
|
});
|
||||||
|
|
||||||
|
// for (const connItem of this.requestHandler.conns) {
|
||||||
|
// const key = connItem[0];
|
||||||
|
// const conn = connItem[1];
|
||||||
|
// logUtil.printLog(`destorying https connection : ${key}`);
|
||||||
|
// conn.end();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (const cltSocketItem of this.requestHandler.cltSockets) {
|
||||||
|
// const key = cltSocketItem[0];
|
||||||
|
// const cltSocket = cltSocketItem[1];
|
||||||
|
// logUtil.printLog(`endding https cltSocket : ${key}`);
|
||||||
|
// cltSocket.end();
|
||||||
|
// }
|
||||||
|
|
||||||
if (this.socketPool) {
|
if (this.socketPool) {
|
||||||
for (const key in this.socketPool) {
|
for (const key in this.socketPool) {
|
||||||
@ -296,92 +292,8 @@ class ProxyCore extends events.EventEmitter {
|
|||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* start proxy server as well as recorder and webInterface
|
|
||||||
*/
|
|
||||||
class ProxyServer extends ProxyCore {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {object} config - config
|
|
||||||
* @param {object} [config.webInterface] - config of the web interface
|
|
||||||
* @param {boolean} [config.webInterface.enable=false] - if web interface is enabled
|
|
||||||
* @param {number} [config.webInterface.webPort=8002] - http port of the web interface
|
|
||||||
*/
|
|
||||||
constructor(config) {
|
|
||||||
// prepare a recorder
|
|
||||||
const recorder = new Recorder();
|
|
||||||
const configForCore = Object.assign({
|
|
||||||
recorder,
|
|
||||||
}, config);
|
|
||||||
|
|
||||||
super(configForCore);
|
|
||||||
|
|
||||||
this.proxyWebinterfaceConfig = config.webInterface;
|
|
||||||
this.recorder = recorder;
|
|
||||||
this.webServerInstance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
// start web interface if neeeded
|
|
||||||
if (this.proxyWebinterfaceConfig && this.proxyWebinterfaceConfig.enable) {
|
|
||||||
this.webServerInstance = new WebInterface(this.proxyWebinterfaceConfig, this.recorder);
|
|
||||||
// start web server
|
|
||||||
this.webServerInstance.start().then(() => {
|
|
||||||
// start proxy core
|
|
||||||
super.start();
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
this.emit('error', e);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
super.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
super.close()
|
|
||||||
.then((error) => {
|
|
||||||
if (error) {
|
|
||||||
resolve(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.recorder) {
|
|
||||||
logUtil.printLog('clearing cache file...');
|
|
||||||
this.recorder.clear();
|
|
||||||
}
|
|
||||||
const tmpWebServer = this.webServerInstance;
|
|
||||||
this.recorder = null;
|
|
||||||
this.webServerInstance = null;
|
|
||||||
if (tmpWebServer) {
|
|
||||||
logUtil.printLog('closing webserver...');
|
|
||||||
tmpWebServer.close((error) => {
|
|
||||||
if (error) {
|
|
||||||
console.error(error);
|
|
||||||
logUtil.printLog(`proxy web server close FAILED: ${error.message}`, logUtil.T_ERR);
|
|
||||||
} else {
|
|
||||||
logUtil.printLog(`proxy web server closed at ${this.proxyHostName} : ${this.webPort}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(error);
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
resolve(null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.ProxyCore = ProxyCore;
|
export default ProxyCore;
|
||||||
module.exports.ProxyServer = ProxyServer;
|
|
||||||
module.exports.ProxyRecorder = Recorder;
|
|
||||||
module.exports.ProxyWebServer = WebInterface;
|
|
||||||
module.exports.utils = {
|
|
||||||
systemProxyMgr: require('./systemProxyMgr'),
|
|
||||||
certMgr,
|
|
||||||
};
|
|
87
lib/proxy/proxyServer.ts
Normal file
87
lib/proxy/proxyServer.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import ProxyCore from './proxyCore.js';
|
||||||
|
import Recorder from '../recorder';
|
||||||
|
import WebInterface from '../webInterface';
|
||||||
|
import logUtil from '../log';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* start proxy server as well as recorder and webInterface
|
||||||
|
*/
|
||||||
|
class ProxyServer extends ProxyCore {
|
||||||
|
public proxyWebinterfaceConfig: any;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} config - config
|
||||||
|
* @param {object} [config.webInterface] - config of the web interface
|
||||||
|
* @param {boolean} [config.webInterface.enable=false] - if web interface is enabled
|
||||||
|
* @param {number} [config.webInterface.webPort=8002] - http port of the web interface
|
||||||
|
*/
|
||||||
|
constructor(config: AnyProxyConfig) {
|
||||||
|
// prepare a recorder
|
||||||
|
const recorder = new Recorder();
|
||||||
|
const configForCore = Object.assign({
|
||||||
|
recorder,
|
||||||
|
}, config);
|
||||||
|
|
||||||
|
super(configForCore);
|
||||||
|
|
||||||
|
this.proxyWebinterfaceConfig = config.webInterface;
|
||||||
|
this.recorder = recorder;
|
||||||
|
this.webServerInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public start(): ProxyServer {
|
||||||
|
// start web interface if neeeded
|
||||||
|
if (this.proxyWebinterfaceConfig && this.proxyWebinterfaceConfig.enable) {
|
||||||
|
this.webServerInstance = new WebInterface(this.proxyWebinterfaceConfig, this.recorder);
|
||||||
|
// start web server
|
||||||
|
this.webServerInstance.start().then(() => {
|
||||||
|
// start proxy core
|
||||||
|
super.start();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
this.emit('error', e);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public close(): Promise<Error> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
super.close()
|
||||||
|
.then((error) => {
|
||||||
|
if (error) {
|
||||||
|
resolve(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.recorder) {
|
||||||
|
logUtil.printLog('clearing cache file...');
|
||||||
|
this.recorder.clear();
|
||||||
|
}
|
||||||
|
const tmpWebServer = this.webServerInstance;
|
||||||
|
this.recorder = null;
|
||||||
|
this.webServerInstance = null;
|
||||||
|
if (tmpWebServer) {
|
||||||
|
logUtil.printLog('closing webserver...');
|
||||||
|
tmpWebServer.close((error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
logUtil.printLog(`proxy web server close FAILED: ${error.message}`, logUtil.T_ERR);
|
||||||
|
} else {
|
||||||
|
logUtil.printLog(`proxy web server closed at ${this.proxyHostName} : ${this.proxyWebinterfaceConfig.webPort}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProxyServer;
|
@ -412,9 +412,11 @@ class RequestHandler {
|
|||||||
public dangerouslyIgnoreUnauthorized: boolean;
|
public dangerouslyIgnoreUnauthorized: boolean;
|
||||||
public httpServerPort: string;
|
public httpServerPort: string;
|
||||||
public wsIntercept: boolean;
|
public wsIntercept: boolean;
|
||||||
|
public conns: Map<string, net.Socket>;
|
||||||
|
public cltSockets: Map<string, net.Socket>;
|
||||||
public connectReqHandler: () => void;
|
public connectReqHandler: () => void;
|
||||||
private userRequestHandler: () => void;
|
public userRequestHandler: () => void;
|
||||||
private wsHandler: (wsClient: WebSocket, wsReq: http.IncomingMessage) => void;
|
public wsHandler: (wsClient: WebSocket, wsReq: http.IncomingMessage) => void;
|
||||||
private httpsServerMgr: HttpsServerMgr;
|
private httpsServerMgr: HttpsServerMgr;
|
||||||
/**
|
/**
|
||||||
* Creates an instance of RequestHandler.
|
* Creates an instance of RequestHandler.
|
||||||
|
@ -309,7 +309,7 @@ function isFunc(source: object): boolean {
|
|||||||
* @param {object} content
|
* @param {object} content
|
||||||
* @returns the size of the content
|
* @returns the size of the content
|
||||||
*/
|
*/
|
||||||
function getByteSize(content: Buffer): number {
|
function getByteSize(content: Buffer | string): number {
|
||||||
return Buffer.byteLength(content);
|
return Buffer.byteLength(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,22 +2,44 @@
|
|||||||
|
|
||||||
const DEFAULT_WEB_PORT = 8002; // port for web interface
|
const DEFAULT_WEB_PORT = 8002; // port for web interface
|
||||||
|
|
||||||
const express = require('express'),
|
import * as express from 'express';
|
||||||
url = require('url'),
|
import * as url from 'url';
|
||||||
bodyParser = require('body-parser'),
|
import * as bodyParser from 'body-parser';
|
||||||
fs = require('fs'),
|
import * as fs from 'fs';
|
||||||
path = require('path'),
|
import * as path from 'path';
|
||||||
events = require('events'),
|
import * as events from 'events';
|
||||||
qrCode = require('qrcode-npm'),
|
import * as qrCode from 'qrcode-npm';
|
||||||
util = require('./util').default,
|
import * as juicer from 'juicer';
|
||||||
certMgr = require('./certMgr').default,
|
import * as ip from 'ip';
|
||||||
wsServer = require('./wsServer'),
|
import * as http from 'http';
|
||||||
juicer = require('juicer'),
|
import * as compress from 'compression';
|
||||||
ip = require('ip'),
|
import * as buffer from 'buffer';
|
||||||
compress = require('compression');
|
import util from './util';
|
||||||
|
import certMgr from './certMgr';
|
||||||
|
import WsServer from './wsServer';
|
||||||
|
import Recorder from './recorder';
|
||||||
|
import LogUtil from './log';
|
||||||
|
|
||||||
|
/*tslint:disable:no-var-requires*/
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
|
|
||||||
|
// const express = require('express'),
|
||||||
|
// url = require('url'),
|
||||||
|
// bodyParser = require('body-parser'),
|
||||||
|
// fs = require('fs'),
|
||||||
|
// path = require('path'),
|
||||||
|
// events = require('events'),
|
||||||
|
// qrCode = require('qrcode-npm'),
|
||||||
|
// util = require('./util').default,
|
||||||
|
// certMgr = require('./certMgr').default,
|
||||||
|
// wsServer = require('./wsServer'),
|
||||||
|
// juicer = require('juicer'),
|
||||||
|
// ip = require('ip'),
|
||||||
|
// compress = require('compression');
|
||||||
|
|
||||||
|
// const packageJson = require('../package.json');
|
||||||
|
|
||||||
|
const Buffer = buffer.Buffer;
|
||||||
const MAX_CONTENT_SIZE = 1024 * 2000; // 2000kb
|
const MAX_CONTENT_SIZE = 1024 * 2000; // 2000kb
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -25,18 +47,13 @@ const MAX_CONTENT_SIZE = 1024 * 2000; // 2000kb
|
|||||||
* @class webInterface
|
* @class webInterface
|
||||||
* @extends {events.EventEmitter}
|
* @extends {events.EventEmitter}
|
||||||
*/
|
*/
|
||||||
class webInterface extends events.EventEmitter {
|
class WebInterface extends events.EventEmitter {
|
||||||
|
public webPort: number;
|
||||||
/**
|
private recorder: Recorder;
|
||||||
* Creates an instance of webInterface.
|
private app: Express.Application;
|
||||||
*
|
private server: http.Server;
|
||||||
* @param {object} config
|
private wsServer: WsServer;
|
||||||
* @param {number} config.webPort
|
constructor(config: AnyProxyWebInterfaceConfig, recorder: Recorder) {
|
||||||
* @param {object} recorder
|
|
||||||
*
|
|
||||||
* @memberOf webInterface
|
|
||||||
*/
|
|
||||||
constructor(config, recorder) {
|
|
||||||
if (!recorder) {
|
if (!recorder) {
|
||||||
throw new Error('recorder is required for web interface');
|
throw new Error('recorder is required for web interface');
|
||||||
}
|
}
|
||||||
@ -44,7 +61,7 @@ class webInterface extends events.EventEmitter {
|
|||||||
const self = this;
|
const self = this;
|
||||||
self.webPort = config.webPort || DEFAULT_WEB_PORT;
|
self.webPort = config.webPort || DEFAULT_WEB_PORT;
|
||||||
self.recorder = recorder;
|
self.recorder = recorder;
|
||||||
self.config = config || {};
|
// self.config = config || {};
|
||||||
|
|
||||||
self.app = this.getServer();
|
self.app = this.getServer();
|
||||||
self.server = null;
|
self.server = null;
|
||||||
@ -54,25 +71,25 @@ class webInterface extends events.EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* get the express server
|
* get the express server
|
||||||
*/
|
*/
|
||||||
getServer() {
|
public getServer(): Express.Application {
|
||||||
const self = this;
|
const self = this;
|
||||||
const recorder = self.recorder;
|
const recorder = self.recorder;
|
||||||
const ipAddress = ip.address(),
|
const ipAddress = ip.address();
|
||||||
// userRule = proxyInstance.proxyRule,
|
// userRule = proxyInstance.proxyRule,
|
||||||
webBasePath = 'web';
|
const webBasePath = 'web';
|
||||||
let ruleSummary = '';
|
let ruleSummary = '';
|
||||||
let customMenu = [];
|
let customMenu = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ruleSummary = ''; //userRule.summary();
|
ruleSummary = ''; // userRule.summary();
|
||||||
customMenu = ''; // userRule._getCustomMenu();
|
customMenu = []; // userRule._getCustomMenu();
|
||||||
} catch (e) { }
|
} catch (e) { LogUtil.error(e.stack); }
|
||||||
|
|
||||||
const myAbsAddress = 'http://' + ipAddress + ':' + self.webPort + '/',
|
const myAbsAddress = 'http://' + ipAddress + ':' + self.webPort + '/';
|
||||||
staticDir = path.join(__dirname, '../', webBasePath);
|
const staticDir = path.join(__dirname, '../', webBasePath);
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(compress()); //invoke gzip
|
app.use(compress()); // invoke gzip
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
res.setHeader('note', 'THIS IS A REQUEST FROM ANYPROXY WEB INTERFACE');
|
res.setHeader('note', 'THIS IS A REQUEST FROM ANYPROXY WEB INTERFACE');
|
||||||
return next();
|
return next();
|
||||||
@ -97,7 +114,7 @@ class webInterface extends events.EventEmitter {
|
|||||||
res.json({});
|
res.json({});
|
||||||
} else if (result.mime) {
|
} else if (result.mime) {
|
||||||
if (query.raw === 'true') {
|
if (query.raw === 'true') {
|
||||||
//TODO : cache query result
|
// TODO : cache query result
|
||||||
res.type(result.mime).end(result.content);
|
res.type(result.mime).end(result.content);
|
||||||
} else if (query.download === 'true') {
|
} else if (query.download === 'true') {
|
||||||
res.setHeader('Content-disposition', `attachment; filename=${result.fileName}`);
|
res.setHeader('Content-disposition', `attachment; filename=${result.fileName}`);
|
||||||
@ -118,21 +135,21 @@ class webInterface extends events.EventEmitter {
|
|||||||
if (query && query.id) {
|
if (query && query.id) {
|
||||||
recorder.getDecodedBody(parseInt(query.id, 10), (err, result) => {
|
recorder.getDecodedBody(parseInt(query.id, 10), (err, result) => {
|
||||||
// 返回下载信息
|
// 返回下载信息
|
||||||
const _resDownload = function (isDownload) {
|
const resDownload = function(isDownload: boolean): void {
|
||||||
isDownload = typeof isDownload === 'boolean' ? isDownload : true;
|
isDownload = typeof isDownload === 'boolean' ? isDownload : true;
|
||||||
res.json({
|
res.json({
|
||||||
id: query.id,
|
id: query.id,
|
||||||
type: result.type,
|
type: result.type,
|
||||||
method: result.meethod,
|
method: result.method,
|
||||||
fileName: result.fileName,
|
fileName: result.fileName,
|
||||||
ref: `/downloadBody?id=${query.id}&download=${isDownload}&raw=${!isDownload}`
|
ref: `/downloadBody?id=${query.id}&download=${isDownload}&raw=${!isDownload}`,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 返回内容
|
// 返回内容
|
||||||
const _resContent = () => {
|
const resContent = () => {
|
||||||
if (util.getByteSize(result.content || '') > MAX_CONTENT_SIZE) {
|
if (util.getByteSize(result.content || Buffer.from('')) > MAX_CONTENT_SIZE) {
|
||||||
_resDownload(true);
|
resDownload(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +157,7 @@ class webInterface extends events.EventEmitter {
|
|||||||
id: query.id,
|
id: query.id,
|
||||||
type: result.type,
|
type: result.type,
|
||||||
method: result.method,
|
method: result.method,
|
||||||
resBody: result.content
|
resBody: result.content,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,14 +168,14 @@ class webInterface extends events.EventEmitter {
|
|||||||
result.mime.indexOf('text') === 0 ||
|
result.mime.indexOf('text') === 0 ||
|
||||||
// deal with 'application/x-javascript' and 'application/javascript'
|
// deal with 'application/x-javascript' and 'application/javascript'
|
||||||
result.mime.indexOf('javascript') > -1) {
|
result.mime.indexOf('javascript') > -1) {
|
||||||
_resContent();
|
resContent();
|
||||||
} else if (result.type === 'image') {
|
} else if (result.type === 'image') {
|
||||||
_resDownload(false);
|
resDownload(false);
|
||||||
} else {
|
} else {
|
||||||
_resDownload(true);
|
resDownload(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_resContent();
|
resContent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -203,49 +220,51 @@ class webInterface extends events.EventEmitter {
|
|||||||
|
|
||||||
app.get('/fetchCrtFile', (req, res) => {
|
app.get('/fetchCrtFile', (req, res) => {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
const _crtFilePath = certMgr.getRootCAFilePath();
|
const crtFilePath = certMgr.getRootCAFilePath();
|
||||||
if (_crtFilePath) {
|
if (crtFilePath) {
|
||||||
res.setHeader('Content-Type', 'application/x-x509-ca-cert');
|
res.setHeader('Content-Type', 'application/x-x509-ca-cert');
|
||||||
res.setHeader('Content-Disposition', 'attachment; filename="rootCA.crt"');
|
res.setHeader('Content-Disposition', 'attachment; filename="rootCA.crt"');
|
||||||
res.end(fs.readFileSync(_crtFilePath, { encoding: null }));
|
res.end(fs.readFileSync(crtFilePath, { encoding: null }));
|
||||||
} else {
|
} else {
|
||||||
res.setHeader('Content-Type', 'text/html');
|
res.setHeader('Content-Type', 'text/html');
|
||||||
res.end('can not file rootCA ,plase use <strong>anyproxy --root</strong> to generate one');
|
res.end('can not file rootCA ,plase use <strong>anyproxy --root</strong> to generate one');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//make qr code
|
// make qr code
|
||||||
app.get('/qr', (req, res) => {
|
app.get('/qr', (req, res) => {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
const qr = qrCode.qrcode(4, 'M'),
|
const qr = qrCode.qrcode(4, 'M');
|
||||||
targetUrl = myAbsAddress;
|
const targetUrl = myAbsAddress;
|
||||||
qr.addData(targetUrl);
|
qr.addData(targetUrl);
|
||||||
qr.make();
|
qr.make();
|
||||||
const qrImageTag = qr.createImgTag(4);
|
const qrImageTag = qr.createImgTag(4);
|
||||||
const resDom = '<a href="__url"> __img <br> click or scan qr code to start client </a>'.replace(/__url/, targetUrl).replace(/__img/, qrImageTag);
|
const resDom = '<a href="__url"> __img <br> click or scan qr code to start client </a>'
|
||||||
|
.replace(/__url/, targetUrl).replace(/__img/, qrImageTag);
|
||||||
res.setHeader('Content-Type', 'text/html');
|
res.setHeader('Content-Type', 'text/html');
|
||||||
res.end(resDom);
|
res.end(resDom);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/api/getQrCode', (req, res) => {
|
app.get('/api/getQrCode', (req, res) => {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
const qr = qrCode.qrcode(4, 'M'),
|
const qr = qrCode.qrcode(4, 'M');
|
||||||
targetUrl = myAbsAddress + 'fetchCrtFile';
|
const targetUrl = myAbsAddress + 'fetchCrtFile';
|
||||||
|
|
||||||
qr.addData(targetUrl);
|
qr.addData(targetUrl);
|
||||||
qr.make();
|
qr.make();
|
||||||
const qrImageTag = qr.createImgTag(4);
|
const qrImageTag = qr.createImgTag(4);
|
||||||
|
|
||||||
// resDom = '<a href="__url"> __img <br> click or scan qr code to download rootCA.crt </a>'.replace(/__url/,targetUrl).replace(/__img/,qrImageTag);
|
// resDom = '<a href="__url"> __img <br> click or scan qr code to download rootCA.crt </a>'
|
||||||
|
// .replace(/__url/,targetUrl).replace(/__img/,qrImageTag);
|
||||||
// res.setHeader("Content-Type", "text/html");
|
// res.setHeader("Content-Type", "text/html");
|
||||||
// res.end(resDom);
|
// res.end(resDom);
|
||||||
|
|
||||||
const isRootCAFileExists = certMgr.isRootCAFileExists();
|
const isRootCAFileExists = certMgr.ifRootCAFileExists();
|
||||||
res.json({
|
res.json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
url: targetUrl,
|
url: targetUrl,
|
||||||
isRootCAFileExists,
|
isRootCAFileExists,
|
||||||
qrImgDom: qrImageTag
|
qrImgDom: qrImageTag,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -254,7 +273,7 @@ class webInterface extends events.EventEmitter {
|
|||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
const rootCAExists = certMgr.isRootCAFileExists();
|
const rootCAExists = certMgr.isRootCAFileExists();
|
||||||
const rootDirPath = certMgr.getRootDirPath();
|
const rootDirPath = certMgr.getRootDirPath();
|
||||||
const interceptFlag = false; //proxyInstance.getInterceptFlag(); TODO
|
const interceptFlag = false; // proxyInstance.getInterceptFlag(); TODO
|
||||||
const globalProxyFlag = false; // TODO: proxyInstance.getGlobalProxyFlag();
|
const globalProxyFlag = false; // TODO: proxyInstance.getGlobalProxyFlag();
|
||||||
res.json({
|
res.json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
@ -264,8 +283,8 @@ class webInterface extends events.EventEmitter {
|
|||||||
currentGlobalProxyFlag: globalProxyFlag,
|
currentGlobalProxyFlag: globalProxyFlag,
|
||||||
ruleSummary: ruleSummary || '',
|
ruleSummary: ruleSummary || '',
|
||||||
ipAddress: util.getAllIpAddress(),
|
ipAddress: util.getAllIpAddress(),
|
||||||
port: '', //proxyInstance.proxyPort, // TODO
|
port: '', // proxyInstance.proxyPort, // TODO
|
||||||
appVersion: packageJson.version
|
appVersion: packageJson.version,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -276,23 +295,23 @@ class webInterface extends events.EventEmitter {
|
|||||||
certMgr.generateRootCA(() => {
|
certMgr.generateRootCA(() => {
|
||||||
res.json({
|
res.json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
code: 'done'
|
code: 'done',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
res.json({
|
res.json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
code: 'root_ca_exists'
|
code: 'root_ca_exists',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const indexTpl = fs.readFileSync(path.join(staticDir, '/index.html'), { encoding: 'utf8' }),
|
const indexTpl = fs.readFileSync(path.join(staticDir, '/index.html'), { encoding: 'utf8' });
|
||||||
opt = {
|
const opt = {
|
||||||
rule: ruleSummary || '',
|
rule: ruleSummary || '',
|
||||||
customMenu: customMenu || [],
|
customMenu: customMenu || [],
|
||||||
ipAddress: ipAddress || '127.0.0.1'
|
ipAddress: ipAddress || '127.0.0.1',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (url.parse(req.url).pathname === '/') {
|
if (url.parse(req.url).pathname === '/') {
|
||||||
@ -306,25 +325,25 @@ class webInterface extends events.EventEmitter {
|
|||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
public start(): Promise<undefined> {
|
||||||
const self = this;
|
const self = this;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
self.server = self.app.listen(self.webPort);
|
self.server = (self.app as any).listen(self.webPort);
|
||||||
self.wsServer = new wsServer({
|
self.wsServer = new WsServer({
|
||||||
server: self.server
|
server: self.server,
|
||||||
}, self.recorder);
|
}, self.recorder);
|
||||||
self.wsServer.start();
|
self.wsServer.start();
|
||||||
resolve();
|
resolve();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
public close(cb: (error: Error) => void): void {
|
||||||
this.server && this.server.close();
|
this.server && this.server.close();
|
||||||
this.wsServer && this.wsServer.closeAll();
|
this.wsServer && this.wsServer.closeAll();
|
||||||
this.server = null;
|
this.server = null;
|
||||||
this.wsServer = null;
|
this.wsServer = null;
|
||||||
this.proxyInstance = null;
|
// this.proxyInstance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = webInterface;
|
export default WebInterface;
|
@ -1,10 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// websocket server manager
|
// websocket server manager, for the webinterface websocket handling
|
||||||
import * as WebSocket from 'ws';
|
import * as WebSocket from 'ws';
|
||||||
import Recorder from './recorder';
|
import Recorder from './recorder';
|
||||||
import logUtil from './log';
|
import logUtil from './log';
|
||||||
import { Server } from 'http';
|
import * as http from 'http';
|
||||||
|
import * as https from 'https';
|
||||||
|
|
||||||
declare interface IWsMessage {
|
declare interface IWsMessage {
|
||||||
type?: 'error' | 'body';
|
type?: 'error' | 'body';
|
||||||
@ -18,7 +19,8 @@ declare interface IWsMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare interface IWsServerConfig {
|
declare interface IWsServerConfig {
|
||||||
server: Server;
|
server: http.Server | https.Server;
|
||||||
|
connHandler?: (wsClient: WebSocket, wsReq: http.IncomingMessage) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface IMultiMessageQueue {
|
declare interface IMultiMessageQueue {
|
||||||
@ -198,4 +200,4 @@ class WsServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = WsServer;
|
export default WsServer;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* manage the websocket server
|
* manage the websocket server, for proxy target only
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
import * as ws from 'ws';
|
import * as ws from 'ws';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
|
import * as https from 'https';
|
||||||
import logUtil from './log.js';
|
import logUtil from './log.js';
|
||||||
|
|
||||||
const WsServer = ws.Server;
|
const WsServer = ws.Server;
|
||||||
@ -15,7 +16,7 @@ const WsServer = ws.Server;
|
|||||||
{handler} config.handler
|
{handler} config.handler
|
||||||
*/
|
*/
|
||||||
function getWsServer(config: {
|
function getWsServer(config: {
|
||||||
server: http.Server;
|
server: http.Server | https.Server;
|
||||||
connHandler: (wsClient: ws, wsReq: http.IncomingMessage) => void;
|
connHandler: (wsClient: ws, wsReq: http.IncomingMessage) => void;
|
||||||
}): ws.Server {
|
}): ws.Server {
|
||||||
const wss = new WsServer({
|
const wss = new WsServer({
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
"ws": "^5.1.0"
|
"ws": "^5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/express": "^4.16.0",
|
||||||
"@types/node": "^8.10.21",
|
"@types/node": "^8.10.21",
|
||||||
"@types/ws": "^6.0.0",
|
"@types/ws": "^6.0.0",
|
||||||
"antd": "^2.5.0",
|
"antd": "^2.5.0",
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
"only-arrow-functions": false,
|
"only-arrow-functions": false,
|
||||||
"no-reference": false,
|
"no-reference": false,
|
||||||
"forin": false,
|
"forin": false,
|
||||||
|
"member-ordering": false,
|
||||||
|
"max-classes-per-file": false,
|
||||||
"typedef": [
|
"typedef": [
|
||||||
true,
|
true,
|
||||||
"call-signature",
|
"call-signature",
|
||||||
|
29
typings/index.d.ts
vendored
29
typings/index.d.ts
vendored
@ -7,17 +7,27 @@ declare module NodeJS {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare interface AnyProxyWebInterfaceConfig {
|
||||||
|
webPort?: number;
|
||||||
|
}
|
||||||
|
|
||||||
declare interface AnyProxyConfig {
|
declare interface AnyProxyConfig {
|
||||||
port: string; // 代理监听端口
|
port?: string; // port of the proxy server
|
||||||
httpServerPort: string; // web server 的端口
|
httpServerPort?: string; // web server 的端口
|
||||||
forceProxyHttps: boolean;
|
type?: 'http' | 'https'; // type of the proxy server
|
||||||
dangerouslyIgnoreUnauthorized: boolean; // 是否忽略https证书
|
forceProxyHttps?: boolean; // proxy https also
|
||||||
wsIntercept: boolean; // 是否代理websocket
|
dangerouslyIgnoreUnauthorized?: boolean; // should ignore
|
||||||
chunkSizeThreshold: number; // throttle的配置
|
wsIntercept?: boolean; // should proxy websocket
|
||||||
|
throttle?: string; // speed limit in kb/s
|
||||||
|
hostname?: string; // the hostname of this proxy, default to 'localhost'
|
||||||
|
recorder?: any; // A Recorder instance
|
||||||
|
silent?: boolean; // if keep the console silent
|
||||||
|
rule?: any; // rule module to use
|
||||||
|
webInterface?: AnyProxyWebInterfaceConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface AnyProxyRule {
|
declare interface AnyProxyRule {
|
||||||
summary?: string,
|
summary?: string | Function,
|
||||||
beforeSendRequest?: Function,
|
beforeSendRequest?: Function,
|
||||||
beforeSendResponse?: Function,
|
beforeSendResponse?: Function,
|
||||||
beforeDealHttpsRequest?: Function,
|
beforeDealHttpsRequest?: Function,
|
||||||
@ -86,4 +96,9 @@ declare interface OneLevelObjectType {
|
|||||||
declare interface IExecScriptResult {
|
declare interface IExecScriptResult {
|
||||||
status: number;
|
status: number;
|
||||||
stdout?: string;
|
stdout?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.json" {
|
||||||
|
const value: any;
|
||||||
|
export default value;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user