UNPKG

catproxy

Version:

a node proxy or host change tools

356 lines (291 loc) 11.4 kB
'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;