v0.29.4
This commit is contained in:
1 parent
f87eec7287
commit
dd8c195600
38 files changed
+5491
-4682
No files matched your search
+20
-16
@@ -48,24 +48,28 @@ pub fn compile_with_active(
|
||||
config.compression.validate()?;
|
||||
config.server_header.validate()?;
|
||||
let forwarding = config.forwarding.compile()?;
|
||||
ensure!(
|
||||
config.web_services.len() <= 128,
|
||||
"too many Web Services (max 128)"
|
||||
);
|
||||
ensure!(config.php_fpm_profiles.len() <= 128, "too many PHP-FPM profiles (max 128)");
|
||||
let mut php_profiles = HashMap::new();
|
||||
for profile in &mut config.php_fpm_profiles {
|
||||
profile.validate().with_context(|| format!("PHP-FPM profile {}", profile.id))?;
|
||||
ensure!(php_profiles.insert(profile.id.clone(), profile.php.clone()).is_none(),
|
||||
"duplicate PHP-FPM profile id");
|
||||
}
|
||||
ensure!(config.web_services.len() <= 128, "too many Web Services (max 128)");
|
||||
let mut web_services = HashMap::new();
|
||||
for service in &mut config.web_services {
|
||||
service
|
||||
.validate()
|
||||
.with_context(|| format!("Web Service {}", service.id))?;
|
||||
let compiled = Arc::new(
|
||||
service
|
||||
.compile()
|
||||
.with_context(|| format!("Web Service {}", service.id))?,
|
||||
);
|
||||
ensure!(
|
||||
web_services.insert(service.id.clone(), compiled).is_none(),
|
||||
"duplicate Web Service id"
|
||||
);
|
||||
service.validate().with_context(|| format!("Web Service {}", service.id))?;
|
||||
// A profile changes effective runtime settings, not the saved standalone
|
||||
// PHP configuration. Detaching a profile restores local settings exactly.
|
||||
let mut effective = service.clone();
|
||||
if let Some(id) = &service.php_profile_id {
|
||||
effective.php = php_profiles.get(id).with_context(|| {
|
||||
format!("Web Service {} references unknown PHP-FPM profile {}", service.id, id)
|
||||
})?.clone();
|
||||
effective.validate().with_context(|| format!("Web Service {} PHP-FPM profile {}", service.id, id))?;
|
||||
}
|
||||
let compiled = Arc::new(effective.compile().with_context(|| format!("Web Service {}", service.id))?);
|
||||
ensure!(web_services.insert(service.id.clone(), compiled).is_none(), "duplicate Web Service id");
|
||||
}
|
||||
ensure!(config.vhosts.len() <= 64, "too many vhosts (max 64)");
|
||||
let mut vhost_ids = HashSet::new();
|
||||
|
||||
@@ -67,6 +67,8 @@ pub struct Config {
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub web_services: Vec<crate::web_server::Service>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub php_fpm_profiles: Vec<crate::web_server::PhpFpmProfile>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub vhosts: Vec<crate::vhost::Vhost>,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub host_policies: Vec<HostPolicy>,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod tests {
|
||||
include!("tests/part_01.rs");
|
||||
include!("tests/part_02.rs");
|
||||
include!("tests/part_03.rs");
|
||||
}
|
||||
@@ -480,3 +480,4 @@ fn backend_diagnostic_flags_compile_to_frontend() {
|
||||
assert!(frontend.backend_header);
|
||||
assert!(frontend.backend_timing_header);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
#[test]
|
||||
fn shared_php_fpm_profile_is_reused_and_detach_restores_local_configuration() {
|
||||
let tmp = tempfile::TempDir::new().unwrap();
|
||||
std::fs::write(tmp.path().join("index.php"), b"<?php echo 'ok';").unwrap();
|
||||
let mut config = demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
config.php_fpm_profiles.push(crate::web_server::PhpFpmProfile {
|
||||
id: "php-default".into(),
|
||||
name: "Default PHP pool".into(),
|
||||
php: crate::web_server::Php {
|
||||
enabled: true,
|
||||
endpoint: "tcp:127.0.0.1:9000".into(),
|
||||
..Default::default()
|
||||
},
|
||||
});
|
||||
let service = crate::web_server::Service {
|
||||
id: "site-one".into(),
|
||||
name: "Site One".into(),
|
||||
document_root: tmp.path().to_path_buf(),
|
||||
php_profile_id: Some("php-default".into()),
|
||||
// Standalone settings remain distinct and disabled.
|
||||
php: crate::web_server::Php::default(),
|
||||
..Default::default()
|
||||
};
|
||||
let mut second = service.clone();
|
||||
second.id = "site-two".into();
|
||||
second.name = "Site Two".into();
|
||||
config.web_services.extend([service, second]);
|
||||
config.vhosts[0].source = crate::vhost::Source::WebServer {
|
||||
web_service_id: "site-one".into(),
|
||||
};
|
||||
config.vhosts[0].routes.clear();
|
||||
config.vhosts[0].backends.clear();
|
||||
|
||||
let snapshot = compile(config, 1, &policy()).unwrap();
|
||||
for id in ["site-one", "site-two"] {
|
||||
let compiled = snapshot.web_php_services.get(id).unwrap();
|
||||
assert!(compiled.php.is_some(), "{id} must use the shared FPM profile");
|
||||
}
|
||||
assert_eq!(snapshot.envelope.config.php_fpm_profiles.len(), 1);
|
||||
assert!(!snapshot.envelope.config.web_services[0].php.enabled);
|
||||
assert!(!snapshot.envelope.config.web_services[1].php.enabled);
|
||||
|
||||
let serialized = serde_json::to_string(&snapshot.envelope.config).unwrap();
|
||||
let mut detached: Config = serde_json::from_str(&serialized).unwrap();
|
||||
detached.web_services[0].php_profile_id = None;
|
||||
let snapshot = compile(detached, 2, &policy()).unwrap();
|
||||
assert!(snapshot.web_php_services.get("site-one").unwrap().php.is_none());
|
||||
assert!(snapshot.web_php_services.get("site-two").unwrap().php.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_php_fpm_profile_reference_and_duplicate_ids_are_rejected() {
|
||||
let tmp = tempfile::TempDir::new().unwrap();
|
||||
let mut config = demo_config("127.0.0.1:9000".parse().unwrap());
|
||||
config.web_services.push(crate::web_server::Service {
|
||||
id: "site".into(),
|
||||
name: "Site".into(),
|
||||
document_root: tmp.path().to_path_buf(),
|
||||
php_profile_id: Some("missing".into()),
|
||||
..Default::default()
|
||||
});
|
||||
let err = compile(config.clone(), 1, &policy()).unwrap_err().to_string();
|
||||
assert!(err.contains("unknown PHP-FPM profile"), "{err}");
|
||||
config.web_services[0].php_profile_id = None;
|
||||
let profile = crate::web_server::PhpFpmProfile {
|
||||
id: "duplicate".into(),
|
||||
name: "Duplicate".into(),
|
||||
php: Default::default(),
|
||||
};
|
||||
config.php_fpm_profiles = vec![profile.clone(), profile];
|
||||
let err = compile(config, 1, &policy()).unwrap_err().to_string();
|
||||
assert!(err.contains("duplicate PHP-FPM profile"), "{err}");
|
||||
}
|
||||
Reference in new issue
Block a user