catproxy
Version:
a node proxy or host change tools
356 lines (291 loc) • 11.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CatProxy = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _http = require('http');
var _http2 = _interopRequireDefault(_http);
var _https = require('https');
var _https2 = _interopRequireDefault(_https);
var _defCfg = require('./config/defCfg');
var _defCfg2 = _interopRequireDefault(_defCfg);
var _config = require('./config/config');
var config = _interopRequireWildcard(_config);
var _merge = require('merge');
var _merge2 = _interopRequireDefault(_merge);
var _promise = require('promise');
var _promise2 = _interopRequireDefault(_promise);
var _log = require('./log');
var _log2 = _interopRequireDefault(_log);
var _requestSerives = require('./requestSerives');
var _events = require('events');
var _events2 = _interopRequireDefault(_events);
var _cert2 = require('./cert/cert.js');
var _httpsProxySer = require('./httpsProxySer');
var _app = require('./web/app');
var _app2 = _interopRequireDefault(_app);
var _getLocalIps = require('./getLocalIps');
var _tools = require('./tools');
var _requestMiddleware = require('./requestMiddleware');
var requestMiddleware = _interopRequireWildcard(_requestMiddleware);
var _configProps = require('./config/configProps');
var _configProps2 = _interopRequireDefault(_configProps);
var _util = require('util');
var _util2 = _interopRequireDefault(_util);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// process.env.NODE_ENV
var CatProxy = function (_EventEmitter) {
_inherits(CatProxy, _EventEmitter);
/**
*
* @param {[type]} option
* {
* type: "当前服务器类型"
* port: "当前http端口",
* httpsPort: "当前https服务器端口",
* certHost: "https证书生成默认host代理",
* crackHttps 是否解开 https请求,在 http代理模式下,
* log: '日志级别',
* uiPort 端口
* }
* @param servers 自定义服务器,最多同时开启2个服务器,一个http一个https, 2个服务器的时候顺序是http,https 如果只有一个则没有顺序问题
*
* @param saveProps 要同步到文件的字段 为空则全部同步
*
*/
function CatProxy(opt, saveProps) {
_classCallCheck(this, CatProxy);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CatProxy).call(this));
_this.option = {};
// 初始化配置文件
(0, config.default)();
var certDir = (0, _cert2.getCertDir)();
_log2.default.info('当前证书目录: ' + certDir);
// 读取缓存配置文件
var fileCfg = {};
_configProps2.default.forEach(function (current) {
var val = config.get(current);
if (val !== undefined && val !== null) {
fileCfg[current] = val;
}
});
if (saveProps === false) {
saveProps = ['hosts', "log", 'breakHttps', 'excludeHttps'];
}
// 混合三种配置
var cfg = (0, _merge2.default)({}, _defCfg2.default, fileCfg, opt);
if (saveProps && saveProps.length) {
_this.option.saveProps = saveProps;
}
// 将用户当前设置保存到缓存配置文件
_configProps2.default.forEach(function (current) {
if (cfg[current] !== null && cfg[current] !== undefined) {
// 为‘’表示要删除这个字段
if (cfg[current] === '' && config.get(current)) {
config.del(current);
} else {
config.set(current, cfg[current]);
}
}
});
if (saveProps && saveProps.length) {
config.save(saveProps);
} else {
config.save();
}
_this._beforeReqEvt = [];
_this._beforeResEvt = [];
_this._afterResEvt = [];
_this._pipeRequestEvt = [];
return _this;
}
_createClass(CatProxy, [{
key: 'init',
value: function init() {
var com = this;
// 别的进程发送的消息
process.on('message', function (message) {
_log2.default.debug('receive message');
if (message.type) {
switch (message.type) {
case "config":
config.set(message.result || {});
// 每次服务变动都重新设置下log
config.save();
com.setLogLevel();
break;
}
}
_log2.default.error('收到未知的消息', message);
});
this.setLogLevel();
// dangerous options
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// // 请求前
// this.beforeReq = beforeReq.bind(this);
// // 请求后
// this.afterRes = afterRes.bind(this);
// // 请求前
// this.beforeRes = beforeRes.bind(this);
return _promise2.default.resolve().then(this.createCache.bind(this)).then(this.checkParam.bind(this)).then(this.checkEnv.bind(this)).then(this.createServer.bind(this)).then(this.uiInit.bind(this)).then(null, this.errorHandle.bind(this));
}
// 创建缓存,创建请求保存
}, {
key: 'createCache',
value: function createCache() {}
}, {
key: 'checkParam',
value: function checkParam() {}
}, {
key: 'setLogLevel',
value: function setLogLevel(logLevel) {
_log2.default.transports.console.level = config.get('log');
}
// 环境检测
}, {
key: 'checkEnv',
value: function checkEnv() {}
}, {
key: 'uiInit',
value: function uiInit() {
var port = config.get('uiPort');
if (+port === 0) {
return;
}
(0, _app2.default)({
port: port,
hostname: _getLocalIps.localIps[0],
host: 'http://' + _getLocalIps.localIps[0] + ':' + port,
isAutoOpen: config.get('autoOpen')
});
}
// 出错处理
}, {
key: 'errorHandle',
value: function errorHandle(err) {
if (err) {
_log2.default.error(err);
}
return _promise2.default.reject(err);
}
// 根据配置创建服务器
}, {
key: 'createServer',
value: function createServer() {
var opt = config.get();
var servers = this.servers || [];
var com = this;
// 可以自定义server或者用系统内置的server
if (opt.type === 'http' && !servers[0]) {
servers[0] = _http2.default.createServer();
} else if (opt.type === 'https' && !servers[0]) {
// 找到证书,创建https的服务器
var _getCert = (0, _cert2.getCert)(opt.certHost);
var key = _getCert.privateKey;
var cert = _getCert.cert;
servers[0] = _https2.default.createServer({ key: key, cert: cert, rejectUnauthorized: false, SNICallback: _httpsProxySer.SNICallback });
} else if (opt.type === 'all' && !servers[0] && !servers[1]) {
servers[0] = _http2.default.createServer();
var _getCert2 = (0, _cert2.getCert)(opt.certHost);
var _key = _getCert2.privateKey;
var _cert = _getCert2.cert;
servers[1] = _https2.default.createServer({ key: _key, cert: _cert, rejectUnauthorized: false, SNICallback: _httpsProxySer.SNICallback });
}
var requestFun = requestMiddleware.middleWare(_requestSerives.requestHandler);
servers.forEach(function (server) {
server.catProxy = com;
// 如果在http下代理https,则需要过度下请求
if (server instanceof _http2.default.Server) {
server.on('connect', _requestSerives.requestConnectHandler);
}
server.on('upgrade', _requestSerives.requestUpgradeHandler);
server.on('request', function (req, res) {
if (req.headers.upgrade) {
return;
}
requestFun.call(this, req, res);
});
var serverType = server instanceof _http2.default.Server ? 'http' : 'https';
var port = serverType === 'http' ? opt.port : opt.httpsPort;
// 如果server没有被监听,则调用默认端口监听
if (!server.listening) {
// 根据server的类型调用不同的端口
server.listen(port, function () {
_log2.default.info('代理服务器启动于:' + (serverType + '://' + _getLocalIps.localIps[0] + ':' + port));
});
}
server.on('error', function (err) {
(0, _tools.error)(err);
process.exit(1);
});
});
this.servers = servers;
}
// 想服务器添加request事件
}, {
key: 'use',
value: function use(fun) {
requestMiddleware.use(fun);
return this;
}
// 在中转请求前,可以用于修改reqInfo
}, {
key: 'onBeforeReq',
value: function onBeforeReq() {
var _this2 = this;
for (var _len = arguments.length, fun = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
fun[_key2] = arguments[_key2];
}
fun.forEach(function (f) {
return _util2.default.isFunction(f) && _this2._beforeReqEvt.push(f);
});
}
// 请求结束,可以用于产看请求结果
}, {
key: 'onAfterRes',
value: function onAfterRes() {
var _this3 = this;
for (var _len2 = arguments.length, fun = Array(_len2), _key3 = 0; _key3 < _len2; _key3++) {
fun[_key3] = arguments[_key3];
}
fun.forEach(function (f) {
return _util2.default.isFunction(f) && _this3._afterResEvt.push(f);
});
}
// 获得中转请求前,可以用于修改resInfo
}, {
key: 'onBeforeRes',
value: function onBeforeRes() {
var _this4 = this;
for (var _len3 = arguments.length, fun = Array(_len3), _key4 = 0; _key4 < _len3; _key4++) {
fun[_key4] = arguments[_key4];
}
fun.forEach(function (f) {
return _util2.default.isFunction(f) && _this4._beforeResEvt.push(f);
});
}
}, {
key: 'onPipeRequest',
value: function onPipeRequest() {
var _this5 = this;
for (var _len4 = arguments.length, fun = Array(_len4), _key5 = 0; _key5 < _len4; _key5++) {
fun[_key5] = arguments[_key5];
}
fun.forEach(function (f) {
return _util2.default.isFunction(f) && _this5._pipeRequestEvt.push(f);
});
}
}]);
return CatProxy;
}(_events2.default);
process.on('uncaughtException', _tools.error);
process.on('exit', function () {
return _log2.default.info('服务器退出');
});
exports.default = CatProxy;
exports.CatProxy = CatProxy;