订阅模式改为直链访问模式和静态文件共享根目录
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
21
config.ini
21
config.ini
@@ -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设置的是/api,app_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
|
||||
; 绑定域名
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
require "website"
|
||||
-- 通用入口函数
|
||||
route = {"/",GET}
|
||||
function access()
|
||||
local data = {
|
||||
name = "Fast Web 快速网站开发框架"
|
||||
}
|
||||
-- 返回JSON数据
|
||||
reply(200,"OK",data)
|
||||
end
|
||||
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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配置文件
|
||||
|
||||
@@ -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; // 设置修改后的路径
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
4
www/api/admin/admin.lua
Normal file
@@ -0,0 +1,4 @@
|
||||
local dkjson = require("dkjson")
|
||||
|
||||
|
||||
response:send("这是需要权限的接口!可以看到这条消息说明你拥有权限。")
|
||||
18
www/api/lib/interceptor.lua
Normal file
18
www/api/lib/interceptor.lua
Normal 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
2
www/api/public/info.lua
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
response:send("这是一个公共public接口,可以随意访问")
|
||||
65
www/index.html
Normal file
65
www/index.html
Normal 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
2
www/js/jquery-3.4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user