v0.36.5
This commit is contained in:
1 parent
34490fd5fc
commit
6ef01212ec
21 files changed
+204
-77
No files matched your search
+23
-10
@@ -150,28 +150,35 @@ pub fn compile_reusing(
|
||||
type LocalHostBuild = (
|
||||
HashMap<String, Vec<Arc<crate::redirect::CompiledHost>>>,
|
||||
HashMap<String, Vec<Arc<crate::not_found::CompiledHost>>>,
|
||||
HashMap<String, Vec<crate::vhost::Listener>>,
|
||||
HashMap<String, Vec<(String, crate::vhost::Listener)>>,
|
||||
);
|
||||
|
||||
fn compile_local_hosts(config: &Config) -> Result<LocalHostBuild> {
|
||||
let mut redirects: HashMap<String, Vec<Arc<crate::redirect::CompiledHost>>> = HashMap::new();
|
||||
let mut not_found_hosts: HashMap<String, Vec<Arc<crate::not_found::CompiledHost>>> =
|
||||
HashMap::new();
|
||||
let mut claimed_hosts: HashMap<String, Vec<crate::vhost::Listener>> = HashMap::new();
|
||||
let mut claimed_hosts: HashMap<String, Vec<(String, crate::vhost::Listener)>> =
|
||||
HashMap::new();
|
||||
for redirect in &config.redirects {
|
||||
let bindings = redirect.frontend.resolved(&config.listeners)?;
|
||||
for name in &redirect.frontend.hosts {
|
||||
let claimed = claimed_hosts.entry(name.clone()).or_default();
|
||||
for a in claimed.iter() {
|
||||
for (owner, a) in claimed.iter() {
|
||||
for b in &bindings {
|
||||
ensure!(
|
||||
!crate::vhost::socket_overlap(a.address, b.address),
|
||||
"overlapping frontend bindings for hostname {}",
|
||||
name
|
||||
"overlapping frontend bindings for hostname {} (already used by {} on {})",
|
||||
name,
|
||||
owner,
|
||||
a.address
|
||||
);
|
||||
}
|
||||
}
|
||||
claimed.extend(bindings.iter().copied());
|
||||
claimed.extend(
|
||||
bindings
|
||||
.iter()
|
||||
.map(|binding| (format!("redirect {}", redirect.id), *binding)),
|
||||
);
|
||||
}
|
||||
if redirect.enabled {
|
||||
let compiled = Arc::new(crate::redirect::compile(redirect, &config.listeners)?);
|
||||
@@ -187,16 +194,22 @@ fn compile_local_hosts(config: &Config) -> Result<LocalHostBuild> {
|
||||
let bindings = host.frontend.resolved(&config.listeners)?;
|
||||
for name in &host.frontend.hosts {
|
||||
let claimed = claimed_hosts.entry(name.clone()).or_default();
|
||||
for a in claimed.iter() {
|
||||
for (owner, a) in claimed.iter() {
|
||||
for b in &bindings {
|
||||
ensure!(
|
||||
!crate::vhost::socket_overlap(a.address, b.address),
|
||||
"overlapping frontend bindings for hostname {}",
|
||||
name
|
||||
"overlapping frontend bindings for hostname {} (already used by {} on {})",
|
||||
name,
|
||||
owner,
|
||||
a.address
|
||||
);
|
||||
}
|
||||
}
|
||||
claimed.extend(bindings.iter().copied());
|
||||
claimed.extend(
|
||||
bindings
|
||||
.iter()
|
||||
.map(|binding| (format!("404 host {}", host.id), *binding)),
|
||||
);
|
||||
}
|
||||
if host.enabled {
|
||||
let compiled = Arc::new(crate::not_found::compile(host, &config.listeners)?);
|
||||
|
||||
+21
-8
@@ -65,7 +65,8 @@ pub fn compile_with_active(
|
||||
php_profiles
|
||||
.insert(profile.id.clone(), profile.php.clone())
|
||||
.is_none(),
|
||||
"duplicate PHP-FPM profile id"
|
||||
"duplicate PHP-FPM profile id {:?}: every profile needs a unique ID",
|
||||
profile.id
|
||||
);
|
||||
}
|
||||
ensure!(
|
||||
@@ -120,7 +121,8 @@ pub fn compile_with_active(
|
||||
);
|
||||
ensure!(
|
||||
web_services.insert(service.id.clone(), compiled).is_none(),
|
||||
"duplicate Web Service id"
|
||||
"duplicate Web Service id {:?}: every Web Service needs a unique ID",
|
||||
service.id
|
||||
);
|
||||
}
|
||||
ensure!(config.vhosts.len() <= 64, "too many vhosts (max 64)");
|
||||
@@ -145,7 +147,11 @@ pub fn compile_with_active(
|
||||
validate_source(&route.source)?;
|
||||
}
|
||||
}
|
||||
ensure!(vhost_ids.insert(host.id.clone()), "duplicate vhost id");
|
||||
ensure!(
|
||||
vhost_ids.insert(host.id.clone()),
|
||||
"duplicate vhost id {:?}: every vhost needs a unique ID",
|
||||
host.id
|
||||
);
|
||||
}
|
||||
ensure!(
|
||||
config.redirects.len() <= 64,
|
||||
@@ -158,7 +164,8 @@ pub fn compile_with_active(
|
||||
.with_context(|| format!("redirect {}", redirect.id))?;
|
||||
ensure!(
|
||||
redirect_ids.insert(redirect.id.clone()),
|
||||
"duplicate redirect id"
|
||||
"duplicate redirect id {:?}: every redirect needs a unique ID",
|
||||
redirect.id
|
||||
);
|
||||
}
|
||||
ensure!(
|
||||
@@ -171,7 +178,8 @@ pub fn compile_with_active(
|
||||
.with_context(|| format!("404 host {}", host.id))?;
|
||||
ensure!(
|
||||
not_found_ids.insert(host.id.clone()),
|
||||
"duplicate 404 host id"
|
||||
"duplicate 404 host id {:?}: every 404 host needs a unique ID",
|
||||
host.id
|
||||
);
|
||||
}
|
||||
let effective_tls = crate::tls::for_all_frontends(
|
||||
@@ -279,7 +287,11 @@ pub fn compile_with_active(
|
||||
let mut acl_profiles: HashMap<String, (Option<CompiledAcl>, crate::rate_limit::CountryAccess)> =
|
||||
HashMap::new();
|
||||
for profile in &mut config.acl_profiles {
|
||||
ensure!(valid_id(&profile.id), "invalid ACL profile id");
|
||||
ensure!(
|
||||
valid_id(&profile.id),
|
||||
"invalid ACL profile id {:?}: use 1-64 letters, digits, '-' or '_'",
|
||||
profile.id
|
||||
);
|
||||
ensure!(
|
||||
!profile.name.trim().is_empty()
|
||||
&& profile.name.len() <= 96
|
||||
@@ -293,7 +305,8 @@ pub fn compile_with_active(
|
||||
acl_profiles
|
||||
.insert(profile.id.clone(), (acl, profile.country_access.clone()))
|
||||
.is_none(),
|
||||
"duplicate ACL profile id"
|
||||
"duplicate ACL profile id {:?}: every ACL profile needs a unique ID",
|
||||
profile.id
|
||||
);
|
||||
}
|
||||
crate::acl::dynamic::configured_hostnames(&config)?;
|
||||
@@ -380,7 +393,7 @@ fn normalize_prefix(prefix: &mut String) -> Result<()> {
|
||||
&& !prefix.contains('?')
|
||||
&& !prefix.contains('#')
|
||||
&& !prefix.bytes().any(|b| b <= 32 || b == 127),
|
||||
"invalid path prefix"
|
||||
"invalid path prefix: it must start with '/', be at most 512 bytes and contain no '?', '#', spaces or control characters"
|
||||
);
|
||||
if prefix.len() > 1 {
|
||||
*prefix = prefix.trim_end_matches('/').to_owned();
|
||||
|
||||
+25
-10
@@ -79,16 +79,22 @@ fn compile_routing(
|
||||
);
|
||||
for name in &routing_hosts {
|
||||
let claimed = claimed_hosts.entry(name.clone()).or_default();
|
||||
for a in claimed.iter() {
|
||||
for (owner, a) in claimed.iter() {
|
||||
for b in &host_bindings {
|
||||
ensure!(
|
||||
!crate::vhost::socket_overlap(a.address, b.address),
|
||||
"overlapping frontend bindings for hostname {}",
|
||||
name
|
||||
"overlapping frontend bindings for hostname {} (already used by {} on {})",
|
||||
name,
|
||||
owner,
|
||||
a.address
|
||||
);
|
||||
}
|
||||
}
|
||||
claimed.extend(host_bindings.iter().copied());
|
||||
claimed.extend(
|
||||
host_bindings
|
||||
.iter()
|
||||
.map(|binding| (format!("vhost {}", host.id), *binding)),
|
||||
);
|
||||
}
|
||||
let needs_proxy_pool = host.source.is_reverse_proxy()
|
||||
|| host.routes.iter().any(|route| {
|
||||
@@ -323,7 +329,8 @@ fn compile_routing(
|
||||
for route in &mut host.routes {
|
||||
ensure!(
|
||||
valid_id(&route.id) && path_ids.insert(route.id.clone()),
|
||||
"invalid/duplicate vhost path id"
|
||||
"location ID {:?} is invalid or used twice in this vhost (use 1-64 letters, digits, '-' or '_', unique per vhost)",
|
||||
route.id
|
||||
);
|
||||
let path_regex = match route.match_type {
|
||||
crate::vhost::PathMatch::Regex | crate::vhost::PathMatch::RegexInsensitive => {
|
||||
@@ -331,7 +338,8 @@ fn compile_routing(
|
||||
!route.path_prefix.is_empty()
|
||||
&& route.path_prefix.len() <= 1024
|
||||
&& !route.path_prefix.chars().any(char::is_control),
|
||||
"invalid vhost location regex"
|
||||
"location {}: the regular expression must be 1-1024 characters without control characters",
|
||||
route.id
|
||||
);
|
||||
let mut builder = regex::RegexBuilder::new(&route.path_prefix);
|
||||
builder
|
||||
@@ -340,17 +348,23 @@ fn compile_routing(
|
||||
)
|
||||
.size_limit(2 * 1024 * 1024)
|
||||
.dfa_size_limit(2 * 1024 * 1024);
|
||||
Some(builder.build().context("invalid vhost location regex")?)
|
||||
Some(builder.build().with_context(|| {
|
||||
format!(
|
||||
"location {}: invalid or too complex regular expression",
|
||||
route.id
|
||||
)
|
||||
})?)
|
||||
}
|
||||
crate::vhost::PathMatch::Exact => {
|
||||
ensure!(
|
||||
!route.path_prefix.contains('?')
|
||||
&& !route.path_prefix.contains('#')
|
||||
&& !route.path_prefix.bytes().any(|b| b <= 32 || b == 127),
|
||||
"invalid exact location path"
|
||||
"location {}: an exact path must not contain '?', '#', spaces or control characters",
|
||||
route.id
|
||||
);
|
||||
route.path_prefix = crate::acl::routing_path(&route.path_prefix)
|
||||
.context("invalid exact location path")?;
|
||||
.with_context(|| format!("location {}: invalid exact path", route.id))?;
|
||||
None
|
||||
}
|
||||
crate::vhost::PathMatch::Prefix | crate::vhost::PathMatch::PrefixPriority => {
|
||||
@@ -361,7 +375,8 @@ fn compile_routing(
|
||||
if !route.internal {
|
||||
ensure!(
|
||||
path_bindings.insert((route.match_type, route.path_prefix.clone())),
|
||||
"duplicate vhost location matcher"
|
||||
"location {}: another location already uses the same path and match type",
|
||||
route.id
|
||||
);
|
||||
}
|
||||
validate_route_rewrite(route, path_regex.as_ref())?;
|
||||
|
||||
Reference in new issue
Block a user