v0.33.0
This commit is contained in:
1 parent
bbfa8cbc3f
commit
2ccc598b12
49 files changed
+4771
-639
No files matched your search
@@ -26,8 +26,7 @@ impl Php {
|
||||
"Web Service PHP request body limit must be 0..8589934592 bytes"
|
||||
);
|
||||
ensure!(
|
||||
self.max_response_header_bytes >= 4096
|
||||
&& self.max_response_header_bytes <= 1024 * 1024,
|
||||
self.max_response_header_bytes >= 4096 && self.max_response_header_bytes <= 1024 * 1024,
|
||||
"Web Service PHP response header limit must be 4096..1048576 bytes"
|
||||
);
|
||||
ensure!(
|
||||
@@ -37,7 +36,13 @@ impl Php {
|
||||
self.custom_params = normalize_fastcgi_params(std::mem::take(&mut self.custom_params))?;
|
||||
self.php_values = normalize_php_values(std::mem::take(&mut self.php_values))?;
|
||||
self.php_admin_values = normalize_php_values(std::mem::take(&mut self.php_admin_values))?;
|
||||
ensure!(!self.php_values.keys().any(|key| self.php_admin_values.contains_key(key)), "PHP_VALUE and PHP_ADMIN_VALUE must not define the same directive");
|
||||
ensure!(
|
||||
!self
|
||||
.php_values
|
||||
.keys()
|
||||
.any(|key| self.php_admin_values.contains_key(key)),
|
||||
"PHP_VALUE and PHP_ADMIN_VALUE must not define the same directive"
|
||||
);
|
||||
let php_custom_bytes = self
|
||||
.custom_params
|
||||
.iter()
|
||||
@@ -50,7 +55,10 @@ impl Php {
|
||||
"Web Service PHP custom FastCGI/PHP_VALUE data must be at most 128 KiB"
|
||||
);
|
||||
if self.enabled {
|
||||
ensure!(!self.extensions.is_empty(), "PHP-FPM needs executable extensions");
|
||||
ensure!(
|
||||
!self.extensions.is_empty(),
|
||||
"PHP-FPM needs executable extensions"
|
||||
);
|
||||
FastCgiEndpoint::parse(&self.endpoint)?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -59,10 +67,17 @@ impl Php {
|
||||
|
||||
impl PhpFpmProfile {
|
||||
pub fn validate(&mut self) -> Result<()> {
|
||||
ensure!(crate::config::valid_id(&self.id), "invalid PHP-FPM profile id");
|
||||
ensure!(
|
||||
crate::config::valid_id(&self.id),
|
||||
"invalid PHP-FPM profile id"
|
||||
);
|
||||
self.name = self.name.trim().to_owned();
|
||||
ensure!(!self.name.is_empty() && self.name.len() <= MAX_SERVICE_NAME_BYTES
|
||||
&& !self.name.chars().any(char::is_control), "PHP-FPM profile name is invalid");
|
||||
ensure!(
|
||||
!self.name.is_empty()
|
||||
&& self.name.len() <= MAX_SERVICE_NAME_BYTES
|
||||
&& !self.name.chars().any(char::is_control),
|
||||
"PHP-FPM profile name is invalid"
|
||||
);
|
||||
self.php.validate()
|
||||
}
|
||||
}
|
||||
@@ -98,7 +113,10 @@ impl Service {
|
||||
&& item != "..",
|
||||
"Web Service index entries must be plain file names"
|
||||
);
|
||||
ensure!(seen.insert(item.clone()), "duplicate Web Service index file");
|
||||
ensure!(
|
||||
seen.insert(item.clone()),
|
||||
"duplicate Web Service index file"
|
||||
);
|
||||
}
|
||||
ensure!(
|
||||
self.mime_types.len() <= MAX_MIME_TYPES,
|
||||
@@ -106,7 +124,10 @@ impl Service {
|
||||
);
|
||||
let mut normalized_mime_types = BTreeMap::new();
|
||||
for (extension, value) in std::mem::take(&mut self.mime_types) {
|
||||
let extension = extension.trim().trim_start_matches('.').to_ascii_lowercase();
|
||||
let extension = extension
|
||||
.trim()
|
||||
.trim_start_matches('.')
|
||||
.to_ascii_lowercase();
|
||||
ensure!(
|
||||
!extension.is_empty()
|
||||
&& extension.len() <= MAX_MIME_EXTENSION_BYTES
|
||||
@@ -160,14 +181,11 @@ impl Service {
|
||||
.matcher
|
||||
.strip_prefix("ext:")
|
||||
.is_some_and(valid_extension)
|
||||
|| rule
|
||||
.matcher
|
||||
.strip_prefix("mime:")
|
||||
.is_some_and(|value| {
|
||||
!value.is_empty()
|
||||
&& value.len() <= MAX_MIME_VALUE_BYTES
|
||||
&& !value.chars().any(char::is_control)
|
||||
});
|
||||
|| rule.matcher.strip_prefix("mime:").is_some_and(|value| {
|
||||
!value.is_empty()
|
||||
&& value.len() <= MAX_MIME_VALUE_BYTES
|
||||
&& !value.chars().any(char::is_control)
|
||||
});
|
||||
ensure!(
|
||||
valid_matcher,
|
||||
"Web Service cache rule matcher must be ext:<extension> or mime:<prefix>"
|
||||
@@ -192,8 +210,8 @@ impl Service {
|
||||
!name.is_empty() && name.len() <= MAX_HEADER_NAME_BYTES,
|
||||
"Web Service response header name must be 1..128 bytes"
|
||||
);
|
||||
let header_name = HeaderName::from_str(&name)
|
||||
.context("invalid Web Service response header name")?;
|
||||
let header_name =
|
||||
HeaderName::from_str(&name).context("invalid Web Service response header name")?;
|
||||
ensure!(
|
||||
!protected_service_header(&header_name),
|
||||
"Web Service response header cannot override framing/transport headers"
|
||||
@@ -203,8 +221,7 @@ impl Service {
|
||||
value.len() <= MAX_HEADER_VALUE_BYTES,
|
||||
"Web Service response header value must be at most 8192 bytes"
|
||||
);
|
||||
HeaderValue::from_str(&value)
|
||||
.context("invalid Web Service response header value")?;
|
||||
HeaderValue::from_str(&value).context("invalid Web Service response header value")?;
|
||||
ensure!(
|
||||
normalized_headers.insert(name, value).is_none(),
|
||||
"duplicate Web Service response header"
|
||||
@@ -277,7 +294,10 @@ impl Service {
|
||||
|
||||
self.php.validate()?;
|
||||
if let Some(id) = &self.php_profile_id {
|
||||
ensure!(crate::config::valid_id(id), "invalid PHP-FPM profile reference");
|
||||
ensure!(
|
||||
crate::config::valid_id(id),
|
||||
"invalid PHP-FPM profile reference"
|
||||
);
|
||||
}
|
||||
htaccess::validate(&mut self.htaccess)?;
|
||||
|
||||
@@ -320,7 +340,10 @@ impl Service {
|
||||
);
|
||||
#[cfg(unix)]
|
||||
let root_handle = Arc::new(open_root_directory(&root).with_context(|| {
|
||||
format!("Web Service {} document root could not be opened safely", self.id)
|
||||
format!(
|
||||
"Web Service {} document root could not be opened safely",
|
||||
self.id
|
||||
)
|
||||
})?);
|
||||
let htaccess = htaccess::compile(&root, &self.htaccess)?;
|
||||
if let Some(compiled) = &htaccess {
|
||||
@@ -337,10 +360,7 @@ impl Service {
|
||||
.response_headers
|
||||
.iter()
|
||||
.map(|(name, value)| {
|
||||
Ok::<_, anyhow::Error>((
|
||||
HeaderName::from_str(name)?,
|
||||
HeaderValue::from_str(value)?,
|
||||
))
|
||||
Ok::<_, anyhow::Error>((HeaderName::from_str(name)?, HeaderValue::from_str(value)?))
|
||||
})
|
||||
.collect::<std::result::Result<Vec<_>, anyhow::Error>>()?;
|
||||
let cache_rules = self
|
||||
@@ -367,12 +387,20 @@ impl Service {
|
||||
Ok(CompiledRewriteRule {
|
||||
pattern: Regex::new(&rule.pattern)?,
|
||||
replacement: rule.replacement.clone(),
|
||||
status: rule.status.and_then(|value| StatusCode::from_u16(value).ok()),
|
||||
status: rule
|
||||
.status
|
||||
.and_then(|value| StatusCode::from_u16(value).ok()),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
let mut script_extensions: HashSet<String> = self.php.extensions.iter().cloned().collect();
|
||||
script_extensions.extend(["php", "phtml", "phar", "php3", "php4", "php5", "php7", "php8"].into_iter().map(str::to_owned));
|
||||
script_extensions.extend(
|
||||
[
|
||||
"php", "phtml", "phar", "php3", "php4", "php5", "php7", "php8",
|
||||
]
|
||||
.into_iter()
|
||||
.map(str::to_owned),
|
||||
);
|
||||
let php = if self.php.enabled {
|
||||
Some(CompiledPhp {
|
||||
extensions: self.php.extensions.iter().cloned().collect(),
|
||||
@@ -381,6 +409,7 @@ impl Service {
|
||||
connect_timeout: Duration::from_millis(self.php.connect_timeout_ms),
|
||||
request_timeout: Duration::from_millis(self.php.request_timeout_ms),
|
||||
permits: Arc::new(Semaphore::new(self.php.max_concurrent_requests)),
|
||||
max_concurrent: self.php.max_concurrent_requests,
|
||||
pass_authorization: self.php.pass_authorization,
|
||||
max_request_body_bytes: self.php.max_request_body_bytes,
|
||||
max_response_header_bytes: self.php.max_response_header_bytes,
|
||||
@@ -403,10 +432,9 @@ impl Service {
|
||||
mime_types: self
|
||||
.mime_types
|
||||
.iter()
|
||||
.map(|(extension, value)| {
|
||||
Ok((extension.clone(), HeaderValue::from_str(value)?))
|
||||
})
|
||||
.collect::<std::result::Result<BTreeMap<_, _>, http::header::InvalidHeaderValue>>()?,
|
||||
.map(|(extension, value)| Ok((extension.clone(), HeaderValue::from_str(value)?)))
|
||||
.collect::<std::result::Result<BTreeMap<_, _>, http::header::InvalidHeaderValue>>(
|
||||
)?,
|
||||
default_mime_type: HeaderValue::from_str(&self.default_mime_type)?,
|
||||
cache_control: self
|
||||
.cache_control
|
||||
|
||||
Reference in new issue
Block a user