Settings hot reloading - Part 2
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user