mirror of
https://github.com/icewind1991/warp-real-ip.git
synced 2026-06-03 18:54:06 +02:00
Merge pull request #1 from moriyoshi/allowing-ipnetwork-instead-of-ipaddr
Allow specifying IP networks for permitted proxies in place of IP addresses.
This commit is contained in:
commit
69df28d0ad
3 changed files with 60 additions and 3 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -378,6 +378,15 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnetwork"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
|
@ -1088,6 +1097,7 @@ dependencies = [
|
||||||
name = "warp-real-ip"
|
name = "warp-real-ip"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ipnetwork",
|
||||||
"rfc7239",
|
"rfc7239",
|
||||||
"tokio",
|
"tokio",
|
||||||
"warp",
|
"warp",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ documentation = "https://docs.rs/warp-real-ip"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
warp = { version = "0.3" }
|
warp = { version = "0.3" }
|
||||||
rfc7239 = "0.1"
|
rfc7239 = "0.1"
|
||||||
|
ipnetwork = "~0.18"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.0", features = ["macros"] }
|
tokio = { version = "1.0", features = ["macros"] }
|
||||||
50
src/lib.rs
50
src/lib.rs
|
|
@ -1,12 +1,57 @@
|
||||||
|
use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
|
||||||
use rfc7239::{parse, Forwarded, NodeIdentifier, NodeName};
|
use rfc7239::{parse, Forwarded, NodeIdentifier, NodeName};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::iter::once;
|
use std::iter::{once, FromIterator, IntoIterator};
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use warp::filters::addr::remote;
|
use warp::filters::addr::remote;
|
||||||
use warp::Filter;
|
use warp::Filter;
|
||||||
|
|
||||||
|
/// Represents a set of IP networks.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct IpNetworks {
|
||||||
|
networks: Vec<IpNetwork>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IpNetworks {
|
||||||
|
/// Checks if addr is part of any IP networks included.
|
||||||
|
pub fn contains(&self, addr: &IpAddr) -> bool {
|
||||||
|
self.networks.iter().any(|&network| network.contains(*addr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Vec<IpAddr>> for IpNetworks {
|
||||||
|
fn from(addrs: Vec<IpAddr>) -> Self {
|
||||||
|
Self::from_iter(addrs.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Vec<IpAddr>> for IpNetworks {
|
||||||
|
fn from(addrs: &Vec<IpAddr>) -> Self {
|
||||||
|
Self::from_iter(addrs.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromIterator<&'a IpAddr> for IpNetworks {
|
||||||
|
fn from_iter<T: IntoIterator<Item = &'a IpAddr>>(addrs: T) -> Self {
|
||||||
|
Self::from_iter(addrs.into_iter().map(|&addr| -> IpNetwork {
|
||||||
|
match addr {
|
||||||
|
IpAddr::V4(addr) => Ipv4Network::from(addr).into(),
|
||||||
|
IpAddr::V6(addr) => Ipv6Network::from(addr).into(),
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<IpNetwork> for IpNetworks {
|
||||||
|
fn from_iter<T: IntoIterator<Item = IpNetwork>>(addrs: T) -> Self {
|
||||||
|
IpNetworks {
|
||||||
|
networks: Vec::<IpNetwork>::from_iter(addrs),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a `Filter` that provides the "real ip" of the connected client.
|
/// Creates a `Filter` that provides the "real ip" of the connected client.
|
||||||
///
|
///
|
||||||
/// This uses the "x-forwarded-for" or "x-real-ip" headers set by reverse proxies.
|
/// This uses the "x-forwarded-for" or "x-real-ip" headers set by reverse proxies.
|
||||||
|
|
@ -28,8 +73,9 @@ use warp::Filter;
|
||||||
/// .map(|addr: Option<IpAddr>| format!("Hello {}", addr.unwrap()));
|
/// .map(|addr: Option<IpAddr>| format!("Hello {}", addr.unwrap()));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn real_ip(
|
pub fn real_ip(
|
||||||
trusted_proxies: Vec<IpAddr>,
|
trusted_proxies: impl Into<IpNetworks>,
|
||||||
) -> impl Filter<Extract = (Option<IpAddr>,), Error = Infallible> + Clone {
|
) -> impl Filter<Extract = (Option<IpAddr>,), Error = Infallible> + Clone {
|
||||||
|
let trusted_proxies = trusted_proxies.into();
|
||||||
remote().and(get_forwarded_for()).map(
|
remote().and(get_forwarded_for()).map(
|
||||||
move |addr: Option<SocketAddr>, forwarded_for: Vec<IpAddr>| {
|
move |addr: Option<SocketAddr>, forwarded_for: Vec<IpAddr>| {
|
||||||
addr.map(|addr| {
|
addr.map(|addr| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue