From fc38fa25943db335e1e98253ba0351b7f6ff3316 Mon Sep 17 00:00:00 2001 From: karanabe <152078880+karanabe@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:19:45 +0900 Subject: [PATCH] fix(client): handle proxy auth without password --- src/client/proxy/matcher.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/client/proxy/matcher.rs b/src/client/proxy/matcher.rs index 5136716..a883133 100644 --- a/src/client/proxy/matcher.rs +++ b/src/client/proxy/matcher.rs @@ -331,6 +331,8 @@ fn get_first_env(names: &[&str]) -> String { } fn parse_env_uri(val: &str) -> Option { + use std::borrow::Cow; + let uri = val.parse::().ok()?; let mut builder = http::Uri::builder(); let mut is_httpish = false; @@ -358,13 +360,19 @@ fn parse_env_uri(val: &str) -> Option { let authority = uri.authority()?; if let Some((userinfo, host_port)) = authority.as_str().split_once('@') { - let (user, pass) = userinfo.split_once(':')?; + let (user, pass) = match userinfo.split_once(':') { + Some((user, pass)) => (user, Some(pass)), + None => (userinfo, None), + }; let user = percent_decode_str(user).decode_utf8_lossy(); - let pass = percent_decode_str(pass).decode_utf8_lossy(); + let pass = pass.map(|pass| percent_decode_str(pass).decode_utf8_lossy()); if is_httpish { - auth = Auth::Basic(encode_basic_auth(&user, Some(&pass))); + auth = Auth::Basic(encode_basic_auth(&user, pass.as_deref())); } else { - auth = Auth::Raw(user.into(), pass.into()); + auth = Auth::Raw( + user.into_owned(), + pass.map_or_else(String::new, Cow::into_owned), + ); } builder = builder.authority(host_port); } else { @@ -822,6 +830,19 @@ mod tests { ); } + #[test] + fn test_parse_http_auth_without_password() { + let p = p! { + all = "http://Aladdin@y.ep", + }; + let proxy = intercept(&p, "https://example.local"); + assert_eq!(proxy.uri(), "http://y.ep"); + assert_eq!( + proxy.basic_auth().expect("basic_auth"), + "Basic QWxhZGRpbjo=" + ); + } + #[test] fn test_parse_http_auth_without_scheme() { let p = p! {