This commit is contained in:
Mateusz Gruszczyński committed 2026-10-19 14:05:13 +02:00
1 parent 28e39f7ce4
commit b57beb83c7
34 files changed
+1037 -314

No files matched your search

-4
View File
@@ -39,10 +39,6 @@ impl PeerFormatting {
untrusted_headers: std::sync::Mutex::new(None),
}
}
fn peer_header(&self) -> &HeaderValue {
&self.peer_header
}
fn cached_untrusted(&self, authority: &HeaderValue, tls: bool) -> Option<HeaderMap> {
self.untrusted_headers
.lock()
+128 -54
View File
@@ -19,7 +19,11 @@ mod tests {
for (peer, local, networks) in [
("192.0.2.51:32000", "127.0.0.1:8080", Vec::<String>::new()),
("[2001:db8::8]:32100", "[2001:db8::1]:8443", Vec::new()),
("10.2.3.4:4123", "10.0.0.1:8443", vec!["10.0.0.0/8".to_owned()]),
(
"10.2.3.4:4123",
"10.0.0.1:8443",
vec!["10.0.0.0/8".to_owned()],
),
] {
let peer: SocketAddr = peer.parse().unwrap();
let local: SocketAddr = local.parse().unwrap();
@@ -27,25 +31,38 @@ mod tests {
let compiled = Settings {
trusted_proxies: networks,
trust_forwarded_proto: true,
}.compile().unwrap();
}
.compile()
.unwrap();
let mut incoming = HeaderMap::new();
incoming.insert("x-forwarded-for", "198.51.100.8, 10.3.2.1".parse().unwrap());
incoming.insert("x-forwarded-proto", "https".parse().unwrap());
let authority = HeaderValue::from_static("app.example:8443");
let uri: Uri = "/some%20file?q=4".parse().unwrap();
let plain = compiled.context_with_original_url(
&incoming, peer, local, true, &authority, &uri, false
).unwrap();
let cached = compiled.context_with_peer(
&incoming, peer, local, true, &authority, &uri, false,
Some(&formatter), true,
).unwrap();
let plain = compiled
.context_with_original_url(&incoming, peer, local, true, &authority, &uri, false)
.unwrap();
let cached = compiled
.context_with_peer(
&incoming,
peer,
local,
true,
&authority,
&uri,
false,
Some(&formatter),
true,
)
.unwrap();
assert_eq!(cached.client_ip, plain.client_ip);
assert_eq!(cached.scheme, plain.scheme);
assert_eq!(cached.original_url, plain.original_url);
assert_eq!(cached.values, plain.values);
assert_eq!(formatter.peer_header().to_str().unwrap(),
crate::vhost::canonical_ip(peer.ip()).to_string());
assert_eq!(
formatter.peer_header.to_str().unwrap(),
crate::vhost::canonical_ip(peer.ip()).to_string()
);
for include_ip in [false, true] {
let mut a = incoming.clone();
let mut b = incoming.clone();
@@ -87,13 +104,30 @@ mod tests {
let host = HeaderValue::from_str(host).unwrap();
let uri: Uri = path.parse().unwrap();
for original_url in [false, true] {
let direct = compiled.context_with_original_url(
&incoming, peer, local, tls, &host, &uri, original_url,
).unwrap();
let cached = compiled.context_with_peer(
&incoming, peer, local, tls, &host, &uri, original_url,
Some(&formatter), false,
).unwrap();
let direct = compiled
.context_with_original_url(
&incoming,
peer,
local,
tls,
&host,
&uri,
original_url,
)
.unwrap();
let cached = compiled
.context_with_peer(
&incoming,
peer,
local,
tls,
&host,
&uri,
original_url,
Some(&formatter),
false,
)
.unwrap();
assert_eq!(cached.client_ip, direct.client_ip);
assert_eq!(cached.scheme, direct.scheme);
assert_eq!(cached.original_url, direct.original_url);
@@ -111,19 +145,30 @@ mod tests {
let trusted = Settings {
trusted_proxies: vec!["192.0.2.0/24".to_owned()],
trust_forwarded_proto: true,
}.compile().unwrap();
}
.compile()
.unwrap();
let mut forwarded = HeaderMap::new();
forwarded.insert("x-forwarded-for", "198.51.100.9".parse().unwrap());
forwarded.insert("x-forwarded-proto", "https".parse().unwrap());
let host = HeaderValue::from_static("app.example");
let uri: Uri = "/trusted".parse().unwrap();
let direct = trusted.context_with_original_url(
&forwarded, peer, local, false, &host, &uri, false,
).unwrap();
let cached = trusted.context_with_peer(
&forwarded, peer, local, false, &host, &uri, false,
Some(&formatter), false,
).unwrap();
let direct = trusted
.context_with_original_url(&forwarded, peer, local, false, &host, &uri, false)
.unwrap();
let cached = trusted
.context_with_peer(
&forwarded,
peer,
local,
false,
&host,
&uri,
false,
Some(&formatter),
false,
)
.unwrap();
assert_eq!(cached.client_ip, "198.51.100.9".parse::<IpAddr>().unwrap());
assert_eq!(cached.scheme, "https");
assert_eq!(cached.values, direct.values);
@@ -136,12 +181,19 @@ mod tests {
let compiled = Settings::default().compile().unwrap();
let peer: SocketAddr = "192.0.2.9:4000".parse().unwrap();
let local: SocketAddr = "127.0.0.1:8080".parse().unwrap();
let value = compiled.context_with_peer(
&HeaderMap::new(), peer, local, false,
&HeaderValue::from_static("app.example"),
&"/".parse().unwrap(), false,
Some(&PeerFormatting::new(peer, local)), false,
).unwrap();
let value = compiled
.context_with_peer(
&HeaderMap::new(),
peer,
local,
false,
&HeaderValue::from_static("app.example"),
&"/".parse().unwrap(),
false,
Some(&PeerFormatting::new(peer, local)),
false,
)
.unwrap();
let mut headers = HeaderMap::new();
for (name, val) in [
("forwarded", "for=203.0.113.1"),
@@ -173,10 +225,19 @@ mod tests {
let local: SocketAddr = "127.0.0.1:8080".parse().unwrap();
let authority = HeaderValue::from_static("app.example");
let uri: Uri = "/safe".parse().unwrap();
let value = compiled.context_with_peer(
&HeaderMap::new(), actual, local, false,
&authority, &uri, false, Some(&different), false,
).unwrap();
let value = compiled
.context_with_peer(
&HeaderMap::new(),
actual,
local,
false,
&authority,
&uri,
false,
Some(&different),
false,
)
.unwrap();
assert_eq!(value.client_ip, actual.ip());
assert_eq!(value.values["x-forwarded-for"], "198.51.100.6");
}
@@ -373,23 +434,29 @@ mod tests {
let source = Settings {
trusted_proxies: vec!["10.0.0.0/8".into()],
trust_forwarded_proto: true,
}.compile().unwrap();
}
.compile()
.unwrap();
let mut supplied = HeaderMap::new();
supplied.insert("forwarded", "for=203.0.113.8".parse().unwrap());
supplied.insert("x-forwarded-proto", "http".parse().unwrap());
let context = source.context(
&supplied,
"[2001:db8::5]:5050".parse().unwrap(),
"[2001:db8::10]:8080".parse().unwrap(),
true,
&"app.example:443".parse().unwrap(),
&"/s?q=1".parse().unwrap(),
).unwrap();
let context = source
.context(
&supplied,
"[2001:db8::5]:5050".parse().unwrap(),
"[2001:db8::10]:8080".parse().unwrap(),
true,
&"app.example:443".parse().unwrap(),
&"/s?q=1".parse().unwrap(),
)
.unwrap();
assert_eq!(context.client_ip, "2001:db8::5".parse::<IpAddr>().unwrap());
assert_eq!(context.scheme, "https");
assert_eq!(context.original_url, "https://app.example:443/s?q=1");
assert_eq!(context.values["forwarded"],
"for=\"[2001:db8::5]\";by=\"[2001:db8::10]\";proto=https;host=\"app.example:443\"");
assert_eq!(
context.values["forwarded"],
"for=\"[2001:db8::5]\";by=\"[2001:db8::10]\";proto=https;host=\"app.example:443\""
);
assert_eq!(context.values["x-forwarded-for"], "2001:db8::5");
assert_eq!(context.values["x-real-ip"], "2001:db8::5");
assert_eq!(context.values["x-forwarded-proto"], "https");
@@ -404,9 +471,15 @@ mod tests {
(false, "[2001:db8::a]:5010", "[2001:db8::b]:8080"),
] {
let settings = Settings {
trusted_proxies: if trusted { vec!["10.0.0.0/8".into()] } else { vec![] },
trusted_proxies: if trusted {
vec!["10.0.0.0/8".into()]
} else {
vec![]
},
trust_forwarded_proto: true,
}.compile().unwrap();
}
.compile()
.unwrap();
let mut incoming = HeaderMap::new();
incoming.insert("x-forwarded-for", "192.0.2.15".parse().unwrap());
incoming.insert("x-forwarded-proto", "http".parse().unwrap());
@@ -414,10 +487,12 @@ mod tests {
let local: SocketAddr = local.parse().unwrap();
let host: HeaderValue = "app.example:8443".parse().unwrap();
let uri: Uri = "/route?q=hello".parse().unwrap();
let full = settings.context(&incoming, peer, local, true, &host, &uri).unwrap();
let compact = settings.context_with_original_url(
&incoming, peer, local, true, &host, &uri, false,
).unwrap();
let full = settings
.context(&incoming, peer, local, true, &host, &uri)
.unwrap();
let compact = settings
.context_with_original_url(&incoming, peer, local, true, &host, &uri, false)
.unwrap();
assert!(!full.original_url.is_empty());
assert!(compact.original_url.is_empty());
assert_eq!(full.client_ip, compact.client_ip);
@@ -430,5 +505,4 @@ mod tests {
assert_eq!(full_headers, compact_headers);
}
}
}