mm_os
Version:
MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。
227 lines (214 loc) • 5.2 kB
JavaScript
const Manager = require('mm_machine').Manager;
const Drive = require('./drive');
/**
* 静态文件管理类
* @augments {Manager}
* @class
*/
class Static extends Manager {
/**
* 配置参数
* @type {object}
*/
static config = {
/**
* 名称
* @type {string}
*/
name: '',
/**
* 标题
* @type {string}
*/
title: '静态文件管理',
/**
* 描述
* @type {string}
*/
description: '这是静态文件管理器',
/**
* 检索文件名
* @type {string}
*/
filename: 'static.json',
/**
* 模板目录
* @type {string}
*/
tpl_dir: __dirname,
/**
* 基础目录
* @type {string}
*/
base_dir: '../common/static'.fullname(__dirname),
/**
* 自定义目录,加载项目自定义资源
* @type {string}
*/
dir: './app'.fullname(),
/**
* 搜索模式 dir按目录搜索 | file按文件名搜索
* @type {string}
*/
search_way: 'file',
/**
* 是否懒加载
* @type {boolean}
*/
lazy_load: false,
/**
* 模式
* 1.生产模式,改变文件不会重新加载
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
* 3.热重载模式,改变配置文件都会加载配置和脚本
* 4.重载模式,执行完后重新加载脚本,避免变量污染
* 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
* @type {number}
*/
mode: 3
};
/**
* 构造函数
* @param {object} config 配置参数
* @param {object} parent 父级模块
*/
constructor(config, parent) {
super({ ...Static.config, ...config }, parent);
}
/**
* 处理请求
* @param {object} ctx Http请求上下文
* @param {object} next 跳过函数
*/
async _handleRequest(ctx, next) {
var md = ctx.method;
var path = ctx.path;
if (md === 'GET' || md === 'HEAD') {
await this._handleGetRequest(ctx, next, path);
} else {
await next();
}
}
/**
* 处理GET请求
* @param {object} ctx Http请求上下文
* @param {object} next 跳过函数
*/
async run(ctx, next) {
var done;
var infos = this.getInfos();
var len = infos.length;
let path = ctx.path;
if (path.indexOf('.') !== -1) {
done = await this._tryServeFile(ctx, infos, len, function () { });
if (!done) {
await next();
}
} else {
await next();
await this._handleDirReq(ctx, infos, len, path);
}
}
/**
* 尝试提供文件服务
* @param {object} ctx Http请求上下文
* @param {Array} list 驱动列表
* @param {number} len 列表长度
* @param {object} next 跳过函数
* @returns {boolean} 是否成功
*/
async _tryServeFile(ctx, infos, len, next) {
for (var i = 0; i < len; i++) {
var info = infos[i];
if (info.state === 1) {
let mod = this.getMod(info.name);
if (mod) {
var done = await mod.run(ctx, next);
if (done) {
return true;
}
}
}
}
return false;
}
/**
* 处理目录请求
* @param {object} ctx Http请求上下文
* @param {Array} infos 驱动信息列表
* @param {number} len 列表长度
* @param {string} path 请求路径
*/
async _handleDirReq(ctx, infos, len, path) {
var q = ctx.request.querystring;
for (var i = 0; i < len; i++) {
var info = infos[i];
if (info.state === 1) {
let mod = this.getMod(info.name);
if (mod) {
var p = mod.config.path;
if (path === p) {
this._handleExactMatch(ctx, q, p);
break;
} else {
var done = await mod.run(ctx, () => { });
if (done) {
break;
}
}
}
}
}
}
/**
* 处理精确匹配
* @param {object} ctx Http请求上下文
* @param {string} q 查询字符串
* @param {string} p 路径
*/
_handleExactMatch(ctx, q, p) {
if (ctx.status === 404) {
if (q) {
ctx.redirect(p + '/?' + q);
} else {
ctx.redirect(p + '/');
}
}
}
}
/**
* 静态文件驱动类
* @type {Drive}
*/
Static.prototype.Drive = Drive;
exports.Static = Static;
/**
* 创建全局管理器
*/
if (!$.pool.static) {
$.pool.static = {};
}
/**
* 静态文件管理器
* @param {string} scope 作用域
* @param {string} title 标题
* @returns {object} 返回一个缓存类
*/
function staticAdmin(scope, title) {
var sc = scope || $.val.scope + '';
var obj = $.pool.static[sc];
if (!obj) {
$.pool.static[sc] = new Static({
name: sc,
title: title
});
obj = $.pool.static[sc];
}
return obj;
}
/**
* @module 导出Static管理器
*/
if ($.admin) {
$.admin.static = staticAdmin;
}