From f8c93c44f1dd7c33c3a6ea0c3567c2e7fcae305e Mon Sep 17 00:00:00 2001 From: DuProcess <273172371+DuProcess@users.noreply.github.com> Date: Thu, 16 Jul 2026 22:18:12 -0400 Subject: [PATCH] Align SDK SSH destination parsing with CLI --- src/client.rs | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/client.rs b/src/client.rs index a559967..3348144 100644 --- a/src/client.rs +++ b/src/client.rs @@ -731,13 +731,23 @@ fn first_resolved_addr(addrs: &[SocketAddr], host: &str, port: u16) -> Result String { - destination - .rsplit('@') + let without_user = destination + .rsplit_once('@') + .map_or(destination, |(_, host)| host); + let without_path = without_user + .strip_prefix("ssh://") + .unwrap_or(without_user) + .split('/') .next() - .unwrap_or(destination) - .split(':') - .next() - .unwrap_or(destination) + .unwrap_or(without_user); + if let Some(stripped) = without_path.strip_prefix('[') + && let Some((host, _)) = stripped.split_once(']') + { + return host.to_string(); + } + without_path + .split_once(':') + .map_or(without_path, |(host, _)| host) .to_string() } @@ -811,6 +821,15 @@ mod tests { ); assert_eq!(destination_host("palav@example.com"), "example.com"); assert_eq!(destination_host("example.com:2222"), "example.com"); + assert_eq!(destination_host("palav@[2001:db8::1]:2222"), "2001:db8::1"); + assert_eq!( + destination_host("ssh://palav@example.com:2222/srv/app"), + "example.com" + ); + assert_eq!( + destination_host("ssh://palav@[2001:db8::2]:2222/srv/app"), + "2001:db8::2" + ); } #[test] @@ -880,6 +899,21 @@ mod tests { ); } + #[test] + fn sdk_udp_host_preserves_bracketed_ipv6_destination_without_ssh_config() { + assert_eq!( + selected_sdk_udp_host( + None, + &HostConfig::default(), + &ClientConfig::default(), + "deploy@[2001:db8::5]:2222", + &SdkSshConfig::default(), + ) + .unwrap(), + "2001:db8::5" + ); + } + #[test] fn sdk_udp_host_honors_cli_compatible_special_values() { let ssh_config = SdkSshConfig {