From e0f70152ff4a7a7a4b635aa521572c4cefd2e729 Mon Sep 17 00:00:00 2001 From: xx Date: Sat, 8 Jun 2024 16:52:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/net/http_interceptor.h | 16 ++--- include/net/http_router.h | 71 +++--------------- include/net/http_subscribe.h | 45 ++++++++++++ src/net/http_cdn.cpp | 5 +- src/net/http_interceptor.cpp | 33 ++++----- src/net/http_router.cpp | 128 +++++---------------------------- src/net/http_subscribe.cpp | 78 ++++++++++++++++++++ 7 files changed, 176 insertions(+), 200 deletions(-) create mode 100644 include/net/http_subscribe.h create mode 100644 src/net/http_subscribe.cpp diff --git a/include/net/http_interceptor.h b/include/net/http_interceptor.h index abd59b5..37f1f12 100644 --- a/include/net/http_interceptor.h +++ b/include/net/http_interceptor.h @@ -16,9 +16,10 @@ namespace ylib class reqpack; struct interceptor_info { - std::regex express; - std::string express_string; - std::function callback; + std::regex regex; + std::string pattern; + std::string extra; + std::function callback; }; /****************************************************** * class:拦截器 @@ -27,15 +28,14 @@ namespace ylib { public: interceptor(); - ~interceptor(); - bool add(const std::string& regex_express, std::function callback); - bool remove(const std::string& regex_express); - bool exist(const std::string& regex_express); + ~interceptor(); + bool add(const std::string& pattern,const std::string& extra,std::function callback); + bool remove(const std::string& pattern); + bool exist(const std::string& pattern); bool trigger(const std::string& url, network::http::reqpack* rp); void clear(); private: std::vector m_list; - std::shared_mutex m_rw_mutex; }; } diff --git a/include/net/http_router.h b/include/net/http_router.h index 84d94db..1f2ffe5 100644 --- a/include/net/http_router.h +++ b/include/net/http_router.h @@ -21,37 +21,7 @@ namespace ylib class request; class response; class interceptor; - /************************************* - * struct:订阅信息 - *************************************/ - struct subscribe_info { - subscribe_info() - { - method = network::http::ALL; - controller = false; - controller_function = nullptr; - } - // 请求路径 - std::regex express; - // 请求类型 - network::http::method method; - // 回调函数 - std::function callback; - // 控制器。为控制器则启动下面两个属性 - bool controller; - // 创建控制器类指针 - std::function create_controller_callback; - // 控制器函数 - HTTP_CTR_FUNCTION controller_function; -#if HTTP_LUA_ENGINE == 1 - // LUA - std::string lua_filepath; - // LUA虚拟机初始化回调 - std::function lua_init_state; -#endif - // 附加数据 - void* extra = nullptr; - }; + class subscribe; /************************************************************************* * class:路由中专服务 *************************************************************************/ @@ -65,7 +35,6 @@ namespace ylib network::http::router* router; network::http::reqpack* reqpack; }; - public: router(); ~router(); @@ -86,34 +55,9 @@ namespace ylib ******************************************************************/ network::http::interceptor* interceptor(); /****************************************************************** - * function:订阅 - * desc:浏览器请求会首先触发订阅,订阅未找到符合项则触发 other 传入函数。 - * param - * path : 路径 - * method : 请求类型 - * callback : 触发回调 - * return: - * 同一地址不允许订阅两次 - ******************************************************************/ - void subscribe( - const std::string& path, - network::http::method method, - std::function callback, - void* extra = nullptr - ); -#define SUBSCRIBE(ROUTER,CONTROLLER,FUNCTION,PATH,METHOD) ROUTER->subscribe([]()->void*{return new CONTROLLER;},(ylib::network::http::HTTP_CTR_FUNCTION)&CONTROLLER::FUNCTION,PATH,METHOD) - - void subscribe( - std::function create_controller_callback, - network::http::HTTP_CTR_FUNCTION function, - std::string path, - network::http::method method - ); - - /// - /// 清理所有订阅 - /// - void clear_subscribe(); + * function:订阅器 + ******************************************************************/ + network::http::subscribe* subscribe(); /****************************************************************** * function:其它 * desc:未订阅请求触发该回调 @@ -155,8 +99,6 @@ namespace ylib void lua_engine(reqpack *rp,const network::http::subscribe_info& info); #endif private: - // 订阅列表 - ylib::nolock_array m_subscribe; // 线程池 IHPThreadPool* m_threadpool; // [回调] 未订阅请求 @@ -166,7 +108,10 @@ namespace ylib // [回调] 发送前 std::function m_callback_sendbefore; // 拦截器 - network::http::interceptor* m_interceptor; + std::unique_ptr m_interceptor; + // 订阅器 + std::unique_ptr m_subscribe; + private: ylib::queue m_handle_queue; router_config m_config; diff --git a/include/net/http_subscribe.h b/include/net/http_subscribe.h new file mode 100644 index 0000000..4a4d3db --- /dev/null +++ b/include/net/http_subscribe.h @@ -0,0 +1,45 @@ +#pragma once +#include "define.h" +#if USE_NET_HTTP_WEBSITE +#include +#include +#include +#include "http_interface.h" + +namespace ylib +{ + namespace network + { + namespace http + { + class request; + class response; + class reqpack; + struct subscribe_info { + std::regex regex; + std::string pattern; + std::string extra; + std::function callback; + }; + /****************************************************** + * class:订阅器 + ******************************************************/ + class subscribe :public ylib::error_base, public network::http::interface_ + { + public: + subscribe(); + ~subscribe(); + bool add(const std::string& pattern,const std::string& extra,std::function callback); + bool remove(const std::string& pattern); + bool exist(const std::string& pattern); + bool trigger(const std::string& url, network::http::reqpack* rp); + void clear(); + private: + std::vector m_list; + std::shared_mutex m_rw_mutex; + }; + } + } +} + +#endif diff --git a/src/net/http_cdn.cpp b/src/net/http_cdn.cpp index 7bd1999..e82cd02 100644 --- a/src/net/http_cdn.cpp +++ b/src/net/http_cdn.cpp @@ -4,6 +4,7 @@ #include "net/http_reqpack.h" #include "net/http_response.h" #include "net/http_request.h" +#include "net/http_subscribe.h" network::http::cnode::cnode(const cdn_config::node_config& config){ m_reply_wait_msec = 0; @@ -81,7 +82,7 @@ bool network::http::cdn::start(const cdn_config& config){ else { std::cout<<"CDN:Node start"<router()->subscribe("/info",network::http::GET,[&](network::http::request* request,network::http::response* response,void* extra){ + /* website()->router()->subscribe()->add("/info",network::http::GET,[&](network::http::request* request,network::http::response* response,void* extra){ ylib::json rep; std::string value_key; if(request->header("key",value_key) == false || m_cdn_node_key != value_key){ @@ -98,7 +99,7 @@ bool network::http::cdn::start(const cdn_config& config){ rep["up_sec_byte"] = m_cdn_node_bandinfo.up_sec_byte; rep["max_band"] = m_cdn_node_max_band; response->send(rep); - }); + });*/ } ::ithread::start(); diff --git a/src/net/http_interceptor.cpp b/src/net/http_interceptor.cpp index 7735d3d..686bf8d 100644 --- a/src/net/http_interceptor.cpp +++ b/src/net/http_interceptor.cpp @@ -13,28 +13,29 @@ network::http::interceptor::~interceptor() { clear(); } -bool network::http::interceptor::add(const std::string& express, std::function callback) +bool network::http::interceptor::add(const std::string& pattern, const std::string& extra, std::function callback) { std::unique_lock lock(m_rw_mutex); // 判断是否存在 for (size_t i = 0; i < m_list.size(); i++) { - if (m_list.at(i).express_string == express) + if (m_list.at(i).pattern == pattern) return false; } network::http::interceptor_info info; - info.express = std::regex(express.c_str()); + info.regex = std::regex(pattern.c_str()); info.callback = callback; - info.express_string = express; + info.pattern = pattern; + info.extra = extra; m_list.push_back(info); return true; } -bool ylib::network::http::interceptor::remove(const std::string& regex_express) +bool ylib::network::http::interceptor::remove(const std::string& pattern) { std::unique_lock lock(m_rw_mutex); - for(auto iter = m_list.begin();iter != m_list.end();) + for (auto iter = m_list.begin(); iter != m_list.end();) { - if (iter->express_string == regex_express) + if (iter->pattern == pattern) { m_list.erase(iter); return true; @@ -44,12 +45,12 @@ bool ylib::network::http::interceptor::remove(const std::string& regex_express) } return false; } -bool ylib::network::http::interceptor::exist(const std::string& regex_express) +bool ylib::network::http::interceptor::exist(const std::string& pattern) { std::shared_lock lock(m_rw_mutex); for (size_t i = 0; i < m_list.size(); i++) { - if (m_list.at(i).express_string == regex_express) + if (m_list.at(i).pattern == pattern) return true; } return false; @@ -58,15 +59,15 @@ bool network::http::interceptor::trigger(const std::string& url, network::http:: { std::shared_lock lock(m_rw_mutex); - if(m_list.size() == 0) + if (m_list.size() == 0) return true; - for(size_t i=0;iwarn("["+rp->exec_msec()+" ms] false url:"+url+"\t"+" express:"+info->express_string+" ip:"+rp->request()->remote_ipaddress(true),"interceptor"); + ylib::log->warn("[" + rp->exec_msec() + " ms] false url:" + url + "\t" + " express:" + info->express_string + " ip:" + rp->request()->remote_ipaddress(true), "interceptor"); #endif } return result; diff --git a/src/net/http_router.cpp b/src/net/http_router.cpp index 84d00d3..ff7dbfd 100644 --- a/src/net/http_router.cpp +++ b/src/net/http_router.cpp @@ -12,6 +12,7 @@ #include "net/http_agent.h" #include "net/http_cache.h" #include "net/http_cdn.h" +#include "net/http_subscribe.h" #include "HPSocket/HPSocket.h" #include "util/system.h" #if HTTP_LUA_ENGINE == 1 @@ -22,13 +23,13 @@ ylib::network::http::router::router() { m_threadpool = nullptr; - m_interceptor = new network::http::interceptor; + m_interceptor = std::make_unique(); + m_subscribe = std::make_unique(); } ylib::network::http::router::~router() { close(); - delete m_interceptor; } bool network::http::router::start(const router_config &config) @@ -68,49 +69,16 @@ void network::http::router::close() this->m_threadpool = nullptr; } m_interceptor->clear(); - clear_subscribe(); + m_subscribe->clear(); } network::http::interceptor* network::http::router::interceptor(){ m_interceptor->center(center()); - return m_interceptor; + return m_interceptor.get(); } - -void network::http::router::subscribe(const std::string &path, network::http::method method, std::function callback, void* extra) +network::http::subscribe* ylib::network::http::router::subscribe() { -#if HTTP_ROUTER_PRINT == 1 - ylib::log->info("[subscribe][func] express:"+path+" method:"+method_to_string(method),"router"); -#endif - network::http::subscribe_info *svie = new network::http::subscribe_info; - svie->controller = false; - svie->method = method; - svie->express = std::regex(path.c_str()); - svie->callback = callback; - svie->extra = extra; - m_subscribe.append(svie); -} -void network::http::router::subscribe( - std::function create_controller_callback, - network::http::HTTP_CTR_FUNCTION function, - std::string path, - network::http::method method -) -{ -#if HTTP_ROUTER_PRINT == 1 - ylib::log->info("[subscribe][ctl] express:"+path+" method:"+method_to_string(method),"router"); -#endif - network::http::subscribe_info *svie = new network::http::subscribe_info; - svie->controller = true; - svie->method = method; - svie->express = std::regex(path.c_str()); - svie->create_controller_callback = create_controller_callback; - svie->controller_function = function; - m_subscribe.append(svie); -} -void ylib::network::http::router::clear_subscribe() -{ - for (size_t i = 0; i < m_subscribe.size(); i++) - delete m_subscribe.get(i); - m_subscribe.free(); + m_subscribe->center(center()); + return m_subscribe.get(); } void network::http::router::other(std::function callback) { @@ -150,88 +118,26 @@ void ylib::network::http::router::__thread_callback(reqpack* rp) if (is_proxy(rp)) return; /*===============正常请求=================*/ - //拦截器过滤 + try { + // 拦截器过滤 if (m_interceptor->trigger(rp->filepath(), rp) == false) { // 已拒绝继续执行 return; } + // 订阅 + if (m_subscribe->trigger(rp->filepath(), rp)) + return; // 已被处理 + + // 其它 + if (m_callback_other != nullptr) + m_callback_other(rp->request(), rp->response()); } catch (const std::exception& e) { -#if HTTP_ROUTER_PRINT == 1 - // 通用异常返回 - ylib::log->error("(interceptor)business processing exception:" + std::string(e.what()) + ", url:" + rp->filepath() + " ip:" + rp->request()->remote_ipaddress(true), "router"); -#endif rp->response()->send((std::string)e.what(), 500, "Internal Server Error"); - return; - } - bool execed = false; - for(size_t i=0;ifilepath().c_str(),sub->express) && (sub->method == rp->method() || sub->method == network::http::ALL)) - { - execed = true; - try - { - //开始回调 - if (sub->controller) - { - //controller 类型回调 - std::unique_ptr controller((network::http::controller*)sub->create_controller_callback()); - controller->m_reqpack = rp; - controller->center(center()); - //调用处理函数 - (controller.get()->*sub->controller_function)(); - } - else - { - //普通回调 - if (sub->callback != nullptr) - { - sub->callback(rp->request(), rp->response(),sub->extra); - } - else - { -#if HTTP_LUA_ENGINE == 1 - lua_engine(rp,*sub); -#endif - } - } -#if HTTP_ROUTER_PRINT == 1 - ylib::log->info("["+rp->exec_msec()+" ms] controller url:"+rp->filepath()+" ip:"+rp->request()->remote_ipaddress(true),"router"); -#endif - } - catch (const std::exception& e) - { -#if HTTP_ROUTER_PRINT == 1 - // 通用异常返回 - ylib::log->error("business processing exception:" + std::string(e.what()) + ", url:" + rp->filepath()+" ip:"+rp->request()->remote_ipaddress(true),"router"); -#endif - rp->response()->send((std::string)e.what(), 500, "Internal Server Error"); - } - break; - - } - - } - if(execed == false){ - //其它回调 - if (m_callback_other != nullptr) { - try - { - m_callback_other(rp->request(), rp->response()); - } - catch (const std::exception& e) - { - rp->response()->send((std::string)e.what(), 500, "Internal Server Error"); - } - - }else{ - rp->response()->send((std::string)"Services that have not been processed",500,"Service Unavailable"); - } } } size_t ylib::network::http::router::queue_size() diff --git a/src/net/http_subscribe.cpp b/src/net/http_subscribe.cpp new file mode 100644 index 0000000..de86cef --- /dev/null +++ b/src/net/http_subscribe.cpp @@ -0,0 +1,78 @@ +#include "net/http_subscribe.h" +#include "net/http_reqpack.h" +#include "net/http_request.h" +#include +#include "net/http_center.h" +#include "util/time.h" +#if USE_NET_HTTP_WEBSITE +network::http::subscribe::subscribe() +{ + +} +network::http::subscribe::~subscribe() +{ + clear(); +} +bool network::http::subscribe::add(const std::string& pattern, const std::string& extra, std::function callback) +{ + std::unique_lock lock(m_rw_mutex); + // 判断是否存在 + for (size_t i = 0; i < m_list.size(); i++) + { + if (m_list.at(i).pattern == pattern) + return false; + } + network::http::subscribe_info info; + info.regex = std::regex(pattern.c_str()); + info.callback = callback; + info.pattern = pattern; + info.extra = extra; + m_list.push_back(info); + return true; +} +bool ylib::network::http::subscribe::remove(const std::string& pattern) +{ + std::unique_lock lock(m_rw_mutex); + for (auto iter = m_list.begin(); iter != m_list.end();) + { + if (iter->pattern == pattern) + { + m_list.erase(iter); + return true; + } + else + iter++; + } + return false; +} +bool ylib::network::http::subscribe::exist(const std::string& pattern) +{ + std::shared_lock lock(m_rw_mutex); + for (size_t i = 0; i < m_list.size(); i++) + { + if (m_list.at(i).pattern == pattern) + return true; + } + return false; +} +bool network::http::subscribe::trigger(const std::string& url, network::http::reqpack* rp) +{ + std::shared_lock lock(m_rw_mutex); + + if (m_list.size() == 0) + return false; + for (size_t i = 0; i < m_list.size(); i++) + { + if (std::regex_match(url.c_str(), m_list[i].regex)) { + m_list[i].callback(rp->request(),rp->response(), m_list[i].pattern,m_list[i].extra); + return true; + } + } + return false; +} +void ylib::network::http::subscribe::clear() +{ + std::unique_lock lock(m_rw_mutex); + m_list.clear(); +} +#endif