diff --git a/Cargo.lock b/Cargo.lock index bcd94097..a5976dff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -654,15 +654,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "backtrace-ext" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" -dependencies = [ - "backtrace", -] - [[package]] name = "base64" version = "0.22.1" @@ -1339,8 +1330,7 @@ dependencies = [ "hyper-rustls", "hyper-util", "instant-acme", - "kdl", - "miette", + "kdlite", "mimalloc", "monoio", "monoio-compat", @@ -1360,6 +1350,7 @@ dependencies = [ "shadow-rs", "shiba", "smallvec", + "snailquote", "socket2 0.6.1", "tokio", "tokio-rustls", @@ -1538,7 +1529,7 @@ dependencies = [ "anyhow", "glob", "hashlink", - "kdl", + "kdlite", "yaml-rust2", ] @@ -2303,12 +2294,6 @@ dependencies = [ "serde", ] -[[package]] -name = "is_ci" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" - [[package]] name = "is_debug" version = "1.1.0" @@ -2388,15 +2373,10 @@ dependencies = [ ] [[package]] -name = "kdl" -version = "6.5.0" +name = "kdlite" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a29e7b50079ff44549f68c0becb1c73d7f6de2a4ea952da77966daf3d4761e" -dependencies = [ - "miette", - "num", - "winnow 0.6.24", -] +checksum = "92fec2005a8cff787f987380d001fe74db389b4387366fa41536e54810de861e" [[package]] name = "lazy_static" @@ -2469,36 +2449,6 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" -[[package]] -name = "miette" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" -dependencies = [ - "backtrace", - "backtrace-ext", - "cfg-if", - "miette-derive", - "owo-colors", - "supports-color", - "supports-hyperlinks", - "supports-unicode", - "terminal_size", - "textwrap", - "unicode-width 0.1.14", -] - -[[package]] -name = "miette-derive" -version = "7.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "mimalloc" version = "0.1.48" @@ -2655,20 +2605,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.6" @@ -2679,15 +2615,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -2703,28 +2630,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -2930,12 +2835,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" -[[package]] -name = "owo-colors" -version = "4.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" - [[package]] name = "parking" version = "2.2.1" @@ -4014,6 +3913,16 @@ dependencies = [ "syn", ] +[[package]] +name = "snailquote" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec62a949bda7f15800481a711909f946e1204f2460f89210eaf7f57730f88f86" +dependencies = [ + "thiserror 1.0.69", + "unicode_categories", +] + [[package]] name = "socket2" version = "0.5.10" @@ -4052,27 +3961,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "supports-color" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" -dependencies = [ - "is_ci", -] - -[[package]] -name = "supports-hyperlinks" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" - -[[package]] -name = "supports-unicode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" - [[package]] name = "syn" version = "2.0.114" @@ -4151,26 +4039,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "terminal_size" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" -dependencies = [ - "rustix", - "windows-sys 0.60.2", -] - -[[package]] -name = "textwrap" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" -dependencies = [ - "unicode-linebreak", - "unicode-width 0.2.2", -] - [[package]] name = "thiserror" version = "1.0.69" @@ -4373,7 +4241,7 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow 0.7.14", + "winnow", ] [[package]] @@ -4391,7 +4259,7 @@ version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ - "winnow 0.7.14", + "winnow", ] [[package]] @@ -4573,30 +4441,18 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-linebreak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" - [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "untrusted" version = "0.7.1" @@ -5296,15 +5152,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.6.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.7.14" diff --git a/Cargo.toml b/Cargo.toml index 06bbcd72..47b4e747 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,8 @@ exclude = ["build-prepare", "build-installer", "dockertest"] resolver = "2" [workspace.dependencies] -kdl = "6.3.4" -mimalloc = { version = "0.1.46" } +kdlite = "0.1.1" +mimalloc = "0.1.46" password-auth = { version = "1.0.0", features = ["pbkdf2", "argon2", "scrypt"] } shiba = "0.1.1" ferron-common = { path = "./ferron-common", default-features = false } diff --git a/ferron-yaml2kdl-core/Cargo.toml b/ferron-yaml2kdl-core/Cargo.toml index 88ac4936..e2e90cea 100644 --- a/ferron-yaml2kdl-core/Cargo.toml +++ b/ferron-yaml2kdl-core/Cargo.toml @@ -7,5 +7,5 @@ edition = "2021" anyhow = "1.0.98" glob = "0.3.2" hashlink = "0.11.0" -kdl = { workspace = true } +kdlite = { workspace = true } yaml-rust2 = "0.11.0" diff --git a/ferron-yaml2kdl-core/src/lib.rs b/ferron-yaml2kdl-core/src/lib.rs index d4d0d42f..7abbe7e7 100644 --- a/ferron-yaml2kdl-core/src/lib.rs +++ b/ferron-yaml2kdl-core/src/lib.rs @@ -1,18 +1,19 @@ use std::{collections::HashMap, error::Error, path::PathBuf}; use hashlink::LinkedHashMap; -use kdl::{KdlDocument, KdlEntry, KdlNode, KdlValue}; use load_config::load_config; use yaml_rust2::Yaml; mod load_config; /// Converts Ferron 1.x YAML configuration to Ferron 2.x KDL configuration -pub fn convert_yaml_to_kdl(input_path: PathBuf) -> Result> { +pub fn convert_yaml_to_kdl( + input_path: PathBuf, +) -> Result, Box> { let yaml_configuration = load_config(input_path)?; - let mut kdl_configuration = KdlDocument::new(); + let mut kdl_configuration = kdlite::dom::Document::new(); - let kdl_configuration_nodes = kdl_configuration.nodes_mut(); + let kdl_configuration_nodes = &mut kdl_configuration.nodes; let (global_configuration, sni_configurations, load_server_modules, secure_port) = obtain_global_configuration(&yaml_configuration); kdl_configuration_nodes.push(global_configuration); @@ -23,22 +24,14 @@ pub fn convert_yaml_to_kdl(input_path: PathBuf) -> Result Result, -) -> (KdlDocument, Option) { +) -> (kdlite::dom::Document<'static>, Option>) { let empty_hashmap = yaml_rust2::yaml::Hash::new(); let yaml_properties = yaml_subconfiguration.as_hash().unwrap_or(&empty_hashmap); - let mut kdl_config = KdlDocument::new(); - let mut kdl_secure_config = KdlDocument::new(); + let mut kdl_config = kdlite::dom::Document::new(); + let mut kdl_secure_config = kdlite::dom::Document::new(); - let kdl_config_nodes = kdl_config.nodes_mut(); - let kdl_secure_config_nodes = kdl_secure_config.nodes_mut(); + let kdl_config_nodes = &mut kdl_config.nodes; + let kdl_secure_config_nodes = &mut kdl_secure_config.nodes; let mut scgi_to = "tcp://localhost:4000/"; let mut scgi_path = None; @@ -121,14 +104,22 @@ pub fn obtain_host_configuration( if let Some(location_path) = location["path"].as_str() { let (location_config, secure_location_config_option) = obtain_host_configuration(location, loaded_modules, &mut custom_headers.clone()); - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(location_path.to_string())); - kdl_location.set_children(location_config); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(location_path.to_string()), + ))); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); if let Some(secure_location_config) = secure_location_config_option { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(location_path.to_string())); - kdl_location.set_children(secure_location_config); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(location_path.to_string()), + ))); + kdl_location.children = Some(secure_location_config); kdl_secure_config_nodes.insert(0, kdl_location); } } @@ -140,18 +131,26 @@ pub fn obtain_host_configuration( for error_config in error_configs.iter().rev() { let (error_config_d, secure_error_config_d_option) = obtain_host_configuration(error_config, loaded_modules, &mut custom_headers.clone()); - let mut kdl_error_config = KdlNode::new("error_config"); + let mut kdl_error_config = kdlite::dom::Node::new("error_config"); if let Some(status_code) = error_config["scode"].as_i64() { - kdl_error_config.push(KdlValue::Integer(status_code as i128)); + kdl_error_config + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + status_code as i128, + ))); } - kdl_error_config.set_children(error_config_d); + kdl_error_config.children = Some(error_config_d); kdl_config_nodes.insert(0, kdl_error_config); if let Some(secure_error_config_d) = secure_error_config_d_option { - let mut kdl_error_config = KdlNode::new("error_config"); + let mut kdl_error_config = kdlite::dom::Node::new("error_config"); if let Some(status_code) = error_config["scode"].as_i64() { - kdl_error_config.push(KdlValue::Integer(status_code as i128)); + kdl_error_config + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + status_code as i128, + ))); } - kdl_error_config.set_children(secure_error_config_d); + kdl_error_config.children = Some(secure_error_config_d); kdl_config_nodes.insert(0, kdl_error_config); } } @@ -159,8 +158,12 @@ pub fn obtain_host_configuration( } "serverAdministratorEmail" => { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("server_administrator_email"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("server_administrator_email"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -177,36 +180,44 @@ pub fn obtain_host_configuration( } "disableToHTTPSRedirect" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("no_redirect_to_https"); + let mut kdl_property = kdlite::dom::Node::new("no_redirect_to_https"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "wwwredirect" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("wwwredirect"); + let mut kdl_property = kdlite::dom::Node::new("wwwredirect"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "enableIPSpoofing" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("trust_x_forwarded_for"); + let mut kdl_property = kdlite::dom::Node::new("trust_x_forwarded_for"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "allowDoubleSlashes" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("allow_double_slashes"); + let mut kdl_property = kdlite::dom::Node::new("allow_double_slashes"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -216,20 +227,38 @@ pub fn obtain_host_configuration( for value in value { if let Some(regex) = value["regex"].as_str() { if let Some(replacement) = value["replacement"].as_str() { - let mut kdl_property = KdlNode::new("rewrite"); - kdl_property.push(KdlValue::String(regex.to_string())); - kdl_property.push(KdlValue::String(replacement.to_string())); + let mut kdl_property = kdlite::dom::Node::new("rewrite"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(regex.to_string()), + ))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(replacement.to_string()), + ))); if let Some(value) = value["isNotFile"].as_bool() { - kdl_property.push(KdlEntry::new_prop("file", KdlValue::Bool(!value))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_prop("file", kdlite::dom::Value::Bool(!value))); } if let Some(value) = value["isNotDirectory"].as_bool() { - kdl_property.push(KdlEntry::new_prop("directory", KdlValue::Bool(!value))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "directory", + kdlite::dom::Value::Bool(!value), + )); } if let Some(value) = value["allowDoubleSlashes"].as_bool() { - kdl_property.push(KdlEntry::new_prop("allow_double_slashes", KdlValue::Bool(value))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "allow_double_slashes", + kdlite::dom::Value::Bool(value), + )); } if let Some(value) = value["last"].as_bool() { - kdl_property.push(KdlEntry::new_prop("last", KdlValue::Bool(value))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_prop("last", kdlite::dom::Value::Bool(value))); } kdl_config_nodes.push(kdl_property); } @@ -239,25 +268,33 @@ pub fn obtain_host_configuration( } "enableRewriteLogging" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("rewrite_log"); + let mut kdl_property = kdlite::dom::Node::new("rewrite_log"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "wwwroot" => { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("root"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("root"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } "disableTrailingSlashRedirects" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("no_trailing_redirect"); + let mut kdl_property = kdlite::dom::Node::new("no_trailing_redirect"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -267,9 +304,17 @@ pub fn obtain_host_configuration( for value in value { if let Some(user) = value["name"].as_str() { if let Some(pass) = value["pass"].as_str() { - let mut kdl_property = KdlNode::new("user"); - kdl_property.push(KdlValue::String(user.to_string())); - kdl_property.push(KdlValue::String(pass.to_string())); + let mut kdl_property = kdlite::dom::Node::new("user"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(user.to_string()), + ))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(pass.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -280,33 +325,66 @@ pub fn obtain_host_configuration( if let Some(value) = value.as_vec() { for value in value { if let Some(scode) = value["scode"].as_i64() { - let mut kdl_property = KdlNode::new("status"); - kdl_property.push(KdlValue::Integer(scode as i128)); + let mut kdl_property = kdlite::dom::Node::new("status"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + scode as i128, + ))); if let Some(value) = value["url"].as_str() { - kdl_property.push(KdlEntry::new_prop("url", KdlValue::String(value.to_string()))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "url", + kdlite::dom::Value::String(std::borrow::Cow::Owned(value.to_string())), + )); } if let Some(value) = value["regex"].as_str() { - kdl_property.push(KdlEntry::new_prop("regex", KdlValue::String(value.to_string()))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "regex", + kdlite::dom::Value::String(std::borrow::Cow::Owned(value.to_string())), + )); } if let Some(value) = value["location"].as_str() { - kdl_property.push(KdlEntry::new_prop("location", KdlValue::String(value.to_string()))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "location", + kdlite::dom::Value::String(std::borrow::Cow::Owned(value.to_string())), + )); } if let Some(value) = value["realm"].as_str() { - kdl_property.push(KdlEntry::new_prop("realm", KdlValue::String(value.to_string()))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "realm", + kdlite::dom::Value::String(std::borrow::Cow::Owned(value.to_string())), + )); } if let Some(value) = value["disableBruteProtection"].as_bool() { - kdl_property.push(KdlEntry::new_prop("brute_protection", KdlValue::Bool(!value))); + kdl_property.entries.push(kdlite::dom::Entry::new_prop( + "brute_protection", + kdlite::dom::Value::Bool(!value), + )); } if let Some(value) = value["userList"].as_vec() { - kdl_property.push(KdlEntry::new_prop( + kdl_property.entries.push(kdlite::dom::Entry::new_prop( "users", - KdlValue::String(value.iter().filter_map(|v| v.as_str()).collect::>().join(",")), + kdlite::dom::Value::String(std::borrow::Cow::Owned( + value + .iter() + .filter_map(|v| v.as_str()) + .collect::>() + .join(",") + .to_string(), + )), )); } if let Some(value) = value["users"].as_vec() { - kdl_property.push(KdlEntry::new_prop( + kdl_property.entries.push(kdlite::dom::Entry::new_prop( "allowed", - KdlValue::String(value.iter().filter_map(|v| v.as_str()).collect::>().join(",")), + kdlite::dom::Value::String(std::borrow::Cow::Owned( + value + .iter() + .filter_map(|v| v.as_str()) + .collect::>() + .join(",") + .to_string(), + )), )); } kdl_config_nodes.push(kdl_property); @@ -319,9 +397,17 @@ pub fn obtain_host_configuration( for value in value { if let Some(scode) = value["scode"].as_i64() { if let Some(path) = value["path"].as_str() { - let mut kdl_property = KdlNode::new("error_page"); - kdl_property.push(KdlValue::Integer(scode as i128)); - kdl_property.push(KdlValue::String(path.to_string())); + let mut kdl_property = kdlite::dom::Node::new("error_page"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + scode as i128, + ))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(path.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -330,27 +416,33 @@ pub fn obtain_host_configuration( } "enableETag" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("etag"); + let mut kdl_property = kdlite::dom::Node::new("etag"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "enableCompression" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("compressed"); + let mut kdl_property = kdlite::dom::Node::new("compressed"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } } "enableDirectoryListing" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("directory_listing"); + let mut kdl_property = kdlite::dom::Node::new("directory_listing"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -358,14 +450,22 @@ pub fn obtain_host_configuration( "proxyTo" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("proxy"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } else if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("proxy"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -375,14 +475,22 @@ pub fn obtain_host_configuration( "secureProxyTo" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("proxy"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_secure_config_nodes.push(kdl_property); } else if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("proxy"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_secure_config_nodes.push(kdl_property); } } @@ -394,8 +502,12 @@ pub fn obtain_host_configuration( if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("cache_vary"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("cache_vary"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -407,8 +519,12 @@ pub fn obtain_host_configuration( if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("cache_ignore"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("cache_ignore"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -418,12 +534,18 @@ pub fn obtain_host_configuration( "maximumCacheResponseSize" => { if loaded_modules.contains(&"cache".to_string()) { if let Some(value) = value.as_i64() { - let mut kdl_property = KdlNode::new("cache_max_response_size"); - kdl_property.push(KdlValue::Integer(value as i128)); + let mut kdl_property = kdlite::dom::Node::new("cache_max_response_size"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + value as i128, + ))); kdl_config_nodes.push(kdl_property); } else if value.is_null() { - let mut kdl_property = KdlNode::new("cache_max_response_size"); - kdl_property.push(KdlValue::Null); + let mut kdl_property = kdlite::dom::Node::new("cache_max_response_size"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Null)); kdl_config_nodes.push(kdl_property); } } @@ -433,8 +555,12 @@ pub fn obtain_host_configuration( if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("cgi_extension"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("cgi_extension"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -447,18 +573,32 @@ pub fn obtain_host_configuration( for (extension, interpreter) in value { if let Some(extension) = extension.as_str() { if let Some(interpreter) = interpreter.as_vec() { - let mut kdl_property = KdlNode::new("cgi_interpreter"); - kdl_property.push(KdlValue::String(extension.to_string())); + let mut kdl_property = kdlite::dom::Node::new("cgi_interpreter"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(extension.to_string()), + ))); for value in interpreter { if let Some(value) = value.as_str() { - kdl_property.push(KdlValue::String(value.to_string())); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); } } kdl_config_nodes.push(kdl_property); } else if interpreter.is_null() { - let mut kdl_property = KdlNode::new("cgi_interpreter"); - kdl_property.push(KdlValue::String(extension.to_string())); - kdl_property.push(KdlValue::Null); + let mut kdl_property = kdlite::dom::Node::new("cgi_interpreter"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(extension.to_string()), + ))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Null)); kdl_config_nodes.push(kdl_property); } } @@ -494,8 +634,12 @@ pub fn obtain_host_configuration( "authTo" => { if loaded_modules.contains(&"fauth".to_string()) { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("auth_to"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("auth_to"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -505,8 +649,12 @@ pub fn obtain_host_configuration( if let Some(value) = value.as_vec() { for value in value { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("auth_to_copy"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("auth_to_copy"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -516,9 +664,11 @@ pub fn obtain_host_configuration( "enableLoadBalancerHealthCheck" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("lb_health_check"); + let mut kdl_property = kdlite::dom::Node::new("lb_health_check"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -527,8 +677,12 @@ pub fn obtain_host_configuration( "loadBalancerHealthCheckMaximumFails" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_i64() { - let mut kdl_property = KdlNode::new("lb_health_check_max_fails"); - kdl_property.push(KdlValue::Integer(value as i128)); + let mut kdl_property = kdlite::dom::Node::new("lb_health_check_max_fails"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + value as i128, + ))); kdl_config_nodes.push(kdl_property); } } @@ -536,9 +690,11 @@ pub fn obtain_host_configuration( "disableProxyCertificateVerification" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("proxy_no_verification"); + let mut kdl_property = kdlite::dom::Node::new("proxy_no_verification"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -577,9 +733,11 @@ pub fn obtain_host_configuration( "proxyInterceptErrors" => { if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("proxy_intercept_errors"); + let mut kdl_property = kdlite::dom::Node::new("proxy_intercept_errors"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_config_nodes.push(kdl_property); } @@ -589,14 +747,26 @@ pub fn obtain_host_configuration( if loaded_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_bool() { if value { - let mut kdl_property = KdlNode::new("proxy_request_header_remove"); - kdl_property.push(KdlValue::String("X-Forwarded-For".to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy_request_header_remove"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned("X-Forwarded-For".to_string()), + ))); kdl_config_nodes.push(kdl_property); - let mut kdl_property = KdlNode::new("proxy_request_header_remove"); - kdl_property.push(KdlValue::String("X-Forwarded-Proto".to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy_request_header_remove"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned("X-Forwarded-Proto".to_string()), + ))); kdl_config_nodes.push(kdl_property); - let mut kdl_property = KdlNode::new("proxy_request_header_remove"); - kdl_property.push(KdlValue::String("X-Forwarded-Host".to_string())); + let mut kdl_property = kdlite::dom::Node::new("proxy_request_header_remove"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned("X-Forwarded-Host".to_string()), + ))); kdl_config_nodes.push(kdl_property); } } @@ -608,17 +778,28 @@ pub fn obtain_host_configuration( } if loaded_modules.contains(&"scgi".to_string()) { - let mut kdl_scgi = KdlNode::new("scgi"); - kdl_scgi.push(KdlValue::String(scgi_to.to_string())); + let mut kdl_scgi = kdlite::dom::Node::new("scgi"); + kdl_scgi + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(scgi_to.to_string()), + ))); if let Some(scgi_path) = scgi_path { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(scgi_path.to_string())); - kdl_location.push(KdlEntry::new_prop("remove_base", KdlValue::Bool(true))); - let mut location_config = KdlDocument::new(); - let location_config_nodes = location_config.nodes_mut(); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(scgi_path.to_string()), + ))); + kdl_location.entries.push(kdlite::dom::Entry::new_prop( + "remove_base", + kdlite::dom::Value::Bool(true), + )); + let mut location_config = kdlite::dom::Document::new(); + let location_config_nodes = &mut location_config.nodes; location_config_nodes.push(kdl_scgi); - kdl_location.set_children(location_config); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); } else { kdl_config_nodes.push(kdl_scgi); @@ -626,38 +807,63 @@ pub fn obtain_host_configuration( } for custom_header in custom_headers.iter() { - let mut kdl_property = KdlNode::new("header"); - kdl_property.push(KdlValue::String(custom_header.0.to_string())); - kdl_property.push(KdlValue::String(custom_header.1.to_string())); + let mut kdl_property = kdlite::dom::Node::new("header"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(custom_header.0.to_string()), + ))); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(custom_header.1.to_string()), + ))); kdl_config_nodes.push(kdl_property); } if loaded_modules.contains(&"fcgi".to_string()) { - let mut kdl_fcgi = KdlNode::new("fcgi"); - kdl_fcgi.push(KdlValue::String(fcgi_to.to_string())); + let mut kdl_fcgi = kdlite::dom::Node::new("fcgi"); + kdl_fcgi + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(fcgi_to.to_string()), + ))); let mut kdl_fcgi_extensions = Vec::new(); for value in fcgi_script_extensions { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("fcgi_extension"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("fcgi_extension"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_fcgi_extensions.push(kdl_property); } } if let Some(fcgi_path) = fcgi_path { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(fcgi_path.to_string())); - kdl_location.push(KdlEntry::new_prop("remove_base", KdlValue::Bool(true))); - let mut location_config = KdlDocument::new(); - let location_config_nodes = location_config.nodes_mut(); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(fcgi_path.to_string()), + ))); + kdl_location.entries.push(kdlite::dom::Entry::new_prop( + "remove_base", + kdlite::dom::Value::Bool(true), + )); + let mut location_config = kdlite::dom::Document::new(); + let location_config_nodes = &mut location_config.nodes; location_config_nodes.push(kdl_fcgi); for kdl_fcgi_extension in kdl_fcgi_extensions { kdl_config_nodes.push(kdl_fcgi_extension); } - kdl_location.set_children(location_config); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); } else { - kdl_fcgi.push(KdlEntry::new_prop("pass", KdlValue::Bool(false))); + kdl_fcgi + .entries + .push(kdlite::dom::Entry::new_prop("pass", kdlite::dom::Value::Bool(false))); kdl_config_nodes.push(kdl_fcgi); for kdl_fcgi_extension in kdl_fcgi_extensions { kdl_config_nodes.push(kdl_fcgi_extension); @@ -667,17 +873,28 @@ pub fn obtain_host_configuration( if loaded_modules.contains(&"wsgi".to_string()) { if let Some(wsgi_application_path) = wsgi_application_path { - let mut kdl_wsgi = KdlNode::new("wsgi"); - kdl_wsgi.push(KdlValue::String(wsgi_application_path.to_string())); + let mut kdl_wsgi = kdlite::dom::Node::new("wsgi"); + kdl_wsgi + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(wsgi_application_path.to_string()), + ))); if let Some(wsgi_path) = wsgi_path { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(wsgi_path.to_string())); - kdl_location.push(KdlEntry::new_prop("remove_base", KdlValue::Bool(true))); - let mut location_config = KdlDocument::new(); - let location_config_nodes = location_config.nodes_mut(); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(wsgi_path.to_string()), + ))); + kdl_location.entries.push(kdlite::dom::Entry::new_prop( + "remove_base", + kdlite::dom::Value::Bool(true), + )); + let mut location_config = kdlite::dom::Document::new(); + let location_config_nodes = &mut location_config.nodes; location_config_nodes.push(kdl_wsgi); - kdl_location.set_children(location_config); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); } else { kdl_config_nodes.push(kdl_wsgi); @@ -687,17 +904,28 @@ pub fn obtain_host_configuration( if loaded_modules.contains(&"wsgid".to_string()) { if let Some(wsgid_application_path) = wsgid_application_path { - let mut kdl_wsgid = KdlNode::new("wsgid"); - kdl_wsgid.push(KdlValue::String(wsgid_application_path.to_string())); + let mut kdl_wsgid = kdlite::dom::Node::new("wsgid"); + kdl_wsgid + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(wsgid_application_path.to_string()), + ))); if let Some(wsgid_path) = wsgid_path { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(wsgid_path.to_string())); - kdl_location.push(KdlEntry::new_prop("remove_base", KdlValue::Bool(true))); - let mut location_config = KdlDocument::new(); - let location_config_nodes = location_config.nodes_mut(); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(wsgid_path.to_string()), + ))); + kdl_location.entries.push(kdlite::dom::Entry::new_prop( + "remove_base", + kdlite::dom::Value::Bool(true), + )); + let mut location_config = kdlite::dom::Document::new(); + let location_config_nodes = &mut location_config.nodes; location_config_nodes.push(kdl_wsgid); - kdl_location.set_children(location_config); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); } else { kdl_config_nodes.push(kdl_wsgid); @@ -707,17 +935,28 @@ pub fn obtain_host_configuration( if loaded_modules.contains(&"asgi".to_string()) { if let Some(asgi_application_path) = asgi_application_path { - let mut kdl_asgi = KdlNode::new("asgi"); - kdl_asgi.push(KdlValue::String(asgi_application_path.to_string())); + let mut kdl_asgi = kdlite::dom::Node::new("asgi"); + kdl_asgi + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(asgi_application_path.to_string()), + ))); if let Some(asgi_path) = asgi_path { - let mut kdl_location = KdlNode::new("location"); - kdl_location.push(KdlValue::String(asgi_path.to_string())); - kdl_location.push(KdlEntry::new_prop("remove_base", KdlValue::Bool(true))); - let mut location_config = KdlDocument::new(); - let location_config_nodes = location_config.nodes_mut(); + let mut kdl_location = kdlite::dom::Node::new("location"); + kdl_location + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(asgi_path.to_string()), + ))); + kdl_location.entries.push(kdlite::dom::Entry::new_prop( + "remove_base", + kdlite::dom::Value::Bool(true), + )); + let mut location_config = kdlite::dom::Document::new(); + let location_config_nodes = &mut location_config.nodes; location_config_nodes.push(kdl_asgi); - kdl_location.set_children(location_config); + kdl_location.children = Some(location_config); kdl_config_nodes.insert(0, kdl_location); } else { kdl_config_nodes.push(kdl_asgi); @@ -727,7 +966,7 @@ pub fn obtain_host_configuration( ( kdl_config, - if kdl_secure_config.is_empty() { + if kdl_secure_config.nodes.is_empty() { None } else { Some(kdl_secure_config) @@ -735,12 +974,19 @@ pub fn obtain_host_configuration( ) } -pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec, Vec, u16) { +pub fn obtain_global_configuration( + yaml_configuration: &Yaml, +) -> ( + kdlite::dom::Node<'static>, + Vec>, + Vec, + u16, +) { let empty_hashmap = yaml_rust2::yaml::Hash::new(); let yaml_global_properties = yaml_configuration["global"].as_hash().unwrap_or(&empty_hashmap); - let mut kdl_global_properties = KdlNode::new("*"); - let mut kdl_global_children_to_insert = KdlDocument::new(); - let kdl_global_children_nodes = kdl_global_children_to_insert.nodes_mut(); + let mut kdl_global_properties = kdlite::dom::Node::new("*"); + let mut kdl_global_children_to_insert = kdlite::dom::Document::new(); + let kdl_global_children_nodes = &mut kdl_global_children_to_insert.nodes; let mut sni_configuration = Vec::new(); let mut load_server_modules = Vec::new(); @@ -763,19 +1009,19 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { - let kdl_property = KdlNode::new("cgi"); + let kdl_property = kdlite::dom::Node::new("cgi"); kdl_global_children_nodes.push(kdl_property); } "cache" => { - let kdl_property = KdlNode::new("cache"); + let kdl_property = kdlite::dom::Node::new("cache"); kdl_global_children_nodes.push(kdl_property); } "example" => { - let kdl_property = KdlNode::new("example_handler"); + let kdl_property = kdlite::dom::Node::new("example_handler"); kdl_global_children_nodes.push(kdl_property); } "fproxy" => { - let kdl_property = KdlNode::new("forward_proxy"); + let kdl_property = kdlite::dom::Node::new("forward_proxy"); kdl_global_children_nodes.push(kdl_property); } _ => (), @@ -810,36 +1056,56 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if let Some(http2_setting_value) = http2_setting_value.as_i64() { - let mut kdl_property = KdlNode::new("h2_initial_window_size"); - kdl_property.push(KdlValue::Integer(http2_setting_value as i128)); + let mut kdl_property = kdlite::dom::Node::new("h2_initial_window_size"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + http2_setting_value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } } "maxFrameSize" => { if let Some(http2_setting_value) = http2_setting_value.as_i64() { - let mut kdl_property = KdlNode::new("h2_max_frame_size"); - kdl_property.push(KdlValue::Integer(http2_setting_value as i128)); + let mut kdl_property = kdlite::dom::Node::new("h2_max_frame_size"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + http2_setting_value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } } "maxConcurrentStreams" => { if let Some(http2_setting_value) = http2_setting_value.as_i64() { - let mut kdl_property = KdlNode::new("h2_max_concurrent_streams"); - kdl_property.push(KdlValue::Integer(http2_setting_value as i128)); + let mut kdl_property = kdlite::dom::Node::new("h2_max_concurrent_streams"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + http2_setting_value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } } "maxHeaderListSize" => { if let Some(http2_setting_value) = http2_setting_value.as_i64() { - let mut kdl_property = KdlNode::new("h2_max_header_list_size"); - kdl_property.push(KdlValue::Integer(http2_setting_value as i128)); + let mut kdl_property = kdlite::dom::Node::new("h2_max_header_list_size"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + http2_setting_value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } } "enableConnectProtocol" => { if let Some(http2_setting_value) = http2_setting_value.as_bool() { - let mut kdl_property = KdlNode::new("h2_enable_connect_protocol"); - kdl_property.push(KdlValue::Bool(http2_setting_value)); + let mut kdl_property = kdlite::dom::Node::new("h2_enable_connect_protocol"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool( + http2_setting_value, + ))); kdl_global_children_nodes.push(kdl_property); } } @@ -851,15 +1117,23 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("log"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("log"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } "errorLogFilePath" => { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("error_log"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("error_log"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } @@ -889,23 +1163,30 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec (KdlNode, Vec { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("tls_client_certificate"); - kdl_property.push(KdlValue::Bool(value)); + let mut kdl_property = kdlite::dom::Node::new("tls_client_certificate"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(value))); kdl_global_children_nodes.push(kdl_property); } } @@ -924,8 +1207,12 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec (KdlNode, Vec (KdlNode, Vec { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("tls_min_version"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("tls_min_version"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } "tlsMaxVersion" => { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("tls_max_version"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("tls_max_version"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } @@ -965,8 +1264,12 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec (KdlNode, Vec { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("ocsp_stapling"); - kdl_property.push(KdlValue::Bool(value)); + let mut kdl_property = kdlite::dom::Node::new("ocsp_stapling"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(value))); kdl_global_children_nodes.push(kdl_property); } } @@ -997,54 +1302,74 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("auto_tls_contact"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("auto_tls_contact"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } "automaticTLSContactCacheDirectory" => { if let Some(value) = value.as_str() { - let mut kdl_property = KdlNode::new("auto_tls_cache"); - kdl_property.push(KdlValue::String(value.to_string())); + let mut kdl_property = kdlite::dom::Node::new("auto_tls_cache"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(value.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } "automaticTLSLetsEncryptProduction" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("auto_tls_letsencrypt_production"); + let mut kdl_property = kdlite::dom::Node::new("auto_tls_letsencrypt_production"); if !value { - kdl_property.push(KdlValue::Bool(false)); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(false))); } kdl_global_children_nodes.push(kdl_property); } } "useAutomaticTLSHTTPChallenge" => { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("auto_tls_challenge"); - kdl_property.push(KdlValue::String(if value { - "http-01".to_string() - } else { - "tls-alpn-01".to_string() - })); + let mut kdl_property = kdlite::dom::Node::new("auto_tls_challenge"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::String( + std::borrow::Cow::Owned(if value { "http-01" } else { "tls-alpn-01" }.to_string()), + ))); kdl_global_children_nodes.push(kdl_property); } } "timeout" => { if let Some(value) = value.as_i64() { - let mut kdl_property = KdlNode::new("timeout"); - kdl_property.push(KdlValue::Integer(value as i128)); + let mut kdl_property = kdlite::dom::Node::new("timeout"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } else if value.is_null() { - let mut kdl_property = KdlNode::new("timeout"); - kdl_property.push(KdlValue::Null); + let mut kdl_property = kdlite::dom::Node::new("timeout"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Null)); kdl_global_children_nodes.push(kdl_property); } } "loadBalancerHealthCheckWindow" => { if load_server_modules.contains(&"rproxy".to_string()) { if let Some(value) = value.as_i64() { - let mut kdl_property = KdlNode::new("lb_health_check_window"); - kdl_property.push(KdlValue::Integer(value as i128)); + let mut kdl_property = kdlite::dom::Node::new("lb_health_check_window"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } } @@ -1052,12 +1377,18 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if load_server_modules.contains(&"cache".to_string()) { if let Some(value) = value.as_i64() { - let mut kdl_property = KdlNode::new("cache_max_entries"); - kdl_property.push(KdlValue::Integer(value as i128)); + let mut kdl_property = kdlite::dom::Node::new("cache_max_entries"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Integer( + value as i128, + ))); kdl_global_children_nodes.push(kdl_property); } else if value.is_null() { - let mut kdl_property = KdlNode::new("cache_max_entries"); - kdl_property.push(KdlValue::Null); + let mut kdl_property = kdlite::dom::Node::new("cache_max_entries"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Null)); kdl_global_children_nodes.push(kdl_property); } } @@ -1065,8 +1396,10 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if load_server_modules.contains(&"wsgi".to_string()) { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("wsgi_clear_imports"); - kdl_property.push(KdlValue::Bool(value)); + let mut kdl_property = kdlite::dom::Node::new("wsgi_clear_imports"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(value))); kdl_global_children_nodes.push(kdl_property); } } @@ -1074,8 +1407,10 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec { if load_server_modules.contains(&"asgi".to_string()) { if let Some(value) = value.as_bool() { - let mut kdl_property = KdlNode::new("asgi_clear_imports"); - kdl_property.push(KdlValue::Bool(value)); + let mut kdl_property = kdlite::dom::Node::new("asgi_clear_imports"); + kdl_property + .entries + .push(kdlite::dom::Entry::new_value(kdlite::dom::Value::Bool(value))); kdl_global_children_nodes.push(kdl_property); } } @@ -1085,84 +1420,146 @@ pub fn obtain_global_configuration(yaml_configuration: &Yaml) -> (KdlNode, Vec ServerConfigurationEntry { +fn kdlite_error_near(pos: usize, file_contents: &str) -> String { + let part = file_contents + .split_at_checked(pos) + .map(|split| split.1.split_at_checked(50).map_or(split.1, |split2| split2.0)) + .and_then(|part| if part.is_empty() { None } else { Some(part) }); + part.map_or("".to_string(), |p| { + snailquote::escape(p).to_string() + }) +} + +fn display_kdlite_error(err: &kdlite::stream::Error, file_contents: &str) -> String { + match err { + kdlite::stream::Error::ExpectedSpace(index) => { + format!("Expected space near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::ExpectedCloseParen(index) => { + format!("Expected `)` near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::ExpectedComment(index) => format!( + "Expected single-line comment near {}", + kdlite_error_near(*index, file_contents) + ), + kdlite::stream::Error::ExpectedNewline(index) => { + format!("Expected newline near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::ExpectedString(index) => { + format!("Expected string near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::ExpectedValue(index) => { + format!("Expected value near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::UnexpectedCloseBracket(index) => { + format!("Unexpected `}}` near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::UnexpectedNewline(index) => { + format!("Unexpected newline near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::InvalidNumber(index) => { + format!("Invalid number near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::BadKeyword(index) => { + format!("Invalid keyword name near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::BadIdentifier(index) => format!( + "Invalid identifier name near {}", + kdlite_error_near(*index, file_contents) + ), + kdlite::stream::Error::BadEscape(index) => format!( + "Invalid escape sequence near {}", + kdlite_error_near(*index, file_contents) + ), + kdlite::stream::Error::BadIndent(index) => { + format!("Invalid indentation near {}", kdlite_error_near(*index, file_contents)) + } + kdlite::stream::Error::MultipleChildren(index) => format!( + "Multiple children for one KDL node near {}", + kdlite_error_near(*index, file_contents) + ), + kdlite::stream::Error::UnexpectedEof => "Unexpected end of file".to_string(), + kdlite::stream::Error::BannedChar(ch, index) => format!( + "Invalid character `{}` near {}", + ch.escape_default(), + kdlite_error_near(*index, file_contents) + ), + _ => "Unknown error".to_string(), + } +} + +fn kdl_node_to_configuration_entry(kdl_node: &kdlite::dom::Node) -> ServerConfigurationEntry { let mut values = Vec::new(); let mut props = HashMap::new(); - for kdl_entry in kdl_node.iter() { - let value = match kdl_entry.value().to_owned() { - KdlValue::String(value) => ServerConfigurationValue::String(value), - KdlValue::Integer(value) => ServerConfigurationValue::Integer(value), - KdlValue::Float(value) => ServerConfigurationValue::Float(value), - KdlValue::Bool(value) => ServerConfigurationValue::Bool(value), - KdlValue::Null => ServerConfigurationValue::Null, + for kdl_entry in &kdl_node.entries { + let value = match &kdl_entry.value { + kdlite::dom::Value::String(value) => ServerConfigurationValue::String(value.to_string()), + kdlite::dom::Value::Integer(value) => ServerConfigurationValue::Integer(*value), + kdlite::dom::Value::Float(value) => ServerConfigurationValue::Float(*value), + kdlite::dom::Value::Bool(value) => ServerConfigurationValue::Bool(*value), + kdlite::dom::Value::Null => ServerConfigurationValue::Null, }; - if let Some(prop_name) = kdl_entry.name() { - props.insert(prop_name.value().to_string(), value); + if let Some(prop_name) = kdl_entry.key() { + props.insert(prop_name.to_string(), value); } else { values.push(value); } @@ -76,15 +143,12 @@ fn load_configuration_inner( }; // Parse the configuration file contents - let kdl_document: KdlDocument = match file_contents.parse() { + let kdl_document = match kdlite::dom::Document::parse(&file_contents) { Ok(document) => document, - Err(err) => { - let err: miette::Error = err.into(); - Err(anyhow::anyhow!( - "Failed to parse the server configuration file: {:?}", - err - ))? - } + Err(err) => Err(anyhow::anyhow!( + "Failed to parse the server configuration file: {}", + display_kdlite_error(&err, &file_contents) + ))?, }; // Loaded configuration vector @@ -94,14 +158,17 @@ fn load_configuration_inner( let mut loaded_conditions: HashMap> = HashMap::new(); // KDL configuration snippets - let mut snippets: HashMap = HashMap::new(); + let mut snippets: HashMap = HashMap::new(); // Iterate over KDL nodes - for kdl_node in kdl_document { - let global_name = kdl_node.name().value(); - let children = kdl_node.children(); + for kdl_node in &kdl_document.nodes { + let global_name = kdl_node.name(); + let children = &kdl_node.children; if global_name == "snippet" { - if let Some(snippet_name) = kdl_node.get(0).and_then(|v| v.as_string()) { + if let Some(snippet_name) = kdl_node.entry(0).and_then(|v| match &v.value { + kdlite::dom::Value::String(v) => Some(&**v), + _ => None, + }) { if let Some(children) = children { snippets.insert(snippet_name.to_string(), children.to_owned()); } else { @@ -162,26 +229,29 @@ fn load_configuration_inner( }; let mut configuration_entries: HashMap = HashMap::new(); - for kdl_node in children.nodes() { + for kdl_node in &children.nodes { #[allow(clippy::too_many_arguments)] fn kdl_iterate_fn( canonical_pathbuf: &PathBuf, host_filter: &(Option, Option, Option, bool), configurations: &mut Vec, configuration_entries: &mut HashMap, - kdl_node: &KdlNode, + kdl_node: &kdlite::dom::Node, conditions: &mut Option<&mut Conditions>, is_error_config: bool, loaded_conditions: &mut HashMap>, - snippets: &HashMap, + snippets: &HashMap, ) -> Result<(), Box> { let (hostname, ip, port, is_host) = host_filter; - let kdl_node_name = kdl_node.name().value(); - let children = kdl_node.children(); + let kdl_node_name = kdl_node.name(); + let children = &kdl_node.children; if kdl_node_name == "use" { - if let Some(snippet_name) = kdl_node.entry(0).and_then(|e| e.value().as_string()) { + if let Some(snippet_name) = kdl_node.entry(0).and_then(|e| match &e.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + }) { if let Some(snippet) = snippets.get(snippet_name) { - for kdl_node in snippet.nodes() { + for kdl_node in &snippet.nodes { kdl_iterate_fn( canonical_pathbuf, host_filter, @@ -213,13 +283,16 @@ fn load_configuration_inner( let mut configuration_entries: HashMap = HashMap::new(); if let Some(children) = children { if let Some(location) = kdl_node.entry(0) { - if let Some(location_str) = location.value().as_string() { + if let Some(location_str) = match &location.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { let mut conditions = Conditions { location_prefix: location_str.to_string(), conditionals: vec![], }; let mut loaded_conditions = loaded_conditions.clone(); - for kdl_node in children.nodes() { + for kdl_node in &children.nodes { kdl_iterate_fn( canonical_pathbuf, host_filter, @@ -234,7 +307,10 @@ fn load_configuration_inner( } if kdl_node .entry("remove_base") - .and_then(|e| e.value().as_bool()) + .and_then(|e| match &e.value { + kdlite::dom::Value::Bool(b) => Some(*b), + _ => None, + }) .unwrap_or(false) { configuration_entries.insert( @@ -284,11 +360,14 @@ fn load_configuration_inner( } if let Some(children) = children { if let Some(condition_name) = kdl_node.entry(0) { - if let Some(condition_name_str) = condition_name.value().as_string() { + if let Some(condition_name_str) = match &condition_name.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { let mut conditions_data = Vec::new(); let mut nodes_stack = Vec::new(); - nodes_stack.push(children.nodes().iter()); + nodes_stack.push(children.nodes.iter()); while let Some(kdl_node) = { let mut last_iterator_item = None; @@ -300,11 +379,14 @@ fn load_configuration_inner( } last_iterator_item } { - let name = kdl_node.name().value(); + let name = kdl_node.name(); if name == "use" { - if let Some(snippet_name) = kdl_node.get(0).and_then(|v| v.as_string()) { + if let Some(snippet_name) = kdl_node.entry(0).and_then(|v| match &v.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + }) { if let Some(snippet) = snippets.get(snippet_name) { - nodes_stack.push(snippet.nodes().iter()); + nodes_stack.push(snippet.nodes.iter()); continue; } else { Err(anyhow::anyhow!( @@ -350,7 +432,10 @@ fn load_configuration_inner( let mut configuration_entries: HashMap = HashMap::new(); if let Some(children) = children { if let Some(condition_name) = kdl_node.entry(0) { - if let Some(condition_name_str) = condition_name.value().as_string() { + if let Some(condition_name_str) = match &condition_name.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { let mut new_conditions = if let Some(conditions) = conditions { conditions.clone() } else { @@ -369,7 +454,7 @@ fn load_configuration_inner( } let mut loaded_conditions = loaded_conditions.clone(); - for kdl_node in children.nodes() { + for kdl_node in &children.nodes { kdl_iterate_fn( canonical_pathbuf, host_filter, @@ -421,7 +506,10 @@ fn load_configuration_inner( let mut configuration_entries: HashMap = HashMap::new(); if let Some(children) = children { if let Some(condition_name) = kdl_node.entry(0) { - if let Some(condition_name_str) = condition_name.value().as_string() { + if let Some(condition_name_str) = match &condition_name.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { let mut new_conditions = if let Some(conditions) = conditions { conditions.clone() } else { @@ -442,7 +530,7 @@ fn load_configuration_inner( } let mut loaded_conditions = loaded_conditions.clone(); - for kdl_node in children.nodes() { + for kdl_node in &children.nodes { kdl_iterate_fn( canonical_pathbuf, host_filter, @@ -494,9 +582,12 @@ fn load_configuration_inner( let mut configuration_entries: HashMap = HashMap::new(); if let Some(children) = children { if let Some(error_status_code) = kdl_node.entry(0) { - if let Some(error_status_code) = error_status_code.value().as_integer() { + if let Some(error_status_code) = match &error_status_code.value { + kdlite::dom::Value::Integer(i) => Some(*i), + _ => None, + } { let mut loaded_conditions = loaded_conditions.clone(); - for kdl_node in children.nodes() { + for kdl_node in &children.nodes { kdl_iterate_fn( canonical_pathbuf, host_filter, @@ -531,8 +622,8 @@ fn load_configuration_inner( ))? } } else { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); + for kdl_node in &children.nodes { + let kdl_node_name = kdl_node.name(); let value = kdl_node_to_configuration_entry(kdl_node); if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { entries.inner.push(value); @@ -608,11 +699,14 @@ fn load_configuration_inner( } else if global_name == "include" { // Get the list of included files and include the configurations let mut include_files = Vec::new(); - for include_one in kdl_node.entries() { - if include_one.name().is_some() { + for include_one in &kdl_node.entries { + if include_one.key().is_some() { continue; } - if let Some(include_glob) = include_one.value().as_string() { + if let Some(include_glob) = match &include_one.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { let include_glob_pathbuf = match PathBuf::from_str(include_glob) { Ok(pathbuf) => pathbuf, Err(err) => { diff --git a/ferron/src/config/adapters/yaml_legacy.rs b/ferron/src/config/adapters/yaml_legacy.rs index 4f21488d..fbc787f1 100644 --- a/ferron/src/config/adapters/yaml_legacy.rs +++ b/ferron/src/config/adapters/yaml_legacy.rs @@ -7,7 +7,6 @@ use std::{ use ferron_common::observability::ObservabilityBackendChannels; use ferron_yaml2kdl_core::convert_yaml_to_kdl; -use kdl::{KdlDocument, KdlNode, KdlValue}; use crate::config::{ Conditions, ErrorHandlerStatus, ServerConfiguration, ServerConfigurationEntries, ServerConfigurationEntry, @@ -16,19 +15,19 @@ use crate::config::{ use super::ConfigurationAdapter; -fn kdl_node_to_configuration_entry(kdl_node: &KdlNode) -> ServerConfigurationEntry { +fn kdl_node_to_configuration_entry(kdl_node: &kdlite::dom::Node) -> ServerConfigurationEntry { let mut values = Vec::new(); let mut props = HashMap::new(); - for kdl_entry in kdl_node.iter() { - let value = match kdl_entry.value().to_owned() { - KdlValue::String(value) => ServerConfigurationValue::String(value), - KdlValue::Integer(value) => ServerConfigurationValue::Integer(value), - KdlValue::Float(value) => ServerConfigurationValue::Float(value), - KdlValue::Bool(value) => ServerConfigurationValue::Bool(value), - KdlValue::Null => ServerConfigurationValue::Null, + for kdl_entry in &kdl_node.entries { + let value = match &kdl_entry.value { + kdlite::dom::Value::String(value) => ServerConfigurationValue::String(value.to_string()), + kdlite::dom::Value::Integer(value) => ServerConfigurationValue::Integer(*value), + kdlite::dom::Value::Float(value) => ServerConfigurationValue::Float(*value), + kdlite::dom::Value::Bool(value) => ServerConfigurationValue::Bool(*value), + kdlite::dom::Value::Null => ServerConfigurationValue::Null, }; - if let Some(prop_name) = kdl_entry.name() { - props.insert(prop_name.value().to_string(), value); + if let Some(prop_name) = kdl_entry.key() { + props.insert(prop_name.to_string(), value); } else { values.push(value); } @@ -53,7 +52,7 @@ impl YamlLegacyConfigurationAdapter { impl ConfigurationAdapter for YamlLegacyConfigurationAdapter { fn load_configuration(&self, path: &Path) -> Result, Box> { // Read and parse the configuration file contents - let kdl_document: KdlDocument = match convert_yaml_to_kdl(path.to_path_buf()) { + let kdl_document: kdlite::dom::Document = match convert_yaml_to_kdl(path.to_path_buf()) { Ok(document) => document, Err(err) => Err(anyhow::anyhow!( "Failed to read and parse the server configuration file: {}", @@ -65,12 +64,12 @@ impl ConfigurationAdapter for YamlLegacyConfigurationAdapter { let mut configurations = Vec::new(); // Iterate over KDL nodes - for kdl_node in kdl_document { - let global_name = kdl_node.name().value(); - let children = kdl_node.children(); + for kdl_node in &kdl_document.nodes { + let global_name = kdl_node.name(); + let children = &kdl_node.children; if let Some(children) = children { for global_name in global_name.split(",") { - let (hostname, ip, port, is_host) = if global_name == "globals" { + let host_filter = if global_name == "globals" { (None, None, None, false) } else if let Ok(socket_addr) = global_name.parse::() { (None, Some(socket_addr.ip()), Some(socket_addr.port()), true) @@ -118,147 +117,128 @@ impl ConfigurationAdapter for YamlLegacyConfigurationAdapter { }; let mut configuration_entries: HashMap = HashMap::new(); - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); - let children = kdl_node.children(); - if kdl_node_name == "location" { - let mut configuration_entries: HashMap = HashMap::new(); - if let Some(children) = children { - if let Some(location) = kdl_node.entry(0) { - if let Some(location_str) = location.value().as_string() { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); - let children = kdl_node.children(); - if kdl_node_name == "error_config" { - let mut configuration_entries: HashMap = HashMap::new(); - if let Some(children) = children { - if let Some(error_status_code) = kdl_node.entry(0) { - if let Some(error_status_code) = error_status_code.value().as_integer() { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); - let value = kdl_node_to_configuration_entry(kdl_node); - if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { - entries.inner.push(value); - } else { - configuration_entries.insert( - kdl_node_name.to_string(), - ServerConfigurationEntries { inner: vec![value] }, - ); - } - } - configurations.push(ServerConfiguration { - entries: configuration_entries, - filters: ServerConfigurationFilters { - is_host, - hostname: hostname.clone(), - ip, - port, - condition: Some(Conditions { - location_prefix: location_str.to_string(), - conditionals: vec![], - }), - error_handler_status: Some(ErrorHandlerStatus::Status(error_status_code as u16)), - }, - modules: vec![], - observability: ObservabilityBackendChannels::new(), - }); - } else { - Err(anyhow::anyhow!("Invalid error handler status code"))? - } - } else { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); - let value = kdl_node_to_configuration_entry(kdl_node); - if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { - entries.inner.push(value); - } else { - configuration_entries.insert( - kdl_node_name.to_string(), - ServerConfigurationEntries { inner: vec![value] }, - ); - } - } - configurations.push(ServerConfiguration { - entries: configuration_entries, - filters: ServerConfigurationFilters { - is_host, - hostname: hostname.clone(), - ip, - port, - condition: Some(Conditions { - location_prefix: location_str.to_string(), - conditionals: vec![], - }), - error_handler_status: Some(ErrorHandlerStatus::Any), - }, - modules: vec![], - observability: ObservabilityBackendChannels::new(), - }); - } - } else { - Err(anyhow::anyhow!( - "Error handler blocks should have children, but they don't" - ))? - } - } else { - let value = kdl_node_to_configuration_entry(kdl_node); - if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { - entries.inner.push(value); - } else { - configuration_entries.insert( - kdl_node_name.to_string(), - ServerConfigurationEntries { inner: vec![value] }, - ); - } + for kdl_node in &children.nodes { + #[allow(clippy::too_many_arguments)] + fn kdl_iterate_fn( + host_filter: &(Option, Option, Option, bool), + configurations: &mut Vec, + configuration_entries: &mut HashMap, + kdl_node: &kdlite::dom::Node, + conditions: &mut Option<&mut Conditions>, + is_error_config: bool, + ) -> Result<(), Box> { + let (hostname, ip, port, is_host) = host_filter; + let kdl_node_name = kdl_node.name(); + let children = &kdl_node.children; + if kdl_node_name == "location" { + if is_error_config { + Err(anyhow::anyhow!("Locations in error configurations aren't allowed"))?; + } else if conditions.is_some() { + Err(anyhow::anyhow!( + "Nested locations and locations in conditions aren't allowed" + ))?; + } + let mut configuration_entries: HashMap = HashMap::new(); + if let Some(children) = children { + if let Some(location) = kdl_node.entry(0) { + if let Some(location_str) = match &location.value { + kdlite::dom::Value::String(s) => Some(&**s), + _ => None, + } { + let mut conditions = Conditions { + location_prefix: location_str.to_string(), + conditionals: vec![], + }; + for kdl_node in &children.nodes { + kdl_iterate_fn( + host_filter, + configurations, + &mut configuration_entries, + kdl_node, + &mut Some(&mut conditions), + is_error_config, + )?; } - } - if kdl_node - .entry("remove_base") - .and_then(|e| e.value().as_bool()) - .unwrap_or(false) - { - configuration_entries.insert( - "UNDOCUMENTED_REMOVE_PATH_PREFIX".to_string(), - ServerConfigurationEntries { - inner: vec![ServerConfigurationEntry { - values: vec![ServerConfigurationValue::String(location_str.to_string())], - props: HashMap::new(), - }], + if kdl_node + .entry("remove_base") + .and_then(|e| match &e.value { + kdlite::dom::Value::Bool(b) => Some(*b), + _ => None, + }) + .unwrap_or(false) + { + configuration_entries.insert( + "UNDOCUMENTED_REMOVE_PATH_PREFIX".to_string(), + ServerConfigurationEntries { + inner: vec![ServerConfigurationEntry { + values: vec![ServerConfigurationValue::String(location_str.to_string())], + props: HashMap::new(), + }], + }, + ); + } + configurations.push(ServerConfiguration { + entries: configuration_entries, + filters: ServerConfigurationFilters { + is_host: *is_host, + hostname: hostname.clone(), + ip: *ip, + port: *port, + condition: Some(conditions), + error_handler_status: None, }, - ); + modules: vec![], + observability: ObservabilityBackendChannels::new(), + }); + } else { + Err(anyhow::anyhow!("Invalid location path"))? } - configurations.push(ServerConfiguration { - entries: configuration_entries, - filters: ServerConfigurationFilters { - is_host, - hostname: hostname.clone(), - ip, - port, - condition: Some(Conditions { - location_prefix: location_str.to_string(), - conditionals: vec![], - }), - error_handler_status: None, - }, - modules: vec![], - observability: ObservabilityBackendChannels::new(), - }); } else { - Err(anyhow::anyhow!("Invalid location path"))? + Err(anyhow::anyhow!("Invalid location"))? } } else { - Err(anyhow::anyhow!("Invalid location"))? + Err(anyhow::anyhow!("Locations should have children, but they don't"))? } - } else { - Err(anyhow::anyhow!("Locations should have children, but they don't"))? - } - } else if kdl_node_name == "error_config" { - let mut configuration_entries: HashMap = HashMap::new(); - if let Some(children) = children { - if let Some(error_status_code) = kdl_node.entry(0) { - if let Some(error_status_code) = error_status_code.value().as_integer() { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); + } else if kdl_node_name == "error_config" { + if is_error_config { + Err(anyhow::anyhow!("Nested error configurations aren't allowed"))?; + } + let mut configuration_entries: HashMap = HashMap::new(); + if let Some(children) = children { + if let Some(error_status_code) = kdl_node.entry(0) { + if let Some(error_status_code) = match &error_status_code.value { + kdlite::dom::Value::Integer(i) => Some(*i), + _ => None, + } { + for kdl_node in &children.nodes { + kdl_iterate_fn( + host_filter, + configurations, + &mut configuration_entries, + kdl_node, + conditions, + true, + )?; + } + configurations.push(ServerConfiguration { + entries: configuration_entries, + filters: ServerConfigurationFilters { + is_host: *is_host, + hostname: hostname.clone(), + ip: *ip, + port: *port, + condition: None, + error_handler_status: Some(ErrorHandlerStatus::Status(error_status_code as u16)), + }, + modules: vec![], + observability: ObservabilityBackendChannels::new(), + }); + } else { + Err(anyhow::anyhow!("Invalid error handler status code"))? + } + } else { + for kdl_node in &children.nodes { + let kdl_node_name = kdl_node.name(); let value = kdl_node_to_configuration_entry(kdl_node); if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { entries.inner.push(value); @@ -272,63 +252,45 @@ impl ConfigurationAdapter for YamlLegacyConfigurationAdapter { configurations.push(ServerConfiguration { entries: configuration_entries, filters: ServerConfigurationFilters { - is_host, + is_host: *is_host, hostname: hostname.clone(), - ip, - port, + ip: *ip, + port: *port, condition: None, - error_handler_status: Some(ErrorHandlerStatus::Status(error_status_code as u16)), + error_handler_status: Some(ErrorHandlerStatus::Any), }, modules: vec![], observability: ObservabilityBackendChannels::new(), }); - } else { - Err(anyhow::anyhow!("Invalid error handler status code"))? } } else { - for kdl_node in children.nodes() { - let kdl_node_name = kdl_node.name().value(); - let value = kdl_node_to_configuration_entry(kdl_node); - if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { - entries.inner.push(value); - } else { - configuration_entries.insert( - kdl_node_name.to_string(), - ServerConfigurationEntries { inner: vec![value] }, - ); - } - } - configurations.push(ServerConfiguration { - entries: configuration_entries, - filters: ServerConfigurationFilters { - is_host, - hostname: hostname.clone(), - ip, - port, - condition: None, - error_handler_status: Some(ErrorHandlerStatus::Any), - }, - modules: vec![], - observability: ObservabilityBackendChannels::new(), - }); + Err(anyhow::anyhow!( + "Error handler blocks should have children, but they don't" + ))? } } else { - Err(anyhow::anyhow!( - "Error handler blocks should have children, but they don't" - ))? - } - } else { - let value = kdl_node_to_configuration_entry(kdl_node); - if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { - entries.inner.push(value); - } else { - configuration_entries.insert( - kdl_node_name.to_string(), - ServerConfigurationEntries { inner: vec![value] }, - ); + let value = kdl_node_to_configuration_entry(kdl_node); + if let Some(entries) = configuration_entries.get_mut(kdl_node_name) { + entries.inner.push(value); + } else { + configuration_entries.insert( + kdl_node_name.to_string(), + ServerConfigurationEntries { inner: vec![value] }, + ); + } } + Ok(()) } + kdl_iterate_fn( + &host_filter, + &mut configurations, + &mut configuration_entries, + kdl_node, + &mut None, + false, + )?; } + let (hostname, ip, port, is_host) = host_filter; configurations.push(ServerConfiguration { entries: configuration_entries, filters: ServerConfigurationFilters { @@ -344,7 +306,6 @@ impl ConfigurationAdapter for YamlLegacyConfigurationAdapter { }); } } else { - // "include" directives aren't generated by `ferron-yaml2kdl-core` Err(anyhow::anyhow!("Invalid top-level directive"))? } }