diff --git a/Cargo.toml b/Cargo.toml index 7772f8a..2e6078f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bal_server" -version = "0.3.1" +version = "0.3.2" edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/bin/bal-server.rs b/src/bin/bal-server.rs index 8c2304d..6860336 100644 --- a/src/bin/bal-server.rs +++ b/src/bin/bal-server.rs @@ -217,6 +217,38 @@ async fn echo_version() -> impl Responder { HttpResponse::Ok().body(VERSION) } +fn is_valid_ip(ip: &str) -> bool { + ip.parse::().is_ok() +} + +fn extract_client_ip(req: &actix_web::HttpRequest) -> String { + if let Some(val) = req.headers().get("X-Real-IP") + && let Ok(s) = val.to_str() + { + let ip = s.split(',').next().unwrap_or(s).trim(); + if is_valid_ip(ip) { + debug!("client IP from X-Real-IP: {}", ip); + return ip.to_string(); + } + } + if let Some(val) = req.headers().get("X-Forwarded-For") + && let Ok(s) = val.to_str() + { + let ip = s.split(',').next().unwrap_or(s).trim(); + if is_valid_ip(ip) { + debug!("client IP from X-Forwarded-For: {}", ip); + return ip.to_string(); + } + } + let fallback = req + .connection_info() + .peer_addr() + .unwrap_or("unknown") + .to_string(); + debug!("client IP from peer_addr fallback: {}", fallback); + fallback +} + async fn echo_info( path: web::Path, data: web::Data, @@ -232,18 +264,7 @@ async fn echo_info( debug!("network disabled {}", param); return HttpResponse::BadRequest().body("error"); } - let remote_addr = req - .headers() - .get("X-Real-IP") - .and_then(|value| value.to_str().ok()) - .and_then(|xff| xff.split(',').next()) - .map(|ip| ip.trim().to_string()) - .unwrap_or_else(|| { - req.connection_info() - .peer_addr() - .unwrap_or("unknown") - .to_string() - }); + let remote_addr = extract_client_ip(&req); let address = match netconfig.xpub { false => { let address = netconfig.address.to_string();