UNPKG

imsdk-server-core

Version:

轻量级Web服务器框架、WebSocket服务器框架。采用Typescript编写,简单易用。

221 lines (220 loc) 9.97 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebServer = void 0; /** * 对express及其常用插件封装的类 * express相关信息:https://github.com/expressjs/express * helmet相关信息:https://github.com/helmetjs/helmet * compression相关信息:https://github.com/expressjs/compression * cookie-parser相关信息:https://github.com/expressjs/cookie-parser * body-parser相关信息:https://github.com/expressjs/body-parser * multer相关信息:https://github.com/expressjs/multer */ const express_1 = __importDefault(require("express")); const helmet_1 = __importDefault(require("helmet")); const compression_1 = __importDefault(require("compression")); const cookie_parser_1 = __importDefault(require("cookie-parser")); const body_parser_1 = __importDefault(require("body-parser")); const multer_1 = __importDefault(require("multer")); const uuid_1 = require("uuid"); const https_1 = __importDefault(require("https")); const http_1 = __importDefault(require("http")); class WebServer { /** * @param context 上下文包装类实例 * @param category 日志分类 * @param config 配置信息 */ constructor(context, category, config = {}) { this._context = context; this._config = { helmet: {}, compress: {}, cookieSecret: uuid_1.v1(), cookieOptions: {}, bodyParserJson: {}, bodyParserForm: { extended: true }, uploadKey: null, uploadDir: null, uploadMimeTypes: { 'image/jpg': 'jpg', 'image/png': 'png', 'image/gif': 'gif', 'image/bmp': 'bmp' }, webRootUrl: '', webSignPwd: null }; Object.assign(this._config, config); //拷贝配置信息 //绑定log4js实例 this._logger = context.getLogger(category); //绑定app和server this._webapp = express_1.default(); //创建express应用实例 this._server = context.ssls ? https_1.default.createServer(context.readSSLKerCert(), this._webapp) : http_1.default.createServer(this._webapp); //创建HTTP/S服务器实例 //其它属性 this._upload = null; //文件上传处理实例 } /** * 加载比较常用的几个第三方模块 */ loadBaseModules() { //启用helmet插件 if (this._config.helmet) { this._webapp.use(helmet_1.default(this.ensureObject(this._config.helmet))); this._logger.info('helmet module was loaded'); } //启用compress插件(放在最前面可以保证后面的所有内容都经过压缩) if (this._config.compress) { this._webapp.use(compression_1.default(this.ensureObject(this._config.compress))); this._logger.info('compression module was loaded'); } //启用cookie-parser插件 if (this._config.cookieSecret) { this._webapp.use(cookie_parser_1.default(this._config.cookieSecret, this.ensureObject(this._config.cookieOptions))); this._logger.info('cookie-parser module was loaded'); } //启用cookie-parser插件,解析application/json if (this._config.bodyParserJson) { this._webapp.use(body_parser_1.default.json(this.ensureObject(this._config.bodyParserJson))); this._logger.info('body-parser.json module was loaded'); } //启用cookie-parser插件,解析application/x-www-form-urlencoded if (this._config.bodyParserForm) { this._webapp.use(body_parser_1.default.urlencoded(this.ensureObject(this._config.bodyParserForm))); this._logger.info('body-parser.urlencoded module was loaded'); } } /** * 加载打印全部请求信息的模块 * @param logHeaders 是否打印请求头信息 * @param logArgs 是否打印参数信息 */ loadPrintModule(logHeaders = false, logArgs = false) { this._webapp.all('*', (req, resp, next) => { this._logger.info(this._context.getIPV4(req), req.originalUrl); //打印出所有请求路径 if (logHeaders) this._logger.debug('req.headers ->', req.headers); if (logArgs) { if (!this._context.isEmptyObject(req.params)) this._logger.debug('req.params ->', req.params); if (!this._context.isEmptyObject(req.body)) this._logger.debug('req.body ->', req.body); if (!this._context.isEmptyObject(req.query)) this._logger.debug('req.query ->', req.query); if (!this._context.isEmptyObject(req.cookies)) this._logger.debug('req.cookies ->', req.cookies); if (!this._context.isEmptyObject(req.signedCookies)) this._logger.debug('req.signedCookies ->', req.signedCookies); } next(); }); this._logger.info('inner-print module was loaded'); } /** * 加载文件上传模块,具体属性参考依赖库 https://github.com/expressjs/multer * @param url 上传请求的url * @param cb 上传成功或失败的回调,第一个回调参数code=200为成功,其它为失败 * @param options 加载文件上传模块,具体属性参考依赖库 https://github.com/expressjs/multer */ loadUploadModule(url, cb, options = {}) { if (!this._config.uploadKey || !this._config.uploadDir) { throw Error('upload configuration not specified'); } this._upload = multer_1.default({ storage: options.storage || multer_1.default.diskStorage({ destination: (req, file, callback) => { const date = new Date(); const folder = this._config.uploadDir + '/' + date.getFullYear() + '_' + (date.getMonth() + 1) + '_' + date.getDate() + '/'; if (this._context.mkdirsSync(folder)) { callback(null, folder); } else { callback(new Error('创建文件夹出错'), undefined); } }, filename: (req, file, callback) => { const suffix = this._config.uploadMimeTypes[file.mimetype.toLowerCase()]; if (suffix) { callback(null, uuid_1.v1() + '.' + suffix); } else { callback(new Error('不支持的文件格式'), undefined); } } }), dest: options.dest, limits: options.limits || { fileSize: 1024 * 1024 * 10 }, preservePath: options.preservePath, fileFilter: options.fileFilter, }); //实际使用时,必须为POST请求才能收到文件 this._webapp.all(url, (req, resp) => { this._upload.single(this._config.uploadKey)(req, resp, (error) => { if (req.file) { this._logger.debug('req.file ->', req.file); if (error) { cb(500, 'Internal Server Error, ' + error.toString(), req, resp); } else { const data = {}; Object.assign(data, req.body); data._path = req.file.path.replace(new RegExp('\\\\', 'gm'), '/').replace(this._config.uploadDir, ''); //windows系统下分隔符为'\' data._size = req.file.size; data._mimetype = req.file.mimetype; data._orgname = req.file.originalname; this._logger.debug('success data ->', data); cb(200, data, req, resp); } } else { cb(400, 'Bad Request, ' + (error ? error.toString() : new Error('没有收到文件').toString()), req, resp); } }); }); this._logger.info('inner-upload module was loaded'); } /** * 加载静态资源到express容器,具体属性参考依赖库 https://github.com/expressjs/express * @param url http(s)访问请求路径 * @param path 文件或文件夹的路径 * @param options 配置信息,具体属性参考依赖库 https://github.com/expressjs/express */ loadStaticModule(url, path, options) { this._webapp.use(url, express_1.default.static(path, options)); } /** * 开启服务器 * @param callback 服务器启动后的回调函数 */ start(callback) { this._server.listen(this._context.port, () => { this._logger.info('ssls', this._context.ssls, this._context.host, this._context.port, 'is listening...'); if (callback) callback(); }); } /** * 关闭服务器 * @param callback 服务器关闭后的回调函数 */ close(callback) { this._server.close((error) => { this._logger.info('ssls', this._context.ssls, this._context.host, this._context.port, 'was closed.'); if (callback) callback(error); }); } get logger() { return this._logger; } get webapp() { return this._webapp; } get server() { return this._server; } get webRootUrl() { return this._config.webRootUrl; } get webSignPwd() { return this._config.webSignPwd; } /** * 确保返回一个object类型 * @param config */ ensureObject(config) { return config && typeof config === 'object' ? config : {}; } } exports.WebServer = WebServer;