websocket_relay/
security.rs1use anyhow::{Result, anyhow};
2use ipnet::IpNet;
3use std::net::IpAddr;
4
5#[must_use]
8pub fn parse_original_client_ip(xff_header: &str) -> Option<String> {
9 xff_header
10 .split(',')
11 .next()
12 .map(|ip| ip.trim().to_string())
13 .filter(|ip| !ip.is_empty())
14}
15
16pub fn is_proxy_ip_allowed(proxy_ip: IpAddr, allowed_ips: Option<&Vec<String>>) -> Result<bool> {
19 let Some(allowed_list) = allowed_ips else {
20 return Ok(true); };
22
23 for allowed_entry in allowed_list {
24 if let Ok(allowed_ip) = allowed_entry.parse::<IpAddr>() {
26 if proxy_ip == allowed_ip {
27 return Ok(true);
28 }
29 }
30 else if let Ok(allowed_net) = allowed_entry.parse::<IpNet>() {
32 if allowed_net.contains(&proxy_ip) {
33 return Ok(true);
34 }
35 } else {
36 return Err(anyhow!(
37 "Invalid IP address or CIDR in allowed_proxy_ips: {}",
38 allowed_entry
39 ));
40 }
41 }
42
43 Ok(false)
44}