@@ -331,6 +331,8 @@ fn get_first_env(names: &[&str]) -> String {
331331}
332332
333333fn parse_env_uri ( val : & str ) -> Option < Intercept > {
334+ use std:: borrow:: Cow ;
335+
334336 let uri = val. parse :: < http:: Uri > ( ) . ok ( ) ?;
335337 let mut builder = http:: Uri :: builder ( ) ;
336338 let mut is_httpish = false ;
@@ -358,13 +360,19 @@ fn parse_env_uri(val: &str) -> Option<Intercept> {
358360 let authority = uri. authority ( ) ?;
359361
360362 if let Some ( ( userinfo, host_port) ) = authority. as_str ( ) . split_once ( '@' ) {
361- let ( user, pass) = userinfo. split_once ( ':' ) ?;
363+ let ( user, pass) = match userinfo. split_once ( ':' ) {
364+ Some ( ( user, pass) ) => ( user, Some ( pass) ) ,
365+ None => ( userinfo, None ) ,
366+ } ;
362367 let user = percent_decode_str ( user) . decode_utf8_lossy ( ) ;
363- let pass = percent_decode_str ( pass) . decode_utf8_lossy ( ) ;
368+ let pass = pass . map ( |pass| percent_decode_str ( pass) . decode_utf8_lossy ( ) ) ;
364369 if is_httpish {
365- auth = Auth :: Basic ( encode_basic_auth ( & user, Some ( & pass) ) ) ;
370+ auth = Auth :: Basic ( encode_basic_auth ( & user, pass. as_deref ( ) ) ) ;
366371 } else {
367- auth = Auth :: Raw ( user. into ( ) , pass. into ( ) ) ;
372+ auth = Auth :: Raw (
373+ user. into_owned ( ) ,
374+ pass. map_or_else ( String :: new, Cow :: into_owned) ,
375+ ) ;
368376 }
369377 builder = builder. authority ( host_port) ;
370378 } else {
@@ -822,6 +830,19 @@ mod tests {
822830 ) ;
823831 }
824832
833+ #[ test]
834+ fn test_parse_http_auth_without_password ( ) {
835+ let p = p ! {
836+ all = "http://Aladdin@y.ep" ,
837+ } ;
838+ let proxy = intercept ( & p, "https://example.local" ) ;
839+ assert_eq ! ( proxy. uri( ) , "http://y.ep" ) ;
840+ assert_eq ! (
841+ proxy. basic_auth( ) . expect( "basic_auth" ) ,
842+ "Basic QWxhZGRpbjo="
843+ ) ;
844+ }
845+
825846 #[ test]
826847 fn test_parse_http_auth_without_scheme ( ) {
827848 let p = p ! {
0 commit comments