优化更新

This commit is contained in:
xx
2024-06-08 16:52:22 +08:00
parent 3cec02b819
commit e0f70152ff
7 changed files with 176 additions and 200 deletions

View File

@@ -16,9 +16,10 @@ namespace ylib
class reqpack;
struct interceptor_info {
std::regex express;
std::string express_string;
std::function<bool(network::http::reqpack* rp, const std::string& express)> callback;
std::regex regex;
std::string pattern;
std::string extra;
std::function<bool(network::http::reqpack* rp, const std::string& pattern,const std::string& extra)> callback;
};
/******************************************************
* class拦截器
@@ -27,15 +28,14 @@ namespace ylib
{
public:
interceptor();
~interceptor();
bool add(const std::string& regex_express, std::function<bool(network::http::reqpack* rp,const std::string& express)> 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<bool(network::http::reqpack* rp, const std::string& pattern, const std::string& extra)> 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<interceptor_info> m_list;
std::shared_mutex m_rw_mutex;
};
}

View File

@@ -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<void(network::http::request*, network::http::response*,void *extra)> callback;
// 控制器。为控制器则启动下面两个属性
bool controller;
// 创建控制器类指针
std::function<void* ()> create_controller_callback;
// 控制器函数
HTTP_CTR_FUNCTION controller_function;
#if HTTP_LUA_ENGINE == 1
// LUA
std::string lua_filepath;
// LUA虚拟机初始化回调
std::function<void(sol::state& state)> 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<void(network::http::request*, network::http::response*, void*)> 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<void* ()> create_controller_callback,
network::http::HTTP_CTR_FUNCTION function,
std::string path,
network::http::method method
);
/// <summary>
/// 清理所有订阅
/// </summary>
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<network::http::subscribe_info*> m_subscribe;
// 线程池
IHPThreadPool* m_threadpool;
// [回调] 未订阅请求
@@ -166,7 +108,10 @@ namespace ylib
// [回调] 发送前
std::function<void(const ylib::buffer& begin, ylib::buffer* end)> m_callback_sendbefore;
// 拦截器
network::http::interceptor* m_interceptor;
std::unique_ptr<network::http::interceptor> m_interceptor;
// 订阅器
std::unique_ptr<network::http::subscribe> m_subscribe;
private:
ylib::queue<network::http::reqpack*> m_handle_queue;
router_config m_config;

View File

@@ -0,0 +1,45 @@
#pragma once
#include "define.h"
#if USE_NET_HTTP_WEBSITE
#include <regex>
#include <functional>
#include <shared_mutex>
#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<void(network::http::request* request,network::http::response* response,const std::string& pattern,const std::string& extra)> 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<void(network::http::request* request, network::http::response* response, const std::string& pattern, const std::string& extra)> 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<subscribe_info> m_list;
std::shared_mutex m_rw_mutex;
};
}
}
}
#endif

View File

@@ -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"<<std::endl;
website()->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();

View File

@@ -13,28 +13,29 @@ network::http::interceptor::~interceptor()
{
clear();
}
bool network::http::interceptor::add(const std::string& express, std::function<bool(network::http::reqpack* rp,const std::string&)> callback)
bool network::http::interceptor::add(const std::string& pattern, const std::string& extra, std::function<bool(network::http::reqpack* rp, const std::string&,const std::string&)> callback)
{
std::unique_lock<std::shared_mutex> 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<std::shared_mutex> 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<std::shared_mutex> 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<std::shared_mutex> lock(m_rw_mutex);
if(m_list.size() == 0)
if (m_list.size() == 0)
return true;
for(size_t i=0;i<m_list.size();i++)
{
if(std::regex_match(url.c_str(),m_list[i].express)) {
bool result = m_list[i].callback(rp, m_list[i].express_string);
if(result == false){
for (size_t i = 0; i < m_list.size(); i++)
{
if (std::regex_match(url.c_str(), m_list[i].regex)) {
bool result = m_list[i].callback(rp, m_list[i].pattern, m_list[i].extra);
if (result == false) {
#if HTTP_INTERCEPTOR_PRINT == 1
ylib::log->warn("["+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;

View File

@@ -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<network::http::interceptor>();
m_subscribe = std::make_unique<network::http::subscribe>();
}
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<void(network::http::request*,network::http::response*,void*)> 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<void* ()> 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<void(network::http::request*,network::http::response*)> 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;i<m_subscribe.m_count;i++){
auto sub = m_subscribe.get(i);
if (std::regex_match(rp->filepath().c_str(),sub->express) && (sub->method == rp->method() || sub->method == network::http::ALL))
{
execed = true;
try
{
//开始回调
if (sub->controller)
{
//controller 类型回调
std::unique_ptr<network::http::controller> 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()

View File

@@ -0,0 +1,78 @@
#include "net/http_subscribe.h"
#include "net/http_reqpack.h"
#include "net/http_request.h"
#include <iostream>
#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<void(network::http::request* request, network::http::response* response, const std::string& pattern,const std::string& extra)> callback)
{
std::unique_lock<std::shared_mutex> 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<std::shared_mutex> 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<std::shared_mutex> 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<std::shared_mutex> 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<std::shared_mutex> lock(m_rw_mutex);
m_list.clear();
}
#endif