pub fn is_domain_name(host: &str) -> bool {
if host.is_empty() {
return false;
}
if host.starts_with('$') {
return false;
}
if host.starts_with("unix:") {
return false;
}
if host.starts_with('[') && host.contains(']') {
return false;
}
let host_without_port = host.split(':').next().unwrap_or(host);
if is_ipv4_address(host_without_port) {
return false;
}
host_without_port == "localhost" || host_without_port.contains('.')
}
pub fn is_ipv4_address(s: &str) -> bool {
let parts: Vec<&str> = s.split('.').collect();
if parts.len() != 4 {
return false;
}
parts.iter().all(|p| p.parse::<u8>().is_ok())
}
pub fn extract_host_from_url(url: &str) -> Option<&str> {
let after_protocol = if let Some(pos) = url.find("://") {
&url[pos + 3..]
} else {
return None;
};
if after_protocol.starts_with("unix:") {
return Some(after_protocol);
}
let host_and_port = if let Some(pos) = after_protocol.find('/') {
&after_protocol[..pos]
} else {
after_protocol
};
Some(host_and_port)
}
pub fn extract_domain(host: &str) -> &str {
host.split(':').next().unwrap_or(host)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_domain_name() {
assert!(is_domain_name("example.com"));
assert!(is_domain_name("api.example.com"));
assert!(is_domain_name("localhost"));
assert!(is_domain_name("backend.internal"));
assert!(is_domain_name("example.com:8080"));
assert!(!is_domain_name("127.0.0.1"));
assert!(!is_domain_name("127.0.0.1:8080"));
assert!(!is_domain_name("[::1]"));
assert!(!is_domain_name("[::1]:8080"));
assert!(!is_domain_name("$backend"));
assert!(!is_domain_name("unix:/var/run/app.sock"));
assert!(!is_domain_name("backend")); assert!(!is_domain_name(""));
}
#[test]
fn test_is_ipv4_address() {
assert!(is_ipv4_address("127.0.0.1"));
assert!(is_ipv4_address("192.168.1.1"));
assert!(is_ipv4_address("0.0.0.0"));
assert!(is_ipv4_address("255.255.255.255"));
assert!(!is_ipv4_address("example.com"));
assert!(!is_ipv4_address("127.0.0.1.1"));
assert!(!is_ipv4_address("256.0.0.1"));
assert!(!is_ipv4_address("localhost"));
assert!(!is_ipv4_address(""));
}
#[test]
fn test_extract_host_from_url() {
assert_eq!(
extract_host_from_url("http://example.com"),
Some("example.com")
);
assert_eq!(
extract_host_from_url("http://example.com:8080"),
Some("example.com:8080")
);
assert_eq!(
extract_host_from_url("http://example.com/path"),
Some("example.com")
);
assert_eq!(
extract_host_from_url("https://api.example.com:443/api/v1"),
Some("api.example.com:443")
);
assert_eq!(
extract_host_from_url("http://[::1]:8080/path"),
Some("[::1]:8080")
);
assert_eq!(
extract_host_from_url("http://unix:/var/run/app.sock"),
Some("unix:/var/run/app.sock")
);
assert_eq!(extract_host_from_url("example.com"), None);
assert_eq!(extract_host_from_url("backend"), None);
}
#[test]
fn test_extract_domain() {
assert_eq!(extract_domain("example.com"), "example.com");
assert_eq!(extract_domain("example.com:8080"), "example.com");
assert_eq!(extract_domain("localhost:3000"), "localhost");
assert_eq!(extract_domain("127.0.0.1:80"), "127.0.0.1");
}
}