diff --git a/.gitignore b/.gitignore index d6fdf70..8e535fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /target /Cargo.lock /.env -/postgresdata \ No newline at end of file +/postgresdata +/.DS_Store \ No newline at end of file diff --git a/src/handlers.rs b/src/handlers.rs index e6128c7..3dc8d8c 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -8,9 +8,19 @@ use axum::{ use rand::{distr::Alphanumeric, Rng}; use serde_json::json; use sqlx::PgPool; -use std::net::SocketAddr; +use std::net::{IpAddr, SocketAddr}; use tracing::{error, info, warn}; +fn get_real_ip(addr: &SocketAddr, headers: &HeaderMap) -> IpAddr { + let forwarded_for = headers + .get("x-forwarded-for") + .and_then(|value| value.to_str().ok()) + .and_then(|s| s.split(',').next()) + .and_then(|s| s.trim().parse::().ok()); + + forwarded_for.unwrap_or_else(|| addr.ip()) +} + pub async fn auth_middleware( State(state): State, request: Request, @@ -242,10 +252,11 @@ pub async fn redirect_handler( ConnectInfo(addr): ConnectInfo, headers: HeaderMap, ) -> impl IntoResponse { + let client_ip = get_real_ip(&addr, &headers); + info!( "Redirect request for code: '{}' from IP: {}", - short_code, - addr.ip() + short_code, client_ip ); let find_link_result = sqlx::query_as::<_, Link>("SELECT * FROM links WHERE short_code = $1") .bind(&short_code) @@ -264,7 +275,8 @@ pub async fn redirect_handler( .to_string(); let db_pool = state.db_pool.clone(); let link_id = link.id; - let ip_address = addr.ip().to_string(); + let ip_address = client_ip.to_string(); + tokio::spawn(async move { let log_result = sqlx::query( "INSERT INTO redirect_logs (link_id, ip_address, user_agent) VALUES ($1, $2::inet, $3)",