switch to taking a HeaderMap instead of Request

This commit is contained in:
Robin Appelman 2024-11-29 19:08:10 +01:00
commit d2cd67f9e5
2 changed files with 8 additions and 9 deletions

View file

@ -20,6 +20,6 @@ let request = Request::builder().header("x-forwarded-for", "192.0.2.1").body(())
let trusted_proxies = [ let trusted_proxies = [
IpAddr::from([10, 0, 0, 1]).into(), IpAddr::from([10, 0, 0, 1]).into(),
]; ];
let client_ip = real_ip(&request, incoming_ip, &trusted_proxies); let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip); assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip);
``` ```

View file

@ -31,7 +31,7 @@
//! IpAddr::from([10, 0, 0, 1]).into(), //! IpAddr::from([10, 0, 0, 1]).into(),
//! IpNetwork::new(IpAddr::from([10, 10, 10, 0]), 24).unwrap(), // 10.10.10.0/24 //! IpNetwork::new(IpAddr::from([10, 10, 10, 0]), 24).unwrap(), // 10.10.10.0/24
//! ]; //! ];
//! let client_ip = real_ip(&request, incoming_ip, &trusted_proxies); //! let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
//! assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip); //! assert_eq!(Some(IpAddr::from([192, 0, 2, 1])), client_ip);
//! ``` //! ```
//! //!
@ -51,12 +51,12 @@
//! IpAddr::from([10, 0, 0, 1]).into(), //! IpAddr::from([10, 0, 0, 1]).into(),
//! IpNetwork::new(IpAddr::from([10, 10, 10, 0]), 24).unwrap(), //! IpNetwork::new(IpAddr::from([10, 10, 10, 0]), 24).unwrap(),
//! ]; //! ];
//! let client_ip = real_ip(&request, incoming_ip, &trusted_proxies); //! let client_ip = real_ip(request.headers(), incoming_ip, &trusted_proxies);
//! assert_eq!(Some(IpAddr::from([203, 0, 113, 10])), client_ip); //! assert_eq!(Some(IpAddr::from([203, 0, 113, 10])), client_ip);
//! ``` //! ```
use comma_separated::CommaSeparatedIterator; use comma_separated::CommaSeparatedIterator;
use http::Request; use http::HeaderMap;
use ipnetwork::IpNetwork; use ipnetwork::IpNetwork;
use itertools::Either; use itertools::Either;
use rfc7239::{parse, Forwarded, NodeIdentifier, NodeName}; use rfc7239::{parse, Forwarded, NodeIdentifier, NodeName};
@ -68,12 +68,12 @@ use std::str::FromStr;
/// Get the "real-ip" of an incoming request. /// Get the "real-ip" of an incoming request.
/// ///
/// See the [top level documentation](crate) for more usage details. /// See the [top level documentation](crate) for more usage details.
pub fn real_ip<B>( pub fn real_ip(
request: &Request<B>, headers: &HeaderMap,
remote: IpAddr, remote: IpAddr,
trusted_proxies: &[IpNetwork], trusted_proxies: &[IpNetwork],
) -> Option<IpAddr> { ) -> Option<IpAddr> {
let mut hops = get_forwarded_for(request).chain(once(remote)); let mut hops = get_forwarded_for(headers).chain(once(remote));
let first = hops.next(); let first = hops.next();
let hops = first.iter().copied().chain(hops); let hops = first.iter().copied().chain(hops);
@ -93,8 +93,7 @@ pub fn real_ip<B>(
/// Extracts the ip addresses from the "forwarded for" chain from a request /// Extracts the ip addresses from the "forwarded for" chain from a request
/// ///
/// Note that this doesn't perform any validation against clients forging the headers /// Note that this doesn't perform any validation against clients forging the headers
pub fn get_forwarded_for<B>(request: &Request<B>) -> impl DoubleEndedIterator<Item = IpAddr> + '_ { pub fn get_forwarded_for(headers: &HeaderMap) -> impl DoubleEndedIterator<Item = IpAddr> + '_ {
let headers = request.headers();
if let Some(header) = headers.get("forwarded") { if let Some(header) = headers.get("forwarded") {
let header = header.to_str().unwrap_or_default(); let header = header.to_str().unwrap_or_default();
let hops = parse(header).filter_map(|forward| match forward { let hops = parse(header).filter_map(|forward| match forward {