use url::Url;
const MULTICAST_SCHEMES: &[&str] = &["udp", "rtp"];
pub fn is_multicast(url: &str) -> bool {
let Ok(parsed) = Url::parse(url) else {
let lower = url.to_ascii_lowercase();
return lower.starts_with("udp://") || lower.starts_with("rtp://");
};
MULTICAST_SCHEMES.contains(&parsed.scheme())
}
pub fn convert_to_udpxy(url: &str, proxy_base: &str) -> Option<String> {
if let Ok(parsed) = Url::parse(url) {
if MULTICAST_SCHEMES.contains(&parsed.scheme()) {
let scheme = parsed.scheme();
let netloc = match parsed.port() {
Some(port) => format!("{}:{}", parsed.host_str().unwrap_or(""), port),
None => parsed.host_str().unwrap_or("").to_string(),
};
let base = proxy_base.trim_end_matches('/');
return Some(format!("{base}/{scheme}/{netloc}"));
}
return None;
}
let lower = url.to_ascii_lowercase();
for &scheme in MULTICAST_SCHEMES {
let prefix = format!("{scheme}://");
if lower.starts_with(&prefix) {
let netloc = &url[prefix.len()..];
let netloc = netloc.split('/').next().unwrap_or(netloc);
let base = proxy_base.trim_end_matches('/');
return Some(format!("{base}/{scheme}/{netloc}"));
}
}
None
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn convert_udp_url_to_udpxy() {
let result = convert_to_udpxy("udp://239.0.0.1:5001", "http://proxy:8888");
assert_eq!(result, Some("http://proxy:8888/udp/239.0.0.1:5001".into()));
}
#[test]
fn convert_rtp_url_to_udpxy() {
let result = convert_to_udpxy("rtp://239.1.2.3:1234", "http://proxy:8888");
assert_eq!(result, Some("http://proxy:8888/rtp/239.1.2.3:1234".into()));
}
#[test]
fn non_multicast_url_returns_none() {
let result = convert_to_udpxy("http://example.com/stream", "http://proxy:8888");
assert_eq!(result, None);
}
#[test]
fn is_multicast_detects_udp() {
assert!(is_multicast("udp://239.0.0.1:5001"));
}
#[test]
fn is_multicast_detects_rtp() {
assert!(is_multicast("rtp://239.1.2.3:1234"));
}
#[test]
fn is_multicast_rejects_http() {
assert!(!is_multicast("http://example.com/stream"));
}
#[test]
fn proxy_base_trailing_slash_stripped() {
let result = convert_to_udpxy("udp://239.0.0.1:5001", "http://proxy:8888/");
assert_eq!(result, Some("http://proxy:8888/udp/239.0.0.1:5001".into()));
}
}