@@ -39,9 +39,31 @@ fn url<'a, 'b>(
3939 gix_url:: Url :: from_parts (
4040 protocol,
4141 user. into ( ) . map ( Into :: into) ,
42+ None ,
4243 host. into ( ) . map ( Into :: into) ,
4344 port. into ( ) ,
4445 path. into ( ) ,
46+ false ,
47+ )
48+ . unwrap_or_else ( |err| panic ! ( "'{}' failed: {err:?}" , path. as_bstr( ) ) )
49+ }
50+
51+ fn url_with_pass < ' a , ' b > (
52+ protocol : Scheme ,
53+ user : impl Into < Option < & ' a str > > ,
54+ password : impl Into < String > ,
55+ host : impl Into < Option < & ' b str > > ,
56+ port : impl Into < Option < u16 > > ,
57+ path : & [ u8 ] ,
58+ ) -> gix_url:: Url {
59+ gix_url:: Url :: from_parts (
60+ protocol,
61+ user. into ( ) . map ( Into :: into) ,
62+ Some ( password. into ( ) ) ,
63+ host. into ( ) . map ( Into :: into) ,
64+ port. into ( ) ,
65+ path. into ( ) ,
66+ false ,
4567 )
4668 . unwrap_or_else ( |err| panic ! ( "'{}' failed: {err:?}" , path. as_bstr( ) ) )
4769}
@@ -53,12 +75,14 @@ fn url_alternate<'a, 'b>(
5375 port : impl Into < Option < u16 > > ,
5476 path : & [ u8 ] ,
5577) -> gix_url:: Url {
56- let url = gix_url:: Url :: from_parts_as_alternative_form (
78+ let url = gix_url:: Url :: from_parts (
5779 protocol. clone ( ) ,
5880 user. into ( ) . map ( Into :: into) ,
81+ None ,
5982 host. into ( ) . map ( Into :: into) ,
6083 port. into ( ) ,
6184 path. into ( ) ,
85+ true ,
6286 )
6387 . expect ( "valid" ) ;
6488 assert_eq ! ( url. scheme, protocol) ;
@@ -92,7 +116,7 @@ mod radicle {
92116mod http {
93117 use gix_url:: Scheme ;
94118
95- use crate :: parse:: { assert_url, assert_url_roundtrip, url} ;
119+ use crate :: parse:: { assert_url, assert_url_roundtrip, url, url_with_pass } ;
96120
97121 #[ test]
98122 fn username_expansion_is_unsupported ( ) -> crate :: Result {
@@ -102,6 +126,44 @@ mod http {
102126 )
103127 }
104128 #[ test]
129+ fn empty_user_cannot_roundtrip ( ) -> crate :: Result {
130+ let actual = gix_url:: parse ( "http://@example.com/~byron/hello" . into ( ) ) ?;
131+ let expected = url ( Scheme :: Http , "" , "example.com" , None , b"/~byron/hello" ) ;
132+ assert_eq ! ( actual, expected) ;
133+ assert_eq ! (
134+ actual. to_bstring( ) ,
135+ "http://example.com/~byron/hello" ,
136+ "we cannot differentiate between empty user and no user"
137+ ) ;
138+ Ok ( ( ) )
139+ }
140+ #[ test]
141+ fn username_and_password ( ) -> crate :: Result {
142+ assert_url_roundtrip (
143+ "http://user:[email protected] /~byron/hello" , 144+ url_with_pass ( Scheme :: Http , "user" , "password" , "example.com" , None , b"/~byron/hello" ) ,
145+ )
146+ }
147+ #[ test]
148+ fn only_password ( ) -> crate :: Result {
149+ assert_url_roundtrip (
150+ "http://:[email protected] /~byron/hello" , 151+ url_with_pass ( Scheme :: Http , "" , "password" , "example.com" , None , b"/~byron/hello" ) ,
152+ )
153+ }
154+ #[ test]
155+ fn username_and_empty_password ( ) -> crate :: Result {
156+ let actual = gix_url:: parse ( "http://user:@example.com/~byron/hello" . into ( ) ) ?;
157+ let expected = url_with_pass ( Scheme :: Http , "user" , "" , "example.com" , None , b"/~byron/hello" ) ;
158+ assert_eq ! ( actual, expected) ;
159+ assert_eq ! (
160+ actual. to_bstring( ) ,
161+ "http://[email protected] /~byron/hello" , 162+ "an empty password appears like no password to us - fair enough"
163+ ) ;
164+ Ok ( ( ) )
165+ }
166+ #[ test]
105167 fn secure ( ) -> crate :: Result {
106168 assert_url_roundtrip (
107169 "https://github.com/byron/gitoxide" ,
0 commit comments