use std::collections::HashSet;
use url::Url;
pub struct HostValidator {
domains: HashSet<String>,
}
impl HostValidator {
pub fn new(domains: &[String]) -> Self {
let normalized_domains: HashSet<String> = domains
.iter()
.map(|domain| domain.trim().to_lowercase())
.collect();
HostValidator {
domains: normalized_domains,
}
}
pub fn is_valid_host(&self, url_str: &str) -> bool {
if let Ok(url) = Url::parse(url_str) {
if let Some(host) = url.host_str() {
let normalized_host = host.to_lowercase();
return self.domains.contains(&normalized_host);
}
}
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_host_validation() {
let domains = vec!["example.com".to_string(), "test.org".to_string()];
let validator = HostValidator::new(&domains);
assert!(validator.is_valid_host("https://example.com/path"));
assert!(validator.is_valid_host("http://example.com"));
assert!(validator.is_valid_host("https://test.org/page?query=value"));
assert!(!validator.is_valid_host("https://example.com.")); assert!(!validator.is_valid_host("https://.example.com")); assert!(!validator.is_valid_host("https://-example.com")); assert!(!validator.is_valid_host("https://example-.com"));
assert!(!validator.is_valid_host("file:///path/to/file"));
assert!(!validator.is_valid_host("mailto:user@example.com"));
assert!(!validator.is_valid_host("data:text/plain,Hello%20World"));
assert!(!validator.is_valid_host("https://"));
assert!(!validator.is_valid_host("http://"));
assert!(!validator.is_valid_host("not-a-url"));
}
}