优化更新
This commit is contained in:
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
45
include/net/http_subscribe.h
Normal file
45
include/net/http_subscribe.h
Normal 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
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
78
src/net/http_subscribe.cpp
Normal file
78
src/net/http_subscribe.cpp
Normal 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
|
||||
Reference in New Issue
Block a user