v0.26.1
This commit is contained in:
1 parent
ddc5c6593f
commit
b9d137eee1
63 files changed
+1232
-445
No files matched your search
@@ -238,6 +238,12 @@ pub struct CompiledFrontend {
|
||||
pub pages: crate::pages::VhostPages,
|
||||
pub proxy_timeouts: crate::vhost::ProxyTimeouts,
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ResolvedLogVhost {
|
||||
pub vhost: String,
|
||||
pub matched_by: &'static str,
|
||||
}
|
||||
|
||||
pub struct Snapshot {
|
||||
pub vhost_metrics: std::collections::BTreeMap<String, Arc<crate::metrics::VhostMetrics>>,
|
||||
pub forwarding: crate::forwarding::Compiled,
|
||||
|
||||
@@ -93,6 +93,54 @@ impl Snapshot {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Resolve a persistent protocol-error record to a configured vhost using
|
||||
/// the same exact/wildcard precedence and listener binding rules as normal routing.
|
||||
/// Client-provided Host/SNI values are never used as file names directly.
|
||||
pub fn resolve_logging_vhost(
|
||||
&self,
|
||||
local: SocketAddr,
|
||||
tls: bool,
|
||||
routed_vhost: Option<&str>,
|
||||
authority: Option<&str>,
|
||||
host: Option<&str>,
|
||||
sni: Option<&str>,
|
||||
) -> Option<ResolvedLogVhost> {
|
||||
if let Some(routed) = routed_vhost.filter(|value| !value.is_empty()) {
|
||||
if self.frontends.values().flatten().any(|frontend| {
|
||||
frontend.id == routed
|
||||
&& frontend
|
||||
.bindings
|
||||
.iter()
|
||||
.any(|binding| binding.matches(local, tls))
|
||||
}) {
|
||||
return Some(ResolvedLogVhost {
|
||||
vhost: routed.to_owned(),
|
||||
matched_by: "router",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (candidate, matched_by) in [
|
||||
(authority, "authority"),
|
||||
(host, "host"),
|
||||
(sni, "sni"),
|
||||
] {
|
||||
let Some(candidate) = candidate else {
|
||||
continue;
|
||||
};
|
||||
let Ok(normalized) = request_host(candidate) else {
|
||||
continue;
|
||||
};
|
||||
if let Some(frontend) = self.frontend(&normalized, local, tls) {
|
||||
return Some(ResolvedLogVhost {
|
||||
vhost: frontend.id.clone(),
|
||||
matched_by,
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
/// Select a redirect host/rule using the accepted socket, TLS state and normalized path.
|
||||
/// Exact hostnames win over the longest matching wildcard, matching vhost behavior.
|
||||
pub fn redirect_on(
|
||||
|
||||
@@ -187,6 +187,57 @@ fn wildcard_host_patterns_are_normalized_and_exact_hosts_win() {
|
||||
"wildcard/main"
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn logging_vhost_resolution_reuses_router_host_precedence() {
|
||||
let mut config = demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
config.vhosts[0].id = "wildcard".into();
|
||||
config.vhosts[0].frontend.hosts = vec!["*.example.test".into()];
|
||||
let mut exact = config.vhosts[0].clone();
|
||||
exact.id = "exact".into();
|
||||
exact.frontend.hosts = vec!["api.example.test".into()];
|
||||
config.vhosts.push(exact);
|
||||
let snapshot = compile(config, 1, &policy()).unwrap();
|
||||
let local: SocketAddr = "127.0.0.1:8080".parse().unwrap();
|
||||
|
||||
let routed = snapshot
|
||||
.resolve_logging_vhost(
|
||||
local,
|
||||
false,
|
||||
Some("wildcard"),
|
||||
Some("api.example.test"),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(routed.vhost, "wildcard");
|
||||
assert_eq!(routed.matched_by, "router");
|
||||
|
||||
let exact = snapshot
|
||||
.resolve_logging_vhost(local, false, None, Some("API.EXAMPLE.TEST:8080"), None, None)
|
||||
.unwrap();
|
||||
assert_eq!(exact.vhost, "exact");
|
||||
assert_eq!(exact.matched_by, "authority");
|
||||
|
||||
let wildcard = snapshot
|
||||
.resolve_logging_vhost(local, false, None, None, Some("www.example.test:8080"), None)
|
||||
.unwrap();
|
||||
assert_eq!(wildcard.vhost, "wildcard");
|
||||
assert_eq!(wildcard.matched_by, "host");
|
||||
|
||||
let sni = snapshot
|
||||
.resolve_logging_vhost(local, false, None, None, None, Some("api.example.test"))
|
||||
.unwrap();
|
||||
assert_eq!(sni.vhost, "exact");
|
||||
assert_eq!(sni.matched_by, "sni");
|
||||
|
||||
assert!(snapshot
|
||||
.resolve_logging_vhost(local, false, None, None, None, Some("unknown.test"))
|
||||
.is_none());
|
||||
assert!(snapshot
|
||||
.resolve_logging_vhost(local, false, None, None, None, None)
|
||||
.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reusable_acl_profile_reference_is_compiled_and_unknown_reference_fails() {
|
||||
let mut c = demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
|
||||
Reference in new issue
Block a user