87 lines
2.6 KiB
Rust
87 lines
2.6 KiB
Rust
/// Match a domain against a pattern supporting wildcards.
|
|
///
|
|
/// Supported patterns:
|
|
/// - `*` matches any domain
|
|
/// - `*.example.com` matches any subdomain of example.com
|
|
/// - `example.com` exact match
|
|
/// - `**.example.com` matches any depth of subdomain
|
|
pub fn domain_matches(pattern: &str, domain: &str) -> bool {
|
|
let pattern = pattern.trim().to_lowercase();
|
|
let domain = domain.trim().to_lowercase();
|
|
|
|
if pattern == "*" {
|
|
return true;
|
|
}
|
|
|
|
if pattern == domain {
|
|
return true;
|
|
}
|
|
|
|
// Wildcard patterns
|
|
if pattern.starts_with("*.") {
|
|
let suffix = &pattern[2..]; // e.g., "example.com"
|
|
// Match exact parent or any single-level subdomain
|
|
if domain == suffix {
|
|
return true;
|
|
}
|
|
if domain.ends_with(&format!(".{}", suffix)) {
|
|
// Check it's a single level subdomain for `*.`
|
|
let prefix = &domain[..domain.len() - suffix.len() - 1];
|
|
return !prefix.contains('.');
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if pattern.starts_with("**.") {
|
|
let suffix = &pattern[3..];
|
|
// Match exact parent or any depth of subdomain
|
|
return domain == suffix || domain.ends_with(&format!(".{}", suffix));
|
|
}
|
|
|
|
// Use glob-match for more complex patterns
|
|
glob_match::glob_match(&pattern, &domain)
|
|
}
|
|
|
|
/// Check if a domain matches any of the given patterns.
|
|
pub fn domain_matches_any(patterns: &[&str], domain: &str) -> bool {
|
|
patterns.iter().any(|p| domain_matches(p, domain))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_exact_match() {
|
|
assert!(domain_matches("example.com", "example.com"));
|
|
assert!(!domain_matches("example.com", "other.com"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_wildcard_all() {
|
|
assert!(domain_matches("*", "anything.com"));
|
|
assert!(domain_matches("*", "sub.domain.example.com"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_wildcard_subdomain() {
|
|
assert!(domain_matches("*.example.com", "www.example.com"));
|
|
assert!(domain_matches("*.example.com", "api.example.com"));
|
|
assert!(domain_matches("*.example.com", "example.com"));
|
|
assert!(!domain_matches("*.example.com", "deep.sub.example.com"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_double_wildcard() {
|
|
assert!(domain_matches("**.example.com", "www.example.com"));
|
|
assert!(domain_matches("**.example.com", "deep.sub.example.com"));
|
|
assert!(domain_matches("**.example.com", "example.com"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_case_insensitive() {
|
|
assert!(domain_matches("Example.COM", "example.com"));
|
|
assert!(domain_matches("*.EXAMPLE.com", "WWW.example.COM"));
|
|
}
|
|
}
|