UNPKG

xweb

Version:
228 lines (196 loc) 5.04 kB
'use strict'; const fs = require("fs"); const Koa = require("koa"); const KoaWeb = require("koa-web"); const KoaSession = require("koa-session"); const crypto = require('crypto'); const app = new Koa(); module.exports = class Xweb { static __config; /** * 配置设置 * @param {*} config * @returns */ config (config) { if (config === undefined || config.constructor.name !== 'Object') { return; } this.__config = config; } /** * 创建文件夹 * @param {*} path * @returns */ mkdir (path = '') { path = path.replace(/[\\]/g, "/"); let pos = path.lastIndexOf("/"); if (pos >= 0) { path = path.substring(0, pos); } let pathTmp = ""; let pathList = path.split("/"); try { for (const i in pathList) { pathTmp += "/" + pathList[i]; if (fs.existsSync(pathTmp)) { if (fs.statSync(pathTmp).isFile()) { return false; } } else { fs.mkdirSync(pathTmp); } } } catch (e) { return false; } return true; } /** * 读取文件 * @param {*} jsonFile * @param {*} maxAge * @returns */ read (jsonFile = '', maxAge = 0) { if (!fs.existsSync(jsonFile) || !fs.statSync(jsonFile).isFile()) { return {}; } const statSync = fs.statSync(jsonFile); const age = (new Date()).getTime() - parseInt(statSync.mtimeMs); try { if (age > maxAge) { fs.unlinkSync(jsonFile); return {}; } return JSON.parse(fs.readFileSync(jsonFile).toString()); } catch (e) { console.error(e); return {}; } } /** * 获取键值 * @param {*} sessionId * @returns */ getKey(sessionId) { const md5 = crypto.createHash('md5').update(sessionId).digest("hex"); return md5.substring(0, 2) + "/" + md5.substring(2, 16) + ".json"; } /** * 清理文件夹过期的cookie文件 * @param {*} path * @param {*} maxAge */ clearKeys(path = '', maxAge = 0) { fs.readdir(path, function (err, files) { if (err) { return '目录不存在'; } for (const i in files) { let tPath = path + "/" + files[i]; if (!fs.statSync(tPath).isDirectory()) { continue; } fs.readdir(tPath, function (e, _fs) { if (e) { return '目录不存在'; } let delCot = 0; let fCounts = _fs.length; for (const j in _fs) { let jvPath = tPath + "/" + _fs[j]; const statSync = fs.statSync(jvPath); const age = (new Date()).getTime() - parseInt(statSync.mtimeMs); if (age > maxAge) { delCot ++; fs.unlinkSync(jvPath); } } if (delCot >= fCounts) { fs.rmdirSync(tPath); } }); } }) } /** * Koa应用 * @param {*} func */ use (func) { app.use(func); } /** * 初始化 */ init () { app.keys = ['xweb']; let sKey = this.__config.sessionKey; let sMaxAge = this.__config.sessionMaxAge; let config = { key: 'xweb', renew: true, }; if (sKey !== undefined && typeof sKey === 'string') { config['key'] = sKey; } if (sMaxAge !== undefined && typeof sMaxAge === 'number') { config['maxAge'] = parseInt(sMaxAge); } else { sMaxAge = 86400000; config['maxAge'] = sMaxAge; } if (this.__config !== undefined) { let path = this.__config.path; if (typeof path === 'string') { path = path.trim(); let pathLast = path[path.length - 1]; if (pathLast !== '\\' && pathLast !== '/') { path += "/"; } let cachePath = this.__config.sessionPath; if (cachePath === undefined || typeof cachePath !== 'string') { cachePath = path + ".cache/session/"; } else { cachePath = cachePath.trim(); if (!["/", "\\"].includes(cachePath[cachePath.length - 1])) { cachePath += "/"; } cachePath += ".cache/session/"; } this.clearKeys(cachePath, sMaxAge); config['store'] = { // 获取 session 数据 get: (key, maxAge) => { return this.read(cachePath + this.getKey(key), maxAge); }, // 设置 session 数据 set: (key, sess) => { const jsonFile = cachePath + this.getKey(key); if (this.mkdir(jsonFile)) { fs.writeFileSync(jsonFile, JSON.stringify(sess)); } }, // 销毁 session 数据 destroy: (key) => {} }; } } app.use(KoaSession(config, app)); } /** * 页面监听 * @param {*} port * @param {*} func */ listen (port, func) { this.init(); if (this.__config !== undefined) { app.use(KoaWeb(this.__config)); } app.listen(port, func); } };