diff --git a/Cargo.lock b/Cargo.lock index 8b03ffc..e6d6725 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,6 +154,17 @@ dependencies = [ "syn 2.0.41", ] +[[package]] +name = "actix-remote-ip" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7629b357d4705cf3f1e31f989f48ecd56027112f7d52dcf06dd96ee197065f8e" +dependencies = [ + "actix-web", + "futures-util", + "log", +] + [[package]] name = "actix-router" version = "0.5.1" @@ -900,6 +911,7 @@ dependencies = [ "actix-files", "actix-http", "actix-multipart", + "actix-remote-ip", "actix-web", "actix-web-actors", "async-recursion", diff --git a/Cargo.toml b/Cargo.toml index 1851b22..5d6ac3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ actix-web = "4.4.0" actix-files = "0.6.2" actix-multipart = "0.6.1" actix-web-actors = "4.2.0" +actix-remote-ip = "0.1.0" actix-http = "3.3.1" serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.108" diff --git a/src/data/http_request_handler.rs b/src/data/http_request_handler.rs index 95b9c1a..02818bf 100644 --- a/src/data/http_request_handler.rs +++ b/src/data/http_request_handler.rs @@ -1,4 +1,5 @@ use actix_http::header::{HeaderName, HeaderValue}; +use actix_remote_ip::RemoteIP; use std::collections::HashMap; use std::str::FromStr; @@ -15,7 +16,6 @@ use crate::data::error::{Res, ResultBoxError}; use crate::data::user_token::UserAccessToken; use crate::helpers::{account_helper, admin_access_token_helper, api_helper}; use crate::routes::RequestResult; -use crate::utils::network_utils::match_ip; /// Http request handler /// @@ -29,11 +29,16 @@ pub struct HttpRequestHandler { client: Option, curr_user_token: Option, curr_admin_token: Option, + remote_ip: RemoteIP, } impl HttpRequestHandler { /// Construct a new request handler - pub fn new(req: HttpRequest, body: HashMap) -> HttpRequestHandler { + pub fn new( + req: HttpRequest, + body: HashMap, + remote_ip: RemoteIP, + ) -> HttpRequestHandler { HttpRequestHandler { request: req, body, @@ -42,6 +47,7 @@ impl HttpRequestHandler { client: None, curr_user_token: None, curr_admin_token: None, + remote_ip, } } @@ -184,28 +190,7 @@ impl BaseRequestHandler for HttpRequestHandler { /// Get the remote IP address fn remote_ip(&self) -> String { - let mut ip = self.request.peer_addr().unwrap().ip().to_string(); - - // We check if the request comes from a trusted reverse proxy - if let Some(proxy) = conf().proxy.as_ref() { - if match_ip(proxy, &ip) { - if let Some(header) = self.request.headers().get("X-Forwarded-For") { - let header: Vec = header - .to_str() - .unwrap() - .to_string() - .split(",") - .map(|f| f.to_string()) - .collect(); - - if header.len() > 0 { - ip = header[0].to_string(); - } - } - } - } - - ip + self.remote_ip.0.to_string() } fn user_access_token(&self) -> Option<&UserAccessToken> { diff --git a/src/server.rs b/src/server.rs index f8e7bc7..1b5b27c 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,3 +1,4 @@ +use actix_remote_ip::{RemoteIP, RemoteIPConfig}; use std::collections::HashMap; use std::pin::Pin; @@ -252,7 +253,7 @@ async fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> Re } /// Process an incoming request -async fn process_request(custom_req: CustomRequest) -> HttpResponse { +async fn process_request(custom_req: CustomRequest, remote_ip: RemoteIP) -> HttpResponse { let req = &custom_req.req; let (route, _) = find_route(&req.uri().to_string(), None).await; @@ -274,7 +275,7 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse { requests_limit_helper::clean_cache().unwrap(); // Execute the request - let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body); + let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body, remote_ip); match process_simple_route(&route, &mut request).await { // Set default error response if required @@ -357,6 +358,8 @@ pub fn start_server(conf: &Config) -> std::io::Result<()> { let serve_storage_file = conf.serve_storage_file; + let proxy = conf.proxy.clone(); + let server = HttpServer::new(move || { let mut app = App::new(); @@ -367,8 +370,13 @@ pub fn start_server(conf: &Config) -> std::io::Result<()> { )); } - // User WebSocket route - app.service(actix_web::web::resource("/ws").to(user_ws_controller::ws_route)) + app + // Remote IP configuration + .app_data(web::Data::new(RemoteIPConfig { + proxy: proxy.clone(), + })) + // User WebSocket route + .service(actix_web::web::resource("/ws").to(user_ws_controller::ws_route)) // RTC Relay WebSocket route .service(actix_web::web::resource("/rtc_proxy/ws").to(rtc_relay_controller::open_ws)) // Option