@@ -95,9 +95,18 @@ impl Request {
95
95
96
96
impl RequestBuilder {
97
97
pub ( super ) fn new ( client : Client , request : :: Result < Request > ) -> RequestBuilder {
98
- RequestBuilder {
99
- client,
100
- request,
98
+ let mut builder = RequestBuilder { client, request } ;
99
+
100
+ let auth = builder
101
+ . request
102
+ . as_mut ( )
103
+ . ok ( )
104
+ . and_then ( |req| extract_authority ( & mut req. url ) ) ;
105
+
106
+ if let Some ( ( username, password) ) = auth {
107
+ builder. basic_auth ( username, password)
108
+ } else {
109
+ builder
101
110
}
102
111
}
103
112
@@ -170,7 +179,7 @@ impl RequestBuilder {
170
179
Some ( password) => format ! ( "{}:{}" , username, password) ,
171
180
None => format ! ( "{}:" , username)
172
181
} ;
173
- let header_value = format ! ( "Basic {}" , encode( & auth) ) ;
182
+ let header_value = format ! ( "Basic {}" , encode( & dbg! ( auth) ) ) ;
174
183
self . header ( :: header:: AUTHORIZATION , & * header_value)
175
184
}
176
185
@@ -424,6 +433,37 @@ pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
424
433
}
425
434
}
426
435
436
+
437
+ /// Check the request URL for a "username:password" type authority, and if
438
+ /// found, remove it from the URL and return it.
439
+ pub ( crate ) fn extract_authority ( url : & mut Url ) -> Option < ( String , Option < String > ) > {
440
+ use url:: percent_encoding:: percent_decode;
441
+
442
+ if url. has_authority ( ) {
443
+ let username: String = percent_decode ( url. username ( ) . as_bytes ( ) )
444
+ . decode_utf8 ( )
445
+ . ok ( ) ?
446
+ . into ( ) ;
447
+ let password = url. password ( ) . and_then ( |pass| {
448
+ percent_decode ( pass. as_bytes ( ) )
449
+ . decode_utf8 ( )
450
+ . ok ( )
451
+ . map ( String :: from)
452
+ } ) ;
453
+ if !username. is_empty ( ) || password. is_some ( ) {
454
+ url
455
+ . set_username ( "" )
456
+ . expect ( "has_authority means set_username shouldn't fail" ) ;
457
+ url
458
+ . set_password ( None )
459
+ . expect ( "has_authority means set_password shouldn't fail" ) ;
460
+ return Some ( ( username, password) )
461
+ }
462
+ }
463
+
464
+ None
465
+ }
466
+
427
467
#[ cfg( test) ]
428
468
mod tests {
429
469
use super :: Client ;
@@ -536,6 +576,20 @@ mod tests {
536
576
assert_eq ! ( req. url( ) . as_str( ) , "https://google.com/" ) ;
537
577
}
538
578
579
+ #[ test]
580
+ fn convert_url_authority_into_basic_auth ( ) {
581
+ let client = Client :: new ( ) ;
582
+ let some_url = "https://Aladdin:open sesame@localhost/" ;
583
+
584
+ let req = client
585
+ . get ( some_url)
586
+ . build ( )
587
+ . expect ( "request build" ) ;
588
+
589
+ assert_eq ! ( req. url( ) . as_str( ) , "https://localhost/" ) ;
590
+ assert_eq ! ( req. headers( ) [ "authorization" ] , "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" ) ;
591
+ }
592
+
539
593
/*
540
594
use {body, Method};
541
595
use super::Client;
0 commit comments