use url::Url;
static DELEGATED_HOSTS: &[&str] = &[
"bandcamp.com",
"bilibili.com",
"bilibili.tv",
"dailymotion.com",
"facebook.com",
"instagram.com",
"nicovideo.jp",
"odysee.com",
"reddit.com",
"rumble.com",
"soundcloud.com",
"tiktok.com",
"twitch.tv",
"twitter.com",
"vimeo.com",
"x.com",
"youtu.be",
"youtube.com",
];
fn matches_domain(host: &str, domain: &str) -> bool {
if host == domain {
return true;
}
host.len() > domain.len()
&& host.ends_with(domain)
&& host.as_bytes()[host.len() - domain.len() - 1] == b'.'
}
pub fn is_delegated_url(url: &Url, extra: &[String], excluded: &[String]) -> bool {
if !matches!(url.scheme(), "http" | "https") {
return false;
}
let Some(host) = url.host_str() else {
return false;
};
let host = host.trim_matches('.').to_ascii_lowercase();
if excluded.iter().any(|d| matches_domain(&host, d)) {
return false;
}
DELEGATED_HOSTS.iter().any(|d| matches_domain(&host, d))
|| extra.iter().any(|d| matches_domain(&host, d))
}
#[cfg(test)]
mod tests {
use super::*;
fn url(s: &str) -> Url {
Url::parse(s).unwrap()
}
#[test]
fn builtin_list_is_sorted_lowercase_and_bare() {
let mut sorted = DELEGATED_HOSTS.to_vec();
sorted.sort_unstable();
sorted.dedup();
assert_eq!(
sorted, DELEGATED_HOSTS,
"DELEGATED_HOSTS must be sorted and free of duplicates"
);
for host in DELEGATED_HOSTS {
assert_eq!(*host, host.to_ascii_lowercase(), "{host} must be lowercase");
assert!(host.contains('.'), "{host} must be a registrable domain");
assert!(!host.starts_with('.'), "{host} must not have a leading dot");
assert!(!host.contains('/'), "{host} must not contain a path");
assert!(host.is_ascii(), "{host} must be punycode, not unicode");
}
}
#[test]
fn matches_domain_and_subdomains() {
assert!(is_delegated_url(
&url("https://youtube.com/watch?v=x"),
&[],
&[]
));
assert!(is_delegated_url(
&url("https://www.youtube.com/watch?v=x"),
&[],
&[]
));
assert!(is_delegated_url(&url("https://m.youtube.com/"), &[], &[]));
assert!(is_delegated_url(&url("https://youtu.be/abc"), &[], &[]));
}
#[test]
fn does_not_match_lookalike_hosts() {
assert!(!is_delegated_url(
&url("https://youtube.com.evil.example/"),
&[],
&[]
));
assert!(!is_delegated_url(&url("https://notyoutube.com/"), &[], &[]));
assert!(!is_delegated_url(
&url("https://youtube.company/"),
&[],
&[]
));
assert!(!is_delegated_url(&url("https://example.com/"), &[], &[]));
}
#[test]
fn host_matching_is_case_insensitive() {
assert!(is_delegated_url(&url("https://WWW.YouTube.COM/"), &[], &[]));
}
#[test]
fn only_http_schemes_are_delegated() {
assert!(!is_delegated_url(&url("ftp://youtube.com/file"), &[], &[]));
assert!(!is_delegated_url(&url("file:///tmp/youtube.com"), &[], &[]));
}
#[test]
fn extra_hosts_extend_and_exclusions_win() {
let extra = vec!["video.example".to_string()];
assert!(is_delegated_url(
&url("https://cdn.video.example/x"),
&extra,
&[]
));
let excluded = vec!["youtube.com".to_string()];
assert!(!is_delegated_url(
&url("https://www.youtube.com/"),
&[],
&excluded
));
assert!(!is_delegated_url(
&url("https://video.example/"),
&extra,
&["video.example".to_string()]
));
}
}