Per path rate limiter

This commit is contained in:
Ara Sadoyan
2025-07-24 13:34:15 +02:00
parent 6f012cee69
commit 2ad3a059ab
9 changed files with 114 additions and 57 deletions

View File

@@ -133,6 +133,7 @@ async fn get_by_http(url: String, token: Option<String>) -> Option<DashMap<Strin
is_ssl: false,
is_http2: false,
to_https: false,
rate_limit: None,
};
values.push(to_add);
}

View File

@@ -44,6 +44,7 @@ pub async fn hc2(upslist: Arc<UpstreamsDashMap>, fullist: Arc<UpstreamsDashMap>,
is_ssl: tls.0,
is_http2: is_h2,
to_https: k.1.to_https,
rate_limit: k.1.rate_limit,
};
let resp = http_request(_link.as_str(), params.0, "", &client).await;
match resp.0 {
@@ -55,6 +56,7 @@ pub async fn hc2(upslist: Arc<UpstreamsDashMap>, fullist: Arc<UpstreamsDashMap>,
is_ssl: tls.0,
is_http2: is_h2,
to_https: k.1.to_https,
rate_limit: k.1.rate_limit,
};
}
innervec.push(scheme);

View File

@@ -80,6 +80,10 @@ fn populate_headers_and_auth(config: &mut Configuration, parsed: &Config) {
config.extraparams.to_https = parsed.to_https;
config.extraparams.rate_limit = parsed.rate_limit;
if let Some(rate) = &parsed.rate_limit {
info!("Applied Global Rate Limit : {} request per second", rate);
}
if let Some(auth) = &parsed.authorization {
let name = auth.get("type").unwrap_or(&"".to_string()).to_string();
let creds = auth.get("creds").unwrap_or(&"".to_string()).to_string();
@@ -94,8 +98,11 @@ fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
for (hostname, host_config) in upstreams {
let path_map = DashMap::new();
let header_list = DashMap::new();
for (path, path_config) in &host_config.paths {
if let Some(rate) = &path_config.rate_limit {
info!("Applied Rate Limit for {} : {} request per second", hostname, rate);
}
let mut server_list = Vec::new();
let mut hl = Vec::new();
@@ -109,6 +116,14 @@ fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
header_list.insert(path.clone(), hl);
for server in &path_config.servers {
// let mut rate: Option<isize> = None;
// let size: isize = path_config.servers.len() as isize;
// if let Some(limit) = &path_config.rate_limit {
// if size > 0 {
// rate = Some(limit / size);
// }
// }
if let Some((ip, port_str)) = server.split_once(':') {
if let Ok(port) = port_str.parse::<u16>() {
server_list.push(InnerMap {
@@ -117,6 +132,8 @@ fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
is_ssl: true,
is_http2: false,
to_https: path_config.to_https.unwrap_or(false),
// rate_limit: rate,
rate_limit: path_config.rate_limit,
});
}
}

View File

@@ -5,6 +5,23 @@ use std::sync::atomic::AtomicUsize;
// pub type InnerMap = BackendConfig;
pub type UpstreamsDashMap = DashMap<String, DashMap<String, (Vec<InnerMap>, AtomicUsize)>>;
// #[derive(Debug, Default)]
// pub struct UpstreamsMap {
// pub upstreams: DashMap<String, DashMap<String, (Vec<InnerMap>, AtomicUsize)>>,
// pub ratelimit: DashMap<String, Option<isize>>,
// }
// impl UpstreamsMap {
// pub fn new() -> Self {
// Self {
// upstreams: Default::default(),
// ratelimit: Default::default(),
// }
// }
// }
//
// pub type XUpstreamsDashMap = DashMap<String, UpstreamsMap>;
pub type UpstreamsIdMap = DashMap<String, InnerMap>;
pub type Headers = DashMap<String, DashMap<String, Vec<(String, String)>>>;
@@ -97,6 +114,7 @@ pub struct InnerMap {
pub is_ssl: bool,
pub is_http2: bool,
pub to_https: bool,
pub rate_limit: Option<isize>,
}
impl InnerMap {
@@ -107,6 +125,7 @@ impl InnerMap {
is_ssl: Default::default(),
is_http2: Default::default(),
to_https: Default::default(),
rate_limit: Default::default(),
}
}
}

View File

@@ -154,6 +154,7 @@ pub fn clone_idmap_into(original: &UpstreamsDashMap, cloned: &UpstreamsIdMap) {
is_ssl: false,
is_http2: false,
to_https: false,
rate_limit: None,
};
cloned.insert(id, to_add);
cloned.insert(hh, x.to_owned());