@@ -38,18 +38,46 @@ struct URI {
3838
3939 bool uri_parse (string uri) @safe pure {
4040 auto i = uri.findSplit(" ://" );
41- string rest;
41+ string rest, authority, path_and_query ;
4242 if ( i[1 ].length ) {
4343 _scheme = i[0 ].toLower;
4444 rest = i[2 ];
4545 } else {
4646 return false ;
4747 }
48+ if ( _scheme ! in standard_ports ) {
49+ return false ;
50+ }
4851 // separate Authority from path and query
49- i = rest.findSplit(" /" );
50- auto authority = i[0 ];
51- auto path_and_query = i[2 ];
52-
52+ auto query = rest.indexOf(" ?" );
53+ auto path = rest.indexOf(" /" );
54+ // auth/p?q p>0 q>p
55+ // auth/p p>0 q=-1
56+ // auth?q/p p>0 q<p
57+ // auth?q p=-1 q>0
58+ // auth p=-1 q=-1
59+ if ( path >= 0 ) {
60+ if ( query > path || query == - 1 ) {
61+ // a/p?q or a/p
62+ authority = rest[0 .. path];
63+ path_and_query = rest[path+ 1 .. $];
64+ } else if ( query < path ) {
65+ // a?q/p
66+ authority = rest[0 .. query];
67+ path_and_query = rest[query.. $];
68+ }
69+ } else {
70+ if ( query >= 0 ) {
71+ // auth?q p=-1 q>0
72+ authority = rest[0 .. query];
73+ path_and_query = rest[query.. $];
74+ } else {
75+ // auth p=-1 q=-1
76+ authority = rest;
77+ path_and_query = " " ;
78+ }
79+ }
80+
5381 // find user/password/host:port in authority
5482 i = authority.findSplit(" @" );
5583 string up;
@@ -150,11 +178,21 @@ unittest {
150178 assert (a.scheme == " http" );
151179 assert (a.host == " example.com" );
152180 assert (a.path == " /" );
153- a = URI (" svn+ssh ://igor@example.com:1234" );
154- assert (a.scheme == " svn+ssh " );
181+ a = URI (" https ://igor@example.com:1234" );
182+ assert (a.scheme == " https " );
155183 assert (a.host == " example.com" );
156184 assert (a.username == " igor" );
157185 assert (a.path == " /" );
186+ a = URI (" https://example.com?a" );
187+ assert (a.scheme == " https" );
188+ assert (a.host == " example.com" );
189+ assert (a.path == " /" );
190+ assert (a.query == " ?a" );
191+ a = URI (" https://example.com?a=/test" );
192+ assert (a.scheme == " https" );
193+ assert (a.host == " example.com" );
194+ assert (a.path == " /" );
195+ assert (a.query == " ?a=/test" );
158196 a = URI (" http://igor:pass;word@example.com:1234/abc?q=x" );
159197 assert (a.password == " pass;word" );
160198 assert (a.port == 1234 );
@@ -171,5 +209,6 @@ unittest {
171209 a = URI (" http://registrera-domän.se" );
172210 a.idn_encode();
173211 assert (a.host == " xn--registrera-domn-elb.se" );
212+ assertThrown! UriException(URI (" cnn://deeplink?section=livetv&subsection=sliver&stream=CNN1" ));
174213}
175214
0 commit comments