Procházet zdrojové kódy

优化,增加动态订阅

xx před 2 roky
rodič
revize
19d9d6766b

+ 2 - 1
config.ini

@@ -31,7 +31,8 @@ Initialization_script=${www}/api/lib/init.lua
 debug=1
 ; 绑定域名
 domain=["local.newobj.org","127.0.0.1"]
-
+; 允许请求URL的路径直接映射到网站路径中的lua。如你的站点只允许订阅绑定模式,则设置为0关闭此功能以提高安全性。
+direct_url_mapping=1
 [log]
 ; 开启或关闭
 enable=1

+ 1 - 4
src/core/app.cpp

@@ -87,10 +87,7 @@ bool fastweb::app::start(const std::string& config_filepath)
 	if (initialization_script() == false)
 		return false;
 		
-
-
-	// 加载订阅
-	subscribe->load(router);
+	this->subscribe->start();
 
 	return m_center->start();
 }

+ 1 - 0
src/core/config.cpp

@@ -100,6 +100,7 @@ void fastweb::config::cache()
 	website.Initialization_script = m_ini.read("website", "Initialization_script");
 	website.debug = m_ini.read("website", "debug") == "1";
 	website.domain = ylib::json::from(m_ini.read("website", "domain")).to<std::vector<std::string>>();
+	website.direct_url_mapping = m_ini.read("website", "direct_url_mapping") == "1";
 
 	log.enable = m_ini.read("log", "enable") == "1";
 	log.dir = m_ini.read("log", "dir");

+ 1 - 0
src/core/config.h

@@ -31,6 +31,7 @@ namespace fastweb
 			std::string Initialization_script;
 			bool debug = false;
 			std::vector<std::string> domain;
+			bool direct_url_mapping = false;
 		};
 
 		struct log {

+ 14 - 17
src/core/interceptormanager.cpp

@@ -12,43 +12,40 @@ fastweb::interceptor_manager::~interceptor_manager()
 {
 	clear();
 }
-bool fastweb::interceptor_manager::add(const std::string& regex_express, const std::string& filepath)
+bool fastweb::interceptor_manager::add(const std::string& pattern, const std::string& filepath)
 {
-	if (interceptor_manager::interceptor.exist(regex_express))
-	{
-		LOG_WARN("`" + regex_express + "` interceptor is invalid, duplicate rule, filepath: " + filepath);
-		return false;
-	}
-	interceptor_manager::interceptor.add(regex_express, filepath);
-	app()->router->interceptor()->add(regex_express, [this](network::http::reqpack* reqpack, const std::string& express_string)->bool {
-		return this->callback(reqpack, express_string);
+	app()->router->interceptor()->add(pattern,filepath, [&](network::http::reqpack* reqpack, const std::string& pattern,const std::string& filepath)->bool {
+		return this->callback(reqpack, pattern, filepath);
 	});
 	return true;
 }
-bool fastweb::interceptor_manager::remove(const std::string& regex_express)
+bool fastweb::interceptor_manager::remove(const std::string& pattern)
 {
-	interceptor_manager::interceptor.del(regex_express);
-	return app()->router->interceptor()->remove(regex_express);
+	return app()->router->interceptor()->remove(pattern);
 }
-bool fastweb::interceptor_manager::exist(const std::string& regex_express)
+bool fastweb::interceptor_manager::exist(const std::string& pattern)
 {
-	return interceptor_manager::interceptor.exist(regex_express);
+	return app()->router->interceptor()->exist(pattern);
 }
 void fastweb::interceptor_manager::clear()
 {
-	interceptor_manager::interceptor.clear();
 	if(app()->router != nullptr)
 		app()->router->interceptor()->clear();
 }
 
-bool fastweb::interceptor_manager::callback(network::http::reqpack* reqpack, const std::string& express_string)
+bool fastweb::interceptor_manager::callback(network::http::reqpack* reqpack, const std::string& pattern, const std::string& filepath)
 {
+	if (ylib::file::ext(filepath) != "lua")
+	{
+		reqpack->response()->send_file(filepath);
+		return false;
+	}
 	bool ok_continue = false;
 	auto lua = app()->state->get();
 	std::string exception_string;
 	try
 	{
-		sol::load_result script = lua->state->load_file(interceptor_manager::interceptor[express_string]);
+		sol::load_result script = lua->state->load_file(app()->config->website.dir+ filepath);
 		if (!script.valid()) {
 			sol::error err = script;
 			throw ylib::exception(err.what());

+ 6 - 7
src/core/interceptormanager.h

@@ -18,18 +18,17 @@ namespace fastweb
 		interceptor_manager(fastweb::app* app);
 		~interceptor_manager();
 
-		bool add(const std::string& regex_express,const std::string& filepath);
-		bool remove(const std::string& regex_express);
-		bool exist(const std::string& regex_express);
+		bool add(const std::string& pattern,const std::string& filepath);
+		bool remove(const std::string& pattern);
+		bool exist(const std::string& pattern);
 		void clear();
 	private:
 		/// <summary>
 		/// 服务回调
 		/// </summary>
 		/// <param name="reqpack"></param>
-		/// <param name="express_string"></param>
-		bool callback(network::http::reqpack* reqpack, const std::string& express_string);
-	private:
-		ylib::map<std::string, std::string> interceptor;
+		/// <param name="pattern"></param>
+		/// <param name="filepath"></param>
+		bool callback(network::http::reqpack* reqpack, const std::string& pattern,const std::string& filepath);
 	};
 }

+ 42 - 23
src/core/log.cpp

@@ -25,42 +25,61 @@ void fastweb::log::print(const std::string& type,const std::string& msg,const st
 #else
     ylib::println(msg, (ylib::ConsoleTextColor)color);
 #endif
-
-    if (app()->config->log.enable)
-    {
-        std::string logcontent = __now_time + " " + type + " " + msg
+    std::string logcontent = __now_time + " " + type + " " + msg
 #ifdef _WIN32
-            + "\r\n";
+        + "\r\n";
 #else
-            + "\n";
+        + "\n";
 #endif
-        std::string new_time = time::now_time(app()->config->log.name);
-        if (new_time == "")
-        {
-            std::cout << "error: The log file name is incorrect: " << app()->config->log.name << std::endl;
-            return;
-        }
-
-        if (m_current_name != new_time)
+    m_queue.push(logcontent);
+}
+bool fastweb::log::run()
+{
+    if (app()->config == nullptr)
+    {
+        system::sleep_msec(1000);
+        return true;
+    }
+    if (app()->config->log.enable == false)
+    {
+        system::sleep_msec(1000);
+        return true;
+    }
+    std::string logcontent;
+    std::string new_time = time::now_time(app()->config->log.name);
+    if (new_time == "")
+    {
+        std::cout << "error: The log file name is incorrect: " << app()->config->log.name << std::endl;
+        return false;
+    }
+    if (m_current_name != new_time)
+    {
+        m_current_name = new_time;
+        ylib::file::create_dir(app()->config->log.dir, true);
+        std::string newfilepath = app()->config->log.dir + "/" + new_time;
+        m_file.close();
+        if (m_file.open(newfilepath) == false)
         {
-            ylib::file::create_dir(app()->config->log.dir, true);
-            std::string newfilepath = app()->config->log.dir + "/" + new_time;
-            m_file.close();
-            if (m_file.open(newfilepath) == false)
-            {
-                std::cout << "error: open log file failed, filepath: " << newfilepath << std::endl;
-                return;
-            }
+            std::cout << "error: open log file failed, filepath: " << newfilepath << std::endl;
+            return false;
         }
+    }
+    while (m_queue.pop(logcontent))
+    {
         m_file.appead(logcontent);
     }
+    system::sleep_msec(1000);
+    return true;
 }
 fastweb::log::log(fastweb::app* ptr):Interface(ptr)
 {
-
+    ::ithread::start();
+    
 }
 fastweb::log::~log()
 {
+    ::ithread::stop();
+    ::ithread::wait();
 }
 void fastweb::log::success(const std::string& msg, const std::string& filepath, const std::string& func, int line)
 {

+ 6 - 1
src/core/log.h

@@ -2,9 +2,11 @@
 #include <string>
 #include "util/file.h"
 #include "core/define.h"
+#include "util/thread.h"
+#include "util/queue.hpp"
 namespace fastweb
 {
-	class log :public Interface {
+	class log :public Interface,private ylib::ithread {
 	public:
 		log(fastweb::app* ptr);
 		~log();
@@ -17,10 +19,13 @@ namespace fastweb
 		void lua(const std::string& msg);
 	private:
 		void print(const std::string& type, const std::string& msg, const std::string& filepath, const std::string& func, int line, int color, bool error);
+		bool run() override;
 	private:
 		// 当前文件名
 		std::string m_current_name;
 		// 文件
 		ylib::file_io m_file;
+		// 日志队列
+		ylib::queue<std::string> m_queue;
 	};
 }

+ 2 - 0
src/core/modulemanager.cpp

@@ -15,6 +15,7 @@
 #include "module/http/session.h"
 #include "module/http/httpclient.h"
 #include "module/http/interceptor.h"
+#include "module/http/subscribe.h"
 #include "module/globalfuns.h"
 #include "module/mutex.h"
 #include "module/codec.h"
@@ -117,6 +118,7 @@ void fastweb::module_manager::load_core(sol::state* lua)
 	module::request::regist(lua);
 	module::response::regist(lua);
 	module::interceptor::regist(lua);
+	module::subscribe::regist(lua);
 	module::session::regist(lua);
 	module::httpclient::regist(lua);
 	module::globalfuncs::regist(lua);

+ 90 - 79
src/core/subscribemanager.cpp

@@ -1,110 +1,61 @@
-#include "subscribemanager.h"
+#include "core/subscribemanager.h"
 #include "core/config.h"
 #include "core/app.h"
 #include "core/statemanager.h"
 #include "module/http/request.h"
 #include "module/http/response.h"
-fastweb::subscribe_manager::subscribe_manager(fastweb::app* ptr):Interface(ptr)
+#include "net/http_subscribe.h"
+fastweb::subscribe_manager::subscribe_manager(fastweb::app* app) :Interface(app)
 {
 }
 fastweb::subscribe_manager::~subscribe_manager()
 {
 	clear();
 }
-void fastweb::subscribe_manager::load(network::http::router* router)
+void fastweb::subscribe_manager::start()
 {
-	clear();
-	m_router = router;
-	router->other([&](network::http::request* request, network::http::response* response) {
-		this->other(request,response);
+
+	app()->router->other([&](network::http::request* request, network::http::response* response) {
+		this->other(request, response);
+		});
+}
+bool fastweb::subscribe_manager::add(const std::string& pattern, const std::string& filepath)
+{
+	app()->router->subscribe()->add(pattern, filepath, [&](network::http::request* request, network::http::response* response, const std::string& pattern, const std::string& filepath)->bool {
+		return this->callback(request, response, pattern, filepath);
 	});
+	return true;
 }
-
-void fastweb::subscribe_manager::clear()
+bool fastweb::subscribe_manager::remove(const std::string& pattern)
 {
-	if (m_router != nullptr)
-	{
-		m_router->clear_subscribe();
-	}
-	for (size_t i = 0; i < m_subextra.size(); i++)
-		delete m_subextra[i];
-	m_subextra.clear();
-	m_router = nullptr;
+	return app()->router->subscribe()->remove(pattern);
 }
-void fastweb::subscribe_manager::other(network::http::request* request, network::http::response* response)
+bool fastweb::subscribe_manager::exist(const std::string& pattern)
 {
-	auto send_404 = [&](network::http::response* response) {
-		std::string default_404 = app()->config->website.dir + "\\" + app()->config->website.default_404;
-		if (app()->config->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)
-	{
-		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 (strutils::right(request->filepath(),1) == "/")
-	{
-		for (size_t i = 0; i < app()->config->website.default_index.size(); i++)
-		{
-			filepath = app()->config->website.dir + request->filepath() + app()->config->website.default_index[i];
-			if (ylib::file::exist(filepath))
-				break;
-		}
-	}
-	else
-		filepath = app()->config->website.dir + request->filepath();
-	send_file(response, filepath);
+	return app()->router->subscribe()->exist(pattern);
 }
-
-void fastweb::subscribe_manager::exec(const std::string& filepath, network::http::request* request, network::http::response* response)
+void fastweb::subscribe_manager::clear()
 {
+	if(app()->router != nullptr)
+		app()->router->subscribe()->clear();
+}
 
+bool fastweb::subscribe_manager::callback(network::http::request* request, network::http::response* response, const std::string& pattern, const std::string& filepath)
+{
+	bool ok_continue = false;
 	auto lua = app()->state->get();
 	std::string exception_string;
 	try
 	{
-		//auto lbResult = lua->state->load_file(filepath);
-		//if (lbResult.valid() == false)
-		//{
-		//	sol::error err = lbResult;
-		//	throw ylib::exception("Failed to load script, " + std::string(err.what()));
-		//}
-		//module::request m_request(request);
-		//module::response m_response(response);
-
-		//(*lua->state)["response"] = &m_response;
-		//(*lua->state)["request"] = &m_request;
-		//lbResult();
-
-		sol::load_result script = lua->state->load_file(filepath);
+		sol::load_result script = lua->state->load_file(app()->config->website.dir + filepath);
 		if (!script.valid()) {
 			sol::error err = script;
 			throw ylib::exception(err.what());
 		}
 		module::request m_request(request);
 		module::response m_response(response);
-		(*lua->state)["response"] = &m_response;
-		(*lua->state)["request"] = &m_request;
+		(*lua->state)["response"] = m_response;
+		(*lua->state)["request"] = m_request;
 
 		sol::protected_function_result result = script();
 		if (!result.valid()) {
@@ -116,12 +67,72 @@ void fastweb::subscribe_manager::exec(const std::string& filepath, network::http
 	{
 		exception_string = e.what();
 		if (app()->config->website.debug)
-			LOG_ERROR("[subscribe_service][" + request->filepath() + "]: " + e.what());
+			LOG_ERROR("[subscribe][" + request->filepath() + "]: " + e.what());
 	}
-	// 清理
 	lua->state->collect_garbage();
 	app()->state->push(lua);
 
 	if (exception_string.empty() == false)
 		throw ylib::exception(exception_string);
+
+	return ok_continue;
+}
+
+void fastweb::subscribe_manager::other(network::http::request* request, network::http::response* response)
+{
+	std::string filepath = request->filepath();
+	if (filepath.empty())
+		filepath = "/";
+
+	
+
+	// 搜寻默认页面
+	if (filepath[filepath.length()-1] == '/')
+	{
+		std::string default_filepath;
+		for (size_t i = 0; i < app()->config->website.default_index.size(); i++)
+		{
+			default_filepath = app()->config->website.dir + filepath + app()->config->website.default_index[i];
+			if (ylib::file::exist(default_filepath))
+			{
+				filepath += app()->config->website.default_index[i];
+				break;
+			}
+		}
+	}
+
+	std::string ext = ylib::file::ext(filepath);
+	// 判断LUA
+	if (ext == "lua")
+	{
+		if (app()->config->website.direct_url_mapping)
+		{
+			callback(request,response,filepath,filepath);
+		}
+		else
+		{
+			send_404(response);
+		}
+		return;
+	}
+
+	// 发送静态文件
+	std::string absolute_path = app()->config->website.dir + filepath;
+	if (ylib::file::exist(absolute_path))
+		response->send_file(absolute_path);
+	else
+		send_404(response);
+}
+
+void fastweb::subscribe_manager::send_404(network::http::response* response)
+{
+	std::string default_404 = app()->config->website.dir + "\\" + app()->config->website.default_404;
+	if (app()->config->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");
+	}
 }

+ 19 - 12
src/core/subscribemanager.h

@@ -1,41 +1,48 @@
 #pragma once
 
 
-#include "sol/sol.hpp"
 #include "core/structs.h"
 #include "core/define.h"
+#include "net/http_reqpack.h"
 #include "net/http_request.h"
 #include "net/http_response.h"
 #include "net/http_router.h"
+#include "util/map.hpp"
 namespace fastweb
 {
 	/// <summary>
 	/// 订阅管理器
 	/// </summary>
-	class subscribe_manager:public Interface {
+	class subscribe_manager :public Interface {
 	public:
-		subscribe_manager(fastweb::app* ptr);
+		subscribe_manager(fastweb::app* app);
 		~subscribe_manager();
 
-		void load(network::http::router* router);
+		void start();
+		bool add(const std::string& pattern, const std::string& filepath);
+		bool remove(const std::string& pattern);
+		bool exist(const std::string& pattern);
 		void clear();
 	private:
 		/// <summary>
-		/// 其它
+		/// 服务回调
 		/// </summary>
 		/// <param name="request"></param>
 		/// <param name="response"></param>
-		/// <param name="extra"></param>
-		void other(network::http::request* request, network::http::response* response);
+		/// <param name="pattern"></param>
+		/// <param name="filepath"></param>
+		bool callback(network::http::request* request, network::http::response* response, const std::string& pattern, const std::string& filepath);
 		/// <summary>
-		/// 执行lua
+		/// 其它
 		/// </summary>
-		/// <param name="filepath"></param>
 		/// <param name="request"></param>
 		/// <param name="response"></param>
-		void exec(const std::string& filepath, network::http::request* request, network::http::response* response);
+		void other(network::http::request* request, network::http::response* response);
 	private:
-		network::http::router* m_router = nullptr;
-		std::vector<std::string*> m_subextra;
+		/// <summary>
+		/// 未找到页面
+		/// </summary>
+		/// <param name="response"></param>
+		void send_404(network::http::response* response);
 	};
 }

+ 6 - 6
src/module/http/interceptor.cpp

@@ -9,22 +9,22 @@ module::interceptor::~interceptor()
 {
 }
 
-bool module::interceptor::add(const std::string& express_string, const std::string& filepath, sol::this_state ts)
+bool module::interceptor::add(const std::string& pattern, const std::string& filepath, sol::this_state ts)
 {
 	GET_APP;
-	return app->interceptor->add(express_string,app->config->website.dir+ filepath);
+	return app->interceptor->add(pattern,filepath);
 }
 
-bool module::interceptor::remove(const std::string& express_string, sol::this_state ts)
+bool module::interceptor::remove(const std::string& pattern, sol::this_state ts)
 {
 	GET_APP;
-	return app->interceptor->remove(express_string);
+	return app->interceptor->remove(pattern);
 }
 
-bool module::interceptor::exist(const std::string& express_string, sol::this_state ts)
+bool module::interceptor::exist(const std::string& pattern, sol::this_state ts)
 {
 	GET_APP;
-	return app->interceptor->exist(express_string);
+	return app->interceptor->exist(pattern);
 }
 
 void module::interceptor::clear(sol::this_state ts)

+ 6 - 6
src/module/http/interceptor.h

@@ -13,21 +13,21 @@ namespace module
         /// <summary>
         /// 添加
         /// </summary>
-        /// <param name="express_string"></param>
+        /// <param name="pattern"></param>
         /// <param name="filepath"></param>
         /// <returns></returns>
-        static bool add(const std::string& express_string,const std::string& filepath, sol::this_state ts);
+        static bool add(const std::string& pattern,const std::string& filepath, sol::this_state ts);
         /// <summary>
         /// 移除
         /// </summary>
-        /// <param name="express_string"></param>
-        static bool remove(const std::string& express_string, sol::this_state ts);
+        /// <param name="pattern"></param>
+        static bool remove(const std::string& pattern, sol::this_state ts);
         /// <summary>
         /// 是否存在
         /// </summary>
-        /// <param name="express_string"></param>
+        /// <param name="pattern"></param>
         /// <returns></returns>
-        static bool exist(const std::string& express_string, sol::this_state ts);
+        static bool exist(const std::string& pattern, sol::this_state ts);
         /// <summary>
         /// 清空
         /// </summary>

+ 44 - 0
src/module/http/subscribe.cpp

@@ -0,0 +1,44 @@
+#include "subscribe.h"
+#include "core/app.h"
+
+module::subscribe::subscribe()
+{
+}
+
+module::subscribe::~subscribe()
+{
+}
+
+bool module::subscribe::add(const std::string& express_string, const std::string& filepath, sol::this_state ts)
+{
+	GET_APP;
+	return app->subscribe->add(express_string,filepath);
+}
+
+bool module::subscribe::remove(const std::string& express_string, sol::this_state ts)
+{
+	GET_APP;
+	return app->subscribe->remove(express_string);
+}
+
+bool module::subscribe::exist(const std::string& express_string, sol::this_state ts)
+{
+	GET_APP;
+	return app->subscribe->exist(express_string);
+}
+
+void module::subscribe::clear(sol::this_state ts)
+{
+	GET_APP;
+	return app->subscribe->clear();
+}
+
+void module::subscribe::regist(sol::state* lua)
+{
+	lua->new_usertype<module::subscribe>("subscribe",
+		"add", &module::subscribe::add,
+		"remove", &module::subscribe::remove,
+		"exist", &module::subscribe::exist,
+		"clear", &module::subscribe::clear
+	);
+}

+ 39 - 0
src/module/http/subscribe.h

@@ -0,0 +1,39 @@
+#pragma once
+#include "net/http_request.h"
+#include "net/http_response.h"
+#include "sol/sol.hpp"
+
+namespace module
+{
+    class subscribe
+    {
+    public:
+        subscribe();
+        ~subscribe();
+        /// <summary>
+        /// 添加
+        /// </summary>
+        /// <param name="pattern"></param>
+        /// <param name="filepath"></param>
+        /// <returns></returns>
+        static bool add(const std::string& pattern,const std::string& filepath, sol::this_state ts);
+        /// <summary>
+        /// 移除
+        /// </summary>
+        /// <param name="pattern"></param>
+        static bool remove(const std::string& pattern, sol::this_state ts);
+        /// <summary>
+        /// 是否存在
+        /// </summary>
+        /// <param name="pattern"></param>
+        /// <returns></returns>
+        static bool exist(const std::string& pattern, sol::this_state ts);
+        /// <summary>
+        /// 清空
+        /// </summary>
+        static void clear(sol::this_state ts);
+       
+        static void regist(sol::state* lua);
+    };
+}
+

+ 0 - 3
www/api/lib/init.lua

@@ -1,9 +1,6 @@
 
 
 print("init fast web success!")
--- 自定义模块演示
-local hello = hello.new()
-print("Custom Module: "..hello:name())
 -- 增加拦截器
 interceptor.add("/api/*.*","/api/lib/interceptor.lua")
 return true