diff --git a/src/info.rs b/src/info.rs index 4d3ee3d3f..5b506d85a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,8 +12,8 @@ const X_FORWARDED_PROTO: &[u8] = b"x-forwarded-proto"; pub struct ConnectionInfo { scheme: String, host: String, - remote: Option, - peer: Option, + realip_remote_addr: Option, + remote_addr: Option, } impl ConnectionInfo { @@ -29,7 +29,7 @@ impl ConnectionInfo { fn new(req: &RequestHead, cfg: &AppConfig) -> ConnectionInfo { let mut host = None; let mut scheme = None; - let mut remote = None; + let mut realip_remote_addr = None; // load forwarded header for hdr in req.headers.get_all(&header::FORWARDED) { @@ -41,8 +41,8 @@ impl ConnectionInfo { if let Some(val) = items.next() { match &name.to_lowercase() as &str { "for" => { - if remote.is_none() { - remote = Some(val.trim()); + if realip_remote_addr.is_none() { + realip_remote_addr = Some(val.trim()); } } "proto" => { @@ -105,26 +105,25 @@ impl ConnectionInfo { } } - // get peeraddr from socketaddr - let peer = req.peer_addr.map(|addr| format!("{}", addr)); + // get remote_addraddr from socketaddr + let remote_addr = req.peer_addr.map(|addr| format!("{}", addr)); - // remote addr - if remote.is_none() { + if realip_remote_addr.is_none() { if let Some(h) = req .headers .get(&HeaderName::from_lowercase(X_FORWARDED_FOR).unwrap()) { if let Ok(h) = h.to_str() { - remote = h.split(',').next().map(|v| v.trim()); + realip_remote_addr = h.split(',').next().map(|v| v.trim()); } } } ConnectionInfo { - peer, + remote_addr, scheme: scheme.unwrap_or("http").to_owned(), host: host.unwrap_or("localhost").to_owned(), - remote: remote.map(|s| s.to_owned()), + realip_remote_addr: realip_remote_addr.map(|s| s.to_owned()), } } @@ -153,23 +152,23 @@ impl ConnectionInfo { &self.host } - /// Peer address of the request. + /// remote_addr address of the request. /// - /// Get peer address from socket address - pub fn peer(&self) -> Option<&str> { - if let Some(ref peer) = self.peer { - Some(peer) + /// Get remote_addr address from socket address + pub fn remote_addr(&self) -> Option<&str> { + if let Some(ref remote_addr) = self.remote_addr { + Some(remote_addr) } else { None } } - /// Remote socket addr of client initiated HTTP request. + /// Real ip remote addr of client initiated HTTP request. /// /// The addr is resolved through the following headers, in this order: /// /// - Forwarded /// - X-Forwarded-For - /// - peer name of opened socket + /// - remote_addr name of opened socket /// /// # Security /// Do not use this function for security purposes, unless you can ensure the Forwarded and @@ -177,11 +176,11 @@ impl ConnectionInfo { /// address explicitly, use /// [`HttpRequest::peer_addr()`](../web/struct.HttpRequest.html#method.peer_addr) instead. #[inline] - pub fn remote(&self) -> Option<&str> { - if let Some(ref r) = self.remote { + pub fn realip_remote_addr(&self) -> Option<&str> { + if let Some(ref r) = self.realip_remote_addr { Some(r) - } else if let Some(ref peer) = self.peer { - Some(peer) + } else if let Some(ref remote_addr) = self.remote_addr { + Some(remote_addr) } else { None } @@ -210,7 +209,7 @@ mod tests { let info = req.connection_info(); assert_eq!(info.scheme(), "https"); assert_eq!(info.host(), "rust-lang.org"); - assert_eq!(info.remote(), Some("192.0.2.60")); + assert_eq!(info.realip_remote_addr(), Some("192.0.2.60")); let req = TestRequest::default() .header(header::HOST, "rust-lang.org") @@ -219,20 +218,20 @@ mod tests { let info = req.connection_info(); assert_eq!(info.scheme(), "http"); assert_eq!(info.host(), "rust-lang.org"); - assert_eq!(info.remote(), None); + assert_eq!(info.realip_remote_addr(), None); let req = TestRequest::default() .header(X_FORWARDED_FOR, "192.0.2.60") .to_http_request(); let info = req.connection_info(); - assert_eq!(info.remote(), Some("192.0.2.60")); + assert_eq!(info.realip_remote_addr(), Some("192.0.2.60")); let req = TestRequest::default() .header(X_FORWARDED_HOST, "192.0.2.60") .to_http_request(); let info = req.connection_info(); assert_eq!(info.host(), "192.0.2.60"); - assert_eq!(info.remote(), None); + assert_eq!(info.realip_remote_addr(), None); let req = TestRequest::default() .header(X_FORWARDED_PROTO, "https") diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 4bd02b03e..d4853a5bf 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -55,7 +55,7 @@ use crate::HttpResponse; /// /// `%%` The percent sign /// -/// `%a` Client IP-address +/// `%a` Remote IP-address (IP-address of proxy if using reverse proxy) /// /// `%t` Time when the request was started to process (in rfc3339 format) /// @@ -72,7 +72,7 @@ use crate::HttpResponse; /// /// `%U` Request URL /// -/// `%{r}a` Remote IP-address (IP-address of proxy if using reverse proxy) **\*** +/// `%{r}a` Real IP remote address **\*** /// /// `%{FOO}i` request.headers['FOO'] /// @@ -80,9 +80,12 @@ use crate::HttpResponse; /// /// `%{FOO}e` os.environ['FOO'] /// -/// > **\* warning** It is critical to only use this value from intermediate -/// > hosts(proxies, etc) which are trusted by this server, since it is trivial -/// > for the remote client to simulate another client. +/// ### **\* security warning** +/// It is calculated using +/// [`ConnectionInfo::realip_remote_addr()`](../dev/struct.ConnectionInfo.html#method.realip_remote_addr) +/// +/// If you use this value ensure that all requests come from trusted hosts, since it is trivial +/// for the remote client to simulate been another client. /// pub struct Logger(Rc); @@ -322,7 +325,7 @@ impl Format { if let Some(key) = cap.get(2) { results.push(match cap.get(3).unwrap().as_str() { "a" => if key.as_str() == "r" { - FormatText::RemoteAddr + FormatText::RealIPRemoteAddr } else { unreachable!() }, @@ -339,7 +342,7 @@ impl Format { let m = cap.get(1).unwrap(); results.push(match m.as_str() { "%" => FormatText::Percent, - "a" => FormatText::ClientIP, + "a" => FormatText::RemoteAddr, "t" => FormatText::RequestTime, "r" => FormatText::RequestLine, "s" => FormatText::ResponseStatus, @@ -372,8 +375,8 @@ pub enum FormatText { ResponseSize, Time, TimeMillis, - ClientIP, RemoteAddr, + RealIPRemoteAddr, UrlPath, RequestHeader(HeaderName), ResponseHeader(HeaderName), @@ -469,16 +472,16 @@ impl FormatText { }; *self = FormatText::Str(s.to_string()); } - FormatText::ClientIP => { - let s = if let Some(ref peer) = req.connection_info().peer() { + FormatText::RemoteAddr => { + let s = if let Some(ref peer) = req.connection_info().remote_addr() { FormatText::Str(peer.to_string()) } else { FormatText::Str("-".to_string()) }; *self = s; } - FormatText::RemoteAddr => { - let s = if let Some(remote) = req.connection_info().remote() { + FormatText::RealIPRemoteAddr => { + let s = if let Some(remote) = req.connection_info().realip_remote_addr() { FormatText::Str(remote.to_string()) } else { FormatText::Str("-".to_string())