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

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()
install(FILES config.ini DESTINATION bin/debug)
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}/scripts DESTINATION bin/release)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/www DESTINATION bin/release)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/config DESTINATION bin/release)
install(FILES ${PROJECT_SOURCE_DIR}/src/core/entry.h DESTINATION include)

View File

@@ -1,27 +1,20 @@
[variable]
;项目目录
base=${current_dir}
;网站程序目录
www=${current_dir}/www
[scripts]
; 应用目录(可执行脚本)
; 考虑安全性,请勿放置于网站静态文件目录
app_dir=${base}/scripts/app
; LUA库目录
lib_dir=["${base}/scripts/lib"]
lib_dir=["${www}/api/lib"]
; 模块目录
module_dir=${base}/module
; LUA虚拟机缓存数量(并发越高越大)-建议10
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
[website]
; 网站静态文件目录
static_dir=${base}/www
dir=${www}
; 默认页面-404
default_404=page/404.html
; 默认首页(["index.html","index.htm","index.lua"])
@@ -31,9 +24,9 @@ session_dir=${base}/session
; SESSION默认过期时间
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=开启)
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();
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> results;
@@ -100,14 +86,12 @@ std::vector<std::string> config::extractVariableNames(const std::string& text)
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.module_dir = m_ini.read("scripts", "module_dir");
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"));
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_index = ylib::json::from(m_ini.read("website", "default_index")).to<std::vector<std::string>>();
website.session_dir = m_ini.read("website", "session_dir");

View File

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

View File

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

View File

@@ -14,13 +14,6 @@ void subscribe_manager::load(network::http::router* router)
{
clear();
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);
}
@@ -35,83 +28,59 @@ void subscribe_manager::clear()
m_subextra.clear();
m_router = nullptr;
}
void subscribe_manager::init_subscribe(const std::string& filepath)
void subscribe_manager::other(network::http::request* request, network::http::response* response)
{
auto state = sStateMgr->get();
std::string route_pattern;
network::http::method method = network::http::ALL;
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)
auto send_404 = [](network::http::response* response) {
std::string default_404 = sConfig->website.dir + "\\" + sConfig->website.default_404;
if (sConfig->website.default_404 == "" || ylib::file::exist(default_404) == false)
{
case ylib::network::http::GET:
log.append("GET");
break;
case ylib::network::http::POST:
log.append("POST");
break;
case ylib::network::http::PUT:
log.append("PUT");
break;
case ylib::network::http::DEL:
log.append("DEL");
break;
case ylib::network::http::HEAD:
log.append("HEAD");
break;
case ylib::network::http::ALL:
log.append("ALL");
break;
default:
break;
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)
{
if (ylib::file::exist(filepath))
{
if (ylib::file::ext(filepath) == "lua")
{
exec(filepath,request,response);
return;
}
response->send_file(filepath);
}
else
{
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);
}
std::string* extra = new std::string(sConfig->scripts.app_dir + "/" + filepath);
m_subextra.push_back(extra);
m_router->subscribe(route_pattern, method, &subscribe_manager::callback, extra);
else
filepath = sConfig->website.dir + request->filepath();
send_file(response, filepath);
}
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();
std::string exception_string;
try
{
auto lbResult = lua->state->load_file(lua_filepath);
auto lbResult = lua->state->load_file(filepath);
if (lbResult.valid() == false)
{
sol::error err = lbResult;
@@ -120,16 +89,9 @@ void subscribe_manager::callback(network::http::request* request, network::http:
module::request m_request(request);
module::response m_response(response);
lbResult();
(*lua->state)["response"] = &m_response;
(*lua->state)["request"] = &m_request;
auto result = (*lua->state)["access"]();
if (!result.valid()) {
sol::error err = result;
throw ylib::exception(err.what());
}
lbResult();
}
catch (const std::exception& e)
{
@@ -144,51 +106,3 @@ void subscribe_manager::callback(network::http::request* request, network::http:
if (exception_string.empty() == false)
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 clear();
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>
@@ -38,6 +25,13 @@ private:
/// <param name="response"></param>
/// <param name="extra"></param>
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:
network::http::router* m_router = nullptr;
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 filepath2;
if (ylib::file::exist(sConfig->scripts.app_dir + "/" + filepath))
filepath2 = sConfig->scripts.app_dir + "/" + filepath;
if (ylib::file::exist(sConfig->website.dir + "/" + filepath))
filepath2 = sConfig->website.dir + "/" + filepath;
else
{
filepath2 = module_manager::getInstance()->search(filepath);
if (filepath2.empty())
{
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++)
result.append(std::string(sConfig->scripts.lib_dir[i] + "/" + filepath)+"\r\n");
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