From c8b19c26b9057387f7e79a1b7b568e849accba0d Mon Sep 17 00:00:00 2001 From: tickbh Date: Wed, 24 Jan 2024 17:54:18 +0800 Subject: [PATCH] comm --- config/reverse.toml | 2 +- src/reverse/common.rs | 15 +++++++++- src/reverse/location.rs | 6 +++- src/reverse/matcher.rs | 63 ++++++++++++++++++++++++++++------------- src/reverse/server.rs | 8 ++++++ 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/config/reverse.toml b/config/reverse.toml index 440c563..ebe791d 100644 --- a/config/reverse.toml +++ b/config/reverse.toml @@ -72,7 +72,7 @@ try_paths = "{path}/ '/ro(\\w+)/(.*) {path} /ro$1/Cargo.toml' /root/README.md" # allow_ip = "127.0.0.1" [[http.server.location]] -rule = "/ws" +rule = "@ws" is_ws = true proxy_url = "http://ws" headers = ["+ aaa bbb"] diff --git a/src/reverse/common.rs b/src/reverse/common.rs index 517b559..88853f2 100644 --- a/src/reverse/common.rs +++ b/src/reverse/common.rs @@ -20,7 +20,7 @@ use webparse::Url; use wenmeng::RateLimitLayer; use wenmeng::TimeoutLayer; -use super::LimitReq; +use super::{LimitReq, Matcher}; #[serde_as] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] @@ -65,6 +65,10 @@ pub struct CommonConfig { pub domain: Option, #[serde_as(as = "Option")] pub proxy_url: Option, + + #[serde(default = "HashMap::new")] + #[serde_as(as = "HashMap<_, DisplayFromStr>")] + pub match_names: HashMap, } impl CommonConfig { @@ -95,6 +99,8 @@ impl CommonConfig { domain: None, proxy_url: None, + + match_names: HashMap::new(), } } @@ -141,12 +147,19 @@ impl CommonConfig { if self.deny_ip.is_none() { self.deny_ip = parent.deny_ip.clone(); } + + for p in &parent.match_names { + if !self.match_names.contains_key(p.0) { + self.match_names.insert(p.0.clone(), p.1.clone()); + } + } } pub fn pre_deal(&mut self) { if let Some(err) = &mut self.error_log { err.as_error(); } + } pub fn get_rate_limit(&self) -> Option { diff --git a/src/reverse/location.rs b/src/reverse/location.rs index 2a2ac38..a7e830c 100644 --- a/src/reverse/location.rs +++ b/src/reverse/location.rs @@ -110,7 +110,11 @@ impl LocationConfig { /// 当本地限制方法时,优先匹配方法,在进行路径的匹配 pub fn is_match_rule(&self, path: &String, req: &RecvRequest) -> bool { - self.rule.is_match_rule(path, req) + match self.rule.is_match_rule(path, req) { + Err(_) => false, + Ok(b) => b, + } + } async fn deal_client( diff --git a/src/reverse/matcher.rs b/src/reverse/matcher.rs index 9439264..747f42a 100644 --- a/src/reverse/matcher.rs +++ b/src/reverse/matcher.rs @@ -13,7 +13,7 @@ use std::{ collections::HashSet, fmt::{self, Display}, - str::FromStr, + str::FromStr, net::IpAddr, }; use serde::{ @@ -21,7 +21,7 @@ use serde::{ }; use serde_with::{serde_as, DisplayFromStr}; use webparse::{Method, Scheme, WebError}; -use wenmeng::RecvRequest; +use wenmeng::{RecvRequest, ProtResult, ProtError}; use crate::IpSets; @@ -53,6 +53,15 @@ impl Matcher { } } + pub fn get_match_name(&self) -> Option { + if let Some(p) = &self.path { + if p.starts_with("@") { + return Some(p.replace("@", "")); + } + } + None + } + pub fn get_path(&self) -> String { if let Some(p) = &self.path { if p.contains("*") { @@ -69,33 +78,47 @@ impl Matcher { /// 当本地限制方法时,优先匹配方法,在进行路径的匹配 - pub fn is_match_rule(&self, path: &String, req: &RecvRequest) -> bool { + pub fn is_match_rule(&self, path: &String, req: &RecvRequest) -> ProtResult { if let Some(p) = &self.path { if path.find(&*p).is_none() { - return false; + return Ok(false); } } + if let Some(m) = &self.method { if !m.0.contains(req.method()) { - return false; + return Ok(false); + } + } + + if let Some(s) = &self.scheme { + if !s.0.contains(req.scheme()) { + return Ok(false); + } + } + + if let Some(h) = &self.host { + match req.get_host() { + Some(host) if &host == h => {}, + _ => return Ok(false), + } + } + + if let Some(c) = &self.client_ip { + match req.headers().system_get("{client_ip}") { + Some(ip) => { + let ip = ip + .parse::() + .map_err(|_| ProtError::Extension("client ip error"))?; + if !c.contains(&ip) { + return Ok(false) + } + }, + None => return Ok(false), } } - true - // if self.method.is_some() - // && !self - // .method - // .as_ref() - // .unwrap() - // .eq_ignore_ascii_case(method.as_str()) - // { - // return false; - // } - // if let Some(_) = path.find(&self.rule) { - // return true; - // } else { - // false - // } + Ok(true) } } diff --git a/src/reverse/server.rs b/src/reverse/server.rs index 043084b..2c4f0f2 100644 --- a/src/reverse/server.rs +++ b/src/reverse/server.rs @@ -75,6 +75,14 @@ impl ServerConfig { for l in &mut self.location { l.comm.copy_from_parent(&self.comm); l.comm.pre_deal(); + if let Some(n) = l.rule.get_match_name() { + if l.comm.match_names.contains_key(&n) { + l.rule = l.comm.match_names[&n].clone(); + } else { + log::error!("配置匹配名字@{},但未找到相应的配置", n); + println!("配置匹配名字@{},但未找到相应的配置", n); + } + } l.up_name = Some(self.up_name.clone()); l.upstream.append(&mut self.upstream.clone()); l.headers.append(&mut self.headers.clone());