订阅模式改为直链访问模式和静态文件共享根目录

This commit is contained in:
xx
2024-06-05 15:34:16 +08:00
parent 6169348dee
commit 247780a33d
18 changed files with 155 additions and 198 deletions

View File

@@ -163,9 +163,9 @@ if(MSVC)
endif() endif()
install(FILES config.ini DESTINATION bin/debug) install(FILES config.ini DESTINATION bin/debug)
install(FILES config.ini DESTINATION bin/release) install(FILES config.ini DESTINATION bin/release)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/scripts DESTINATION bin/debug) install(DIRECTORY ${PROJECT_SOURCE_DIR}/www DESTINATION bin/debug)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/config DESTINATION bin/debug) install(DIRECTORY ${PROJECT_SOURCE_DIR}/config DESTINATION bin/debug)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/scripts DESTINATION bin/release) install(DIRECTORY ${PROJECT_SOURCE_DIR}/www DESTINATION bin/release)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/config DESTINATION bin/release) install(DIRECTORY ${PROJECT_SOURCE_DIR}/config DESTINATION bin/release)
install(FILES ${PROJECT_SOURCE_DIR}/src/core/entry.h DESTINATION include) install(FILES ${PROJECT_SOURCE_DIR}/src/core/entry.h DESTINATION include)

View File

@@ -1,27 +1,20 @@
[variable] [variable]
;项目目录
base=${current_dir} base=${current_dir}
;网站程序目录
www=${current_dir}/www
[scripts] [scripts]
; 应用目录(可执行脚本)
; 考虑安全性,请勿放置于网站静态文件目录
app_dir=${base}/scripts/app
; LUA库目录 ; LUA库目录
lib_dir=["${base}/scripts/lib"] lib_dir=["${www}/api/lib"]
; 模块目录 ; 模块目录
module_dir=${base}/module module_dir=${base}/module
; LUA虚拟机缓存数量(并发越高越大)-建议10 ; LUA虚拟机缓存数量(并发越高越大)-建议10
lua_cache_size=3000 lua_cache_size=3000
; 脚本映射网站目录
; 例如 app_mapping_dir设置的是/apiapp_dir目录下有regist.lua则浏览器访问地址http://127.0.0.1/scripts/regist.lua
; 注意:必须/结尾
app_mapping_dir=/scripts/
; 自动检测文件修改时间(秒) ; 自动检测文件修改时间(秒)
auto_update_sec=3 auto_update_sec=3
[website] [website]
; 网站静态文件目录 ; 网站静态文件目录
static_dir=${base}/www dir=${www}
; 默认页面-404 ; 默认页面-404
default_404=page/404.html default_404=page/404.html
; 默认首页(["index.html","index.htm","index.lua"]) ; 默认首页(["index.html","index.htm","index.lua"])
@@ -31,9 +24,9 @@ session_dir=${base}/session
; SESSION默认过期时间 ; SESSION默认过期时间
session_timeout_sec=86400 session_timeout_sec=86400
; 初始化加载脚本(网站程序启动) ; 初始化加载脚本(网站程序启动)
Initialization_script=${base}/scripts/init.lua Initialization_script=${www}/api/lib/init.lua
; 拦截器 ; 拦截器
interceptor_scripts= [["${base}/scripts/interceptor.lua","/scripts/*.*"]] interceptor_scripts= [["${www}/api/lib/interceptor.lua","/api/*.*"]]
; 调试模式,开启后控制台输出异常错误信息 (0=关闭 1=开启) ; 调试模式,开启后控制台输出异常错误信息 (0=关闭 1=开启)
debug=1 debug=1
; 绑定域名 ; 绑定域名

View File

@@ -1,10 +0,0 @@
require "website"
-- 通用入口函数
route = {"/",GET}
function access()
local data = {
name = "Fast Web 快速网站开发框架"
}
-- 返回JSON数据
reply(200,"OK",data)
end

View File

@@ -1,7 +0,0 @@
require "website"
function access()
if param("key") == nil or param("key") ~= "123465" then
print("is not found key")
end
return true
end

View File

@@ -47,20 +47,6 @@ bool config::open(const std::string& ini_filepath)
cache(); cache();
return true; return true;
} }
std::vector<std::string> config::lua_app_files()
{
std::vector<std::string> results;
auto luas = ylib::file::traverse(sConfig->scripts.app_dir, "(.*\\.lua)");
for_iter(iter, luas)
{
if (iter->second == IS_DIRECTORY)
continue;
std::string path = strutils::replace(iter->first, '\\', '/');
results.push_back(path);
}
return results;
}
std::vector<std::string> config::lua_lib_files() std::vector<std::string> config::lua_lib_files()
{ {
std::vector<std::string> results; std::vector<std::string> results;
@@ -100,14 +86,12 @@ std::vector<std::string> config::extractVariableNames(const std::string& text)
void config::cache() void config::cache()
{ {
scripts.app_dir = m_ini.read("scripts","app_dir");
scripts.lib_dir = ylib::json::from(m_ini.read("scripts", "lib_dir")).to<std::vector<std::string>>(); scripts.lib_dir = ylib::json::from(m_ini.read("scripts", "lib_dir")).to<std::vector<std::string>>();
scripts.module_dir = m_ini.read("scripts", "module_dir"); scripts.module_dir = m_ini.read("scripts", "module_dir");
scripts.lua_cache_size = ylib::stoi(m_ini.read("scripts", "lua_cache_size")); scripts.lua_cache_size = ylib::stoi(m_ini.read("scripts", "lua_cache_size"));
scripts.app_mapping_dir = m_ini.read("scripts", "app_mapping_dir");
scripts.auto_update_sec = ylib::stoi(m_ini.read("scripts", "auto_update_sec")); scripts.auto_update_sec = ylib::stoi(m_ini.read("scripts", "auto_update_sec"));
website.static_dir = m_ini.read("website","static_dir"); website.dir = m_ini.read("website","dir");
website.default_404 = m_ini.read("website", "default_404"); website.default_404 = m_ini.read("website", "default_404");
website.default_index = ylib::json::from(m_ini.read("website", "default_index")).to<std::vector<std::string>>(); website.default_index = ylib::json::from(m_ini.read("website", "default_index")).to<std::vector<std::string>>();
website.session_dir = m_ini.read("website", "session_dir"); website.session_dir = m_ini.read("website", "session_dir");

View File

@@ -12,11 +12,9 @@ public:
network::http::ssl_config ssl; network::http::ssl_config ssl;
}; };
struct scripts { struct scripts {
std::string app_dir;
std::vector<std::string> lib_dir; std::vector<std::string> lib_dir;
std::string module_dir; std::string module_dir;
uint32 lua_cache_size = 0; uint32 lua_cache_size = 0;
std::string app_mapping_dir;
uint32 auto_update_sec = 0; uint32 auto_update_sec = 0;
}; };
struct website { struct website {
@@ -24,7 +22,7 @@ public:
std::string filepath; std::string filepath;
std::string regex_express; std::string regex_express;
}; };
std::string static_dir; std::string dir;
std::string default_404; std::string default_404;
std::vector<std::string> default_index; std::vector<std::string> default_index;
std::string session_dir; std::string session_dir;
@@ -38,7 +36,6 @@ public:
config(); config();
bool open(const std::string& ini_filepath); bool open(const std::string& ini_filepath);
std::vector<std::string> lua_app_files();
std::vector<std::string> lua_lib_files(); std::vector<std::string> lua_lib_files();
private: private:
// INI配置文件 // INI配置文件

View File

@@ -155,6 +155,7 @@ void module_manager::load_lualib(sol::state* lua)
std::string current_path = (*lua)["package"]["path"]; // 获取当前的路径 std::string current_path = (*lua)["package"]["path"]; // 获取当前的路径
for (size_t i = 0; i < sConfig->scripts.lib_dir.size(); i++) for (size_t i = 0; i < sConfig->scripts.lib_dir.size(); i++)
current_path += ";" + sConfig->scripts.lib_dir[i] + "/?.lua"; // 添加新的路径 current_path += ";" + sConfig->scripts.lib_dir[i] + "/?.lua"; // 添加新的路径
current_path += ";" + sConfig->website.dir + "/?.lua"; // 添加新的路径
(*lua)["package"]["path"] = current_path; // 设置修改后的路径 (*lua)["package"]["path"] = current_path; // 设置修改后的路径
} }

View File

@@ -14,13 +14,6 @@ void subscribe_manager::load(network::http::router* router)
{ {
clear(); clear();
m_router = router; m_router = router;
// 初始化全部订阅
auto files = sConfig->lua_app_files();
for (size_t i = 0; i < files.size(); i++)
{
init_subscribe(files[i]);
}
// 其它绑定
router->other(&subscribe_manager::other); router->other(&subscribe_manager::other);
} }
@@ -35,83 +28,59 @@ void subscribe_manager::clear()
m_subextra.clear(); m_subextra.clear();
m_router = nullptr; m_router = nullptr;
} }
void subscribe_manager::other(network::http::request* request, network::http::response* response)
void subscribe_manager::init_subscribe(const std::string& filepath)
{ {
auto state = sStateMgr->get(); auto send_404 = [](network::http::response* response) {
std::string route_pattern; std::string default_404 = sConfig->website.dir + "\\" + sConfig->website.default_404;
network::http::method method = network::http::ALL; if (sConfig->website.default_404 == "" || ylib::file::exist(default_404) == false)
try
{
auto result = state->state->script_file(sConfig->scripts.app_dir + "/" + filepath);
if (result.valid()) {
auto router = (*state->state)["route"];
auto type = router.get_type();
if (router.is<sol::table>())
{
sol::optional<std::string> route_pattern_param = router[1];
sol::optional<int> method_param = router[2];
if (route_pattern_param && route_pattern_param->empty() == false)
route_pattern = *route_pattern_param;
if (method_param)
method = (network::http::method)*method_param;
}
}
}
catch (const std::exception& e)
{
LOG_ERROR(e.what());
}
sStateMgr->push(state);
if (route_pattern.empty())
route_pattern = sConfig->scripts.app_mapping_dir + filepath;
// OutPutLog
{
std::string log;
log = "[subscribe] lua: " + filepath + "\t pattern: " + route_pattern + "\t method: ";
switch (method)
{ {
case ylib::network::http::GET: response->send((std::string)"404 Not Found", 404, "Not Found");
log.append("GET"); }
break; else
case ylib::network::http::POST: {
log.append("POST"); response->send_file(default_404, -1, 404, "Not Found");
break; }
case ylib::network::http::PUT: };
log.append("PUT"); auto send_file = [&](network::http::response* response, std::string filepath)
break; {
case ylib::network::http::DEL: if (ylib::file::exist(filepath))
log.append("DEL"); {
break; if (ylib::file::ext(filepath) == "lua")
case ylib::network::http::HEAD: {
log.append("HEAD"); exec(filepath,request,response);
break; return;
case ylib::network::http::ALL: }
log.append("ALL"); response->send_file(filepath);
break; }
default: else
break; {
send_404(response);
}
};
std::string filepath;
if (request->filepath() == "/")
{
for (size_t i = 0; i < sConfig->website.default_index.size(); i++)
{
filepath = sConfig->website.dir + request->filepath() + sConfig->website.default_index[i];
if (ylib::file::exist(filepath))
break;
} }
LOG_INFO(log);
} }
else
filepath = sConfig->website.dir + request->filepath();
std::string* extra = new std::string(sConfig->scripts.app_dir + "/" + filepath); send_file(response, filepath);
m_subextra.push_back(extra);
m_router->subscribe(route_pattern, method, &subscribe_manager::callback, extra);
} }
void subscribe_manager::callback(network::http::request* request, network::http::response* response, void* extra) void subscribe_manager::exec(const std::string& filepath, network::http::request* request, network::http::response* response)
{ {
std::string lua_filepath = *(std::string*)extra;
auto lua = sStateMgr->get(); auto lua = sStateMgr->get();
std::string exception_string; std::string exception_string;
try try
{ {
auto lbResult = lua->state->load_file(lua_filepath); auto lbResult = lua->state->load_file(filepath);
if (lbResult.valid() == false) if (lbResult.valid() == false)
{ {
sol::error err = lbResult; sol::error err = lbResult;
@@ -120,16 +89,9 @@ void subscribe_manager::callback(network::http::request* request, network::http:
module::request m_request(request); module::request m_request(request);
module::response m_response(response); module::response m_response(response);
lbResult();
(*lua->state)["response"] = &m_response; (*lua->state)["response"] = &m_response;
(*lua->state)["request"] = &m_request; (*lua->state)["request"] = &m_request;
lbResult();
auto result = (*lua->state)["access"]();
if (!result.valid()) {
sol::error err = result;
throw ylib::exception(err.what());
}
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
@@ -144,51 +106,3 @@ void subscribe_manager::callback(network::http::request* request, network::http:
if (exception_string.empty() == false) if (exception_string.empty() == false)
throw ylib::exception(exception_string); throw ylib::exception(exception_string);
} }
void subscribe_manager::other(network::http::request* request, network::http::response* response)
{
auto send_404 = [](network::http::response* response) {
std::string default_404 = sConfig->website.static_dir + "\\" + sConfig->website.default_404;
if (sConfig->website.default_404 == "" || ylib::file::exist(default_404) == false)
{
response->send((std::string)"404 Not Found", 404, "Not Found");
}
else
{
response->send_file(default_404, -1, 404, "Not Found");
}
};
auto send_file = [&](network::http::response* response, std::string filepath)
{
filepath = sConfig->website.static_dir + filepath;
if (ylib::file::exist(filepath))
{
response->send_file(filepath);
}
else
{
send_404(response);
}
};
if (request->filepath() == "/")
{
bool find = false;
for (size_t i = 0; i < sConfig->website.default_index.size(); i++)
{
std::string filepath = sConfig->website.static_dir + request->filepath() + sConfig->website.default_index[i];
if (ylib::file::exist(filepath))
{
find = true;
response->send_file(filepath);
break;
}
}
if (find == false)
{
send_404(response);
}
return;
}
send_file(response, request->filepath());
}

View File

@@ -18,19 +18,6 @@ public:
void load(network::http::router* router); void load(network::http::router* router);
void clear(); void clear();
private: private:
/// <summary>
/// 初始化订阅
/// </summary>
/// <param name="filepath"></param>
/// <returns></returns>
void init_subscribe(const std::string& filepath);
private:
/// <summary>
/// 服务回调
/// </summary>
/// <param name="request"></param>
/// <param name="response"></param>
static void callback(network::http::request* request, network::http::response* response, void* extra);
/// <summary> /// <summary>
/// 其它 /// 其它
/// </summary> /// </summary>
@@ -38,6 +25,13 @@ private:
/// <param name="response"></param> /// <param name="response"></param>
/// <param name="extra"></param> /// <param name="extra"></param>
static void other(network::http::request* request, network::http::response* response); static void other(network::http::request* request, network::http::response* response);
/// <summary>
/// 执行lua
/// </summary>
/// <param name="filepath"></param>
/// <param name="request"></param>
/// <param name="response"></param>
static void exec(const std::string& filepath,network::http::request* request, network::http::response* response);
private: private:
network::http::router* m_router = nullptr; network::http::router* m_router = nullptr;
std::vector<std::string*> m_subextra; std::vector<std::string*> m_subextra;

View File

@@ -12,15 +12,15 @@ module::timer::~timer()
std::string module::timer::add(const std::string& name, const std::string& filepath, const std::string& funname, int msec, bool loop) std::string module::timer::add(const std::string& name, const std::string& filepath, const std::string& funname, int msec, bool loop)
{ {
std::string filepath2; std::string filepath2;
if (ylib::file::exist(sConfig->scripts.app_dir + "/" + filepath)) if (ylib::file::exist(sConfig->website.dir + "/" + filepath))
filepath2 = sConfig->scripts.app_dir + "/" + filepath; filepath2 = sConfig->website.dir + "/" + filepath;
else else
{ {
filepath2 = module_manager::getInstance()->search(filepath); filepath2 = module_manager::getInstance()->search(filepath);
if (filepath2.empty()) if (filepath2.empty())
{ {
std::string result; std::string result;
result = "not found script lua, App: " + std::string(sConfig->scripts.app_dir + "/" + filepath) + "\r\n Lib: "; result = "not found script lua, Root: " + std::string(sConfig->website.dir + "/" + filepath) + "\r\n Lib: ";
for (size_t i = 0; i < sConfig->scripts.lib_dir.size(); i++) for (size_t i = 0; i < sConfig->scripts.lib_dir.size(); i++)
result.append(std::string(sConfig->scripts.lib_dir[i] + "/" + filepath)+"\r\n"); result.append(std::string(sConfig->scripts.lib_dir[i] + "/" + filepath)+"\r\n");
return result; return result;

4
www/api/admin/admin.lua Normal file
View File

@@ -0,0 +1,4 @@
local dkjson = require("dkjson")
response:send("这是需要权限的接口!可以看到这条消息说明你拥有权限。")

View File

@@ -0,0 +1,18 @@
require "website"
function access()
if string.sub(request:filepath(),1,12) == "/api/public/" then
--公共开放接口
return true
elseif string.sub(request:filepath(),1,11) == "/api/admin/" then
--管理员目录,需要验证权限
print(param("key"),"\t")
if param("key") == nil or param("key") ~= "123456" then
response:send("key不正确")
return false
end
return true
else
response:send("仅允许访问 /api/public 和 /api/admin 目录")
return false
end
end

2
www/api/public/info.lua Normal file
View File

@@ -0,0 +1,2 @@
response:send("这是一个公共public接口可以随意访问")

65
www/index.html Normal file
View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fast Web</title>
<script src="js/jquery-3.4.1.min.js"></script>
<style>
.button-container {
margin-bottom: 10px;
}
.button-container button {
margin-right: 10px;
}
</style>
</head>
<body>
<h1>Fast Web</h1>
<div class="button-container">
<button id="admin-btn">需要权限地址</button>
<button id="public-btn">公共接口</button>
</div>
<form id="interceptor-form">
<label for="path">访问路径:</label>
<input type="text" id="path" name="path" required>
<br><br>
<label for="key">Key:</label>
<input type="text" id="key" name="key" required>
<br><br>
<button type="submit">提交</button>
</form>
<script>
$(document).ready(function(){
$('#admin-btn').click(function(){
$('#path').val('/api/admin/admin.lua');
});
$('#public-btn').click(function(){
$('#path').val('/api/public/info.lua');
});
$('#interceptor-form').on('submit', function(event){
event.preventDefault();
var path = $('#path').val();
var key = $('#key').val();
var data = JSON.stringify({ key: key });
$.ajax({
url: path,
method: 'POST',
contentType: 'application/json',
data: data,
success: function(response) {
alert('请求成功: ' + response);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('请求失败: ' + textStatus + ' - ' + errorThrown);
}
});
});
});
</script>
</body>
</html>

2
www/js/jquery-3.4.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long