@@ -443,12 +443,19 @@ impl OutboundUrl {
443443 // we can always url encode the authority even if it is already encoded.
444444 if let Some ( at) = url. find ( '@' ) {
445445 let scheme_end = url. find ( "://" ) . map ( |e| e + 3 ) . unwrap_or ( 0 ) ;
446- let userinfo = & url[ scheme_end..at] ;
447-
448- let encoded = urlencoding:: encode ( userinfo) ;
449- let prefix = & url[ ..scheme_end] ;
450- let suffix = & url[ scheme_end + userinfo. len ( ) ..] ;
451- url = format ! ( "{prefix}{encoded}{suffix}" ) ;
446+ let path_start = url[ scheme_end..]
447+ . find ( '/' ) // This can calculate the wrong index if the username or password contains a '/'
448+ . map ( |e| e + scheme_end)
449+ . unwrap_or ( usize:: MAX ) ;
450+
451+ if at < path_start {
452+ let userinfo = & url[ scheme_end..at] ;
453+
454+ let encoded = urlencoding:: encode ( userinfo) ;
455+ let prefix = & url[ ..scheme_end] ;
456+ let suffix = & url[ scheme_end + userinfo. len ( ) ..] ;
457+ url = format ! ( "{prefix}{encoded}{suffix}" ) ;
458+ }
452459 }
453460
454461 let parsed = match url:: Url :: parse ( & url) {
@@ -562,6 +569,25 @@ mod test {
562569 use super :: * ;
563570 use std:: net:: { Ipv4Addr , Ipv6Addr } ;
564571
572+ #[ test]
573+ fn outbound_url_handles_at_in_paths ( ) {
574+ let url =
"https://example.com/[email protected] " ; 575+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
576+ assert_eq ! ( "example.com" , url. host) ;
577+
578+ 579+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
580+ assert_eq ! ( "example.com" , url. host) ;
581+
582+ 583+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
584+ assert_eq ! ( "example.com" , url. host) ;
585+
586+ let url =
"https://user:[email protected] " ; 587+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
588+ assert_eq ! ( "example.com" , url. host) ;
589+ }
590+
565591 #[ test]
566592 fn test_allowed_hosts_accepts_url_without_port ( ) {
567593 assert_eq ! (
0 commit comments