fix: preserve URL type in matches_scheme (#2179)

Avoid resolving Url::as_ref() to the full URL string before TunnelScheme
conversion. Add regression coverage for owned/borrowed URLs and the UDP
IPv6 hole-punch branch condition.

Co-authored-by: KKRainbow <443152178@qq.com>
This commit is contained in:
lurenjia
2026-04-28 23:23:41 +08:00
committed by GitHub
parent d5c4700d32
commit f66010e6f9
2 changed files with 35 additions and 1 deletions
+11
View File
@@ -802,12 +802,23 @@ mod tests {
wait_route_appear_with_cost,
},
proto::peer_rpc::GetIpListResponse,
tunnel::{IpScheme, TunnelScheme, matches_scheme},
};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use super::{TESTING, mapped_listener_port, resolve_mapped_listener_addrs};
#[test]
fn udp_ipv6_url_matches_hole_punch_branch_condition() {
let remote_url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap();
let takes_udp_ipv6_hole_punch_branch =
matches_scheme!(remote_url, TunnelScheme::Ip(IpScheme::Udp))
&& matches!(remote_url.host(), Some(url::Host::Ipv6(_)));
assert!(takes_udp_ipv6_hole_punch_branch);
}
#[test]
fn mapped_listener_port_uses_ip_scheme_defaults() {
assert_eq!(
+24 -1
View File
@@ -371,9 +371,13 @@ impl TryFrom<&url::Url> for TunnelScheme {
}
}
pub(crate) fn get_scheme_by_url(l: &url::Url) -> Result<TunnelScheme, Error> {
l.try_into()
}
macro_rules! __matches_scheme__ {
($url:expr, $( $pattern:pat_param )|+ ) => {
matches!($crate::tunnel::TunnelScheme::try_from(($url).as_ref()), Ok($( $pattern )|+))
matches!($crate::tunnel::get_scheme_by_url(&$url), Ok($( $pattern )|+))
};
}
@@ -393,3 +397,22 @@ macro_rules! __matches_protocol__ {
}
pub(crate) use __matches_protocol__ as matches_protocol;
#[cfg(test)]
mod tests {
use super::{IpScheme, TunnelScheme, matches_scheme};
#[test]
fn matches_scheme_accepts_owned_url() {
let url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap();
assert!(matches_scheme!(url, TunnelScheme::Ip(IpScheme::Udp)));
}
#[test]
fn matches_scheme_accepts_borrowed_url() {
let url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap();
assert!(matches_scheme!(&url, TunnelScheme::Ip(IpScheme::Udp)));
}
}