This commit is contained in:
Mateusz Gruszczyński committed 2026-10-08 22:22:46 +02:00
1 parent 76cb4acef0
commit 68678e98be
84 files changed
+1519 -325

No files matched your search

+1
View File
@@ -292,6 +292,7 @@ pub fn compile_with_active(
"HTTP/3 listeners require TLS 1.3 and a TLS 1.3 cipher suite in the global TLS policy"
);
Ok(Snapshot {
web_php_services: web_services,
vhost_metrics,
forwarding,
quic_tls,
+34
View File
@@ -0,0 +1,34 @@
impl Snapshot {
/// Resolve a vhost-local internal named location. Internal locations are
/// deliberately excluded from ordinary URI matching and can only be reached
/// by an explicit internal dispatch such as an error fallback.
pub fn select_internal_on(
&self,
host: &str,
vhost_id: &str,
target: &str,
local: SocketAddr,
tls: bool,
) -> Option<&CompiledRoute> {
for pattern in Self::host_patterns(host) {
let owns_host = self.fallbacks.get(&pattern).is_some_and(|routes| {
routes.iter().any(|route| {
route.frontend.as_ref().is_some_and(|frontend| frontend.id == vhost_id)
&& route.bindings.iter().any(|binding| binding.matches(local, tls))
})
});
if !owns_host {
continue;
}
return self.routes.get(&pattern).and_then(|routes| {
routes.iter().find(|route| {
route.internal
&& route.name == target
&& route.frontend.as_ref().is_some_and(|frontend| frontend.id == vhost_id)
&& route.bindings.iter().any(|binding| binding.matches(local, tls))
})
});
}
None
}
}
+5
View File
@@ -197,13 +197,17 @@ pub struct CompiledRoute {
pub frontend: Option<Arc<CompiledFrontend>>,
pub pool: Option<Arc<crate::balance::Pool>>,
pub cache: Option<bool>,
/// Vhost-local stable location ID (`main` for the main source).
pub name: String,
pub id: String,
pub internal: bool,
pub path_prefix: String,
pub match_type: crate::vhost::PathMatch,
pub path_regex: Option<regex::Regex>,
pub rewrite: crate::vhost::PathRewrite,
pub response: Option<crate::vhost::LocationResponse>,
pub redirect: Option<CompiledLocationRedirect>,
pub error_fallback: Option<crate::vhost::ErrorFallback>,
pub source: CompiledSource,
pub backend: Option<Arc<CompiledBackend>>,
pub acl_profile_id: Option<String>,
@@ -265,6 +269,7 @@ pub struct ResolvedLogVhost {
}
pub struct Snapshot {
pub web_php_services: HashMap<String, Arc<crate::web_server::CompiledService>>,
pub vhost_metrics: std::collections::BTreeMap<String, Arc<crate::metrics::VhostMetrics>>,
pub forwarding: crate::forwarding::Compiled,
pub quic_tls: Option<Arc<quinn::crypto::rustls::QuicServerConfig>>,
+23 -6
View File
@@ -91,8 +91,17 @@ fn compile_routing(
}
claimed.extend(host_bindings.iter().copied());
}
// Backend definitions are irrelevant to a Web Server main source unless
// an enabled Custom Location explicitly uses Reverse Proxy.
let needs_proxy_pool = host.source.is_reverse_proxy()
|| host.routes.iter().any(|route| {
route.enabled
&& route.response.is_none()
&& route.redirect.is_none()
&& route.source.is_reverse_proxy()
});
let mut compiled_members = Vec::new();
for definition in &host.backends {
for definition in host.backends.iter().filter(|_| needs_proxy_pool) {
let mut backend = compile_backend_with_timeout(
&definition.backend(),
&desired_policy,
@@ -240,13 +249,16 @@ fn compile_routing(
frontend: Some(frontend.clone()),
pool: fallback_pool,
cache: None,
name: "main".into(),
id: format!("{}/main", host.id),
internal: false,
path_prefix: "/".into(),
match_type: crate::vhost::PathMatch::Prefix,
path_regex: None,
rewrite: crate::vhost::PathRewrite::default(),
response: None,
redirect: None,
error_fallback: host.error_fallback.clone(),
source: fallback_source,
backend: fallback_backend,
acl_profile_id: None,
@@ -256,7 +268,7 @@ fn compile_routing(
country_access: crate::rate_limit::CountryAccess::default(),
method_policy: crate::vhost::MethodPolicy::default(),
headers: crate::headers::CompiledHeaders::default(),
unavailable: host.transient_unavailable,
unavailable: host.transient_unavailable && host.source.is_reverse_proxy(),
};
for name in &routing_hosts {
fallbacks
@@ -305,10 +317,12 @@ fn compile_routing(
None
}
};
ensure!(
path_bindings.insert((route.match_type, route.path_prefix.clone())),
"duplicate vhost location matcher"
);
if !route.internal {
ensure!(
path_bindings.insert((route.match_type, route.path_prefix.clone())),
"duplicate vhost location matcher"
);
}
validate_route_rewrite(route, path_regex.as_ref())?;
validate_location_response(route.response.as_ref())?;
let compiled_redirect = validate_location_redirect(route.redirect.as_ref())?;
@@ -377,13 +391,16 @@ fn compile_routing(
frontend: Some(frontend.clone()),
pool: route_pool,
cache: route.cache,
name: route.id.clone(),
id: format!("{}/{}", host.id, route.id),
internal: route.internal,
path_prefix: route.path_prefix.clone(),
match_type: route.match_type,
path_regex,
rewrite: route.rewrite.clone(),
response: route.response.clone(),
redirect: compiled_redirect,
error_fallback: route.error_fallback.clone(),
source,
backend,
acl_profile_id: route.acl_profile_id.clone(),
+7 -3
View File
@@ -76,6 +76,7 @@ impl Snapshot {
}
None
}
pub fn frontend(
&self,
host: &str,
@@ -224,7 +225,8 @@ where
F: Fn(&CompiledRoute) -> bool,
{
if let Some(exact) = routes.iter().find(|route| {
allowed(route)
!route.internal
&& allowed(route)
&& route.match_type == crate::vhost::PathMatch::Exact
&& route.path_prefix == path
}) {
@@ -233,7 +235,8 @@ where
let prefix = routes
.iter()
.filter(|route| {
allowed(route)
!route.internal
&& allowed(route)
&& matches!(
route.match_type,
crate::vhost::PathMatch::Prefix | crate::vhost::PathMatch::PrefixPriority
@@ -245,7 +248,8 @@ where
return prefix;
}
if let Some(regex) = routes.iter().find(|route| {
allowed(route)
!route.internal
&& allowed(route)
&& matches!(
route.match_type,
crate::vhost::PathMatch::Regex | crate::vhost::PathMatch::RegexInsensitive