Settings hot reloading - Part 2

This commit is contained in:
mdecimus
2024-03-22 20:16:02 +01:00
parent 333a0d5a1b
commit 5756815e3e
48 changed files with 7261 additions and 104 deletions

View File

@@ -894,6 +894,16 @@ impl AsKey for String {
}
}
impl AsKey for &String {
fn as_key(&self) -> String {
self.to_string()
}
fn as_prefix(&self) -> String {
format!("{self}.")
}
}
impl AsKey for (&str, &str) {
fn as_key(&self) -> String {
format!("{}.{}", self.0, self.1)
@@ -904,6 +914,16 @@ impl AsKey for (&str, &str) {
}
}
impl AsKey for (&str, &String) {
fn as_key(&self) -> String {
format!("{}.{}", self.0, self.1)
}
fn as_prefix(&self) -> String {
format!("{}.{}.", self.0, self.1)
}
}
impl AsKey for (&String, &str) {
fn as_key(&self) -> String {
format!("{}.{}", self.0, self.1)

View File

@@ -21,7 +21,12 @@
* for more details.
*/
use std::io::Read;
use ahash::AHashSet;
use mail_auth::flate2::read::GzDecoder;
use crate::config::Config;
#[derive(Debug, Clone, Default)]
pub struct PublicSuffix {
@@ -57,3 +62,108 @@ impl From<&str> for PublicSuffix {
ps
}
}
impl PublicSuffix {
pub async fn parse(config: &mut Config, key: &str) -> PublicSuffix {
let values = config
.values(key)
.map(|(_, s)| s.to_string())
.collect::<Vec<_>>();
let has_values = !values.is_empty();
for (idx, value) in values.into_iter().enumerate() {
let bytes = if value.starts_with("https://") || value.starts_with("http://") {
let result = match reqwest::get(&value).await {
Ok(r) => {
if r.status().is_success() {
r.bytes().await
} else {
config.new_build_error(
format!("{value}.{idx}"),
format!(
"Failed to fetch public suffixes from {value:?}: Status {status}",
value = value,
status = r.status()
),
);
continue;
}
}
Err(err) => Err(err),
};
match result {
Ok(bytes) => bytes.to_vec(),
Err(err) => {
config.new_build_error(
format!("{value}.{idx}"),
format!("Failed to fetch public suffixes from {value:?}: {err}",),
);
continue;
}
}
} else if let Some(filename) = value.strip_prefix("file://") {
match std::fs::read(filename) {
Ok(bytes) => bytes,
Err(err) => {
config.new_build_error(
format!("{value}.{idx}"),
format!("Failed to read public suffixes from {value:?}: {err}",),
);
continue;
}
}
} else {
config.new_parse_error(key, format!("Invalid public suffix file {value:?}"));
continue;
};
let bytes = if value.ends_with(".gz") {
match GzDecoder::new(&bytes[..])
.bytes()
.collect::<Result<Vec<_>, _>>()
{
Ok(bytes) => bytes,
Err(err) => {
config.new_build_error(
format!("{value}.{idx}"),
format!(
"Failed to decompress public suffixes from {value:?}: {err}",
value = value,
err = err
),
);
continue;
}
}
} else {
bytes
};
match String::from_utf8(bytes) {
Ok(list) => {
return PublicSuffix::from(list.as_str());
}
Err(err) => {
config.new_build_error(
format!("{value}.{idx}"),
format!(
"Failed to parse public suffixes from {value:?}: {err}",
value = value,
err = err
),
);
}
}
}
config.new_build_error(
key,
if has_values {
"Failed to parse public suffixes from any source."
} else {
"No public suffixes list was specified."
},
);
PublicSuffix::default()
}
}