URITest.java revision c68609e723a5daa20888abdb640799d4353fd590
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.net;
18
19import java.net.URI;
20import java.net.URISyntaxException;
21import junit.framework.TestCase;
22import libcore.java.util.SerializableTester;
23
24public final class URITest extends TestCase {
25
26    public void testUriParts() throws Exception {
27        URI uri = new URI("http://username:password@host:8080/directory/file?query#ref");
28        assertEquals("http", uri.getScheme());
29        assertEquals("username:password@host:8080", uri.getAuthority());
30        assertEquals("username:password@host:8080", uri.getRawAuthority());
31        assertEquals("username:password", uri.getUserInfo());
32        assertEquals("username:password", uri.getRawUserInfo());
33        assertEquals("host", uri.getHost());
34        assertEquals(8080, uri.getPort());
35        assertEquals("/directory/file", uri.getPath());
36        assertEquals("/directory/file", uri.getRawPath());
37        assertEquals("query", uri.getQuery());
38        assertEquals("query", uri.getRawQuery());
39        assertEquals("ref", uri.getFragment());
40        assertEquals("ref", uri.getRawFragment());
41        assertEquals("//username:password@host:8080/directory/file?query",
42                uri.getSchemeSpecificPart());
43        assertEquals("//username:password@host:8080/directory/file?query",
44                uri.getRawSchemeSpecificPart());
45    }
46
47    public void testEqualsCaseMapping() throws Exception {
48        assertEquals(new URI("HTTP://localhost/foo?bar=baz#quux"),
49                new URI("HTTP://localhost/foo?bar=baz#quux"));
50        assertEquals(new URI("http://localhost/foo?bar=baz#quux"),
51                new URI("http://LOCALHOST/foo?bar=baz#quux"));
52        assertFalse(new URI("http://localhost/foo?bar=baz#quux")
53                .equals(new URI("http://localhost/FOO?bar=baz#quux")));
54        assertFalse(new URI("http://localhost/foo?bar=baz#quux")
55                .equals(new URI("http://localhost/foo?BAR=BAZ#quux")));
56        assertFalse(new URI("http://localhost/foo?bar=baz#quux")
57                .equals(new URI("http://localhost/foo?bar=baz#QUUX")));
58    }
59
60    public void testFileEqualsWithEmptyHost() throws Exception {
61        assertEquals(new URI("file", "", "/a/", null), new URI("file:/a/"));
62        assertEquals(new URI("file", null, "/a/", null), new URI("file:/a/"));
63    }
64
65    public void testUriSerialization() throws Exception {
66        String s = "aced00057372000c6a6176612e6e65742e555249ac01782e439e49ab0300014c0006737472696e6"
67                + "77400124c6a6176612f6c616e672f537472696e673b787074002a687474703a2f2f757365723a706"
68                + "1737340686f73742f706174682f66696c653f7175657279236861736878";
69        URI uri = new URI("http://user:pass@host/path/file?query#hash");
70        new SerializableTester<URI>(uri, s).test();
71    }
72
73    public void testEmptyHost() throws Exception {
74        URI uri = new URI("http:///path");
75        assertEquals(null, uri.getHost());
76        assertEquals("/path", uri.getPath());
77    }
78
79    public void testNoHost() throws Exception {
80        URI uri = new URI("http:/path");
81        assertEquals(null, uri.getHost());
82        assertEquals("/path", uri.getPath());
83    }
84
85    public void testNoPath() throws Exception {
86        URI uri = new URI("http://host");
87        assertEquals("host", uri.getHost());
88        assertEquals("", uri.getPath());
89    }
90
91    public void testEmptyHostAndNoPath() throws Exception {
92        try {
93            new URI("http://");
94            fail();
95        } catch (URISyntaxException expected) {
96        }
97    }
98
99    public void testNoHostAndNoPath() throws Exception {
100        try {
101            new URI("http:");
102            fail();
103        } catch (URISyntaxException expected) {
104        }
105    }
106
107    public void testAtSignInUserInfo() throws Exception {
108        URI uri = new URI("http://user@userhost.com:password@host");
109        assertEquals("user@userhost.com:password@host", uri.getAuthority());
110        assertEquals(null, uri.getUserInfo());
111        assertEquals(null, uri.getHost());
112    }
113
114    public void testUserNoPassword() throws Exception {
115        URI uri = new URI("http://user@host");
116        assertEquals("user@host", uri.getAuthority());
117        assertEquals("user", uri.getUserInfo());
118        assertEquals("host", uri.getHost());
119    }
120
121    public void testUserNoPasswordExplicitPort() throws Exception {
122        URI uri = new URI("http://user@host:8080");
123        assertEquals("user@host:8080", uri.getAuthority());
124        assertEquals("user", uri.getUserInfo());
125        assertEquals("host", uri.getHost());
126        assertEquals(8080, uri.getPort());
127    }
128
129    public void testUserPasswordHostPort() throws Exception {
130        URI uri = new URI("http://user:password@host:8080");
131        assertEquals("user:password@host:8080", uri.getAuthority());
132        assertEquals("user:password", uri.getUserInfo());
133        assertEquals("host", uri.getHost());
134        assertEquals(8080, uri.getPort());
135    }
136
137    public void testUserPasswordEmptyHostPort() throws Exception {
138        URI uri = new URI("http://user:password@:8080");
139        assertEquals("user:password@:8080", uri.getAuthority());
140        // from RI. this is curious
141        assertEquals(null, uri.getUserInfo());
142        assertEquals(null, uri.getHost());
143        assertEquals(-1, uri.getPort());
144    }
145
146    public void testUserPasswordEmptyHostEmptyPort() throws Exception {
147        URI uri = new URI("http://user:password@:");
148        assertEquals("user:password@:", uri.getAuthority());
149        // from RI. this is curious
150        assertEquals(null, uri.getUserInfo());
151        assertEquals(null, uri.getHost());
152        assertEquals(-1, uri.getPort());
153    }
154
155    public void testPathOnly() throws Exception {
156        URI uri = new URI("http://host/path");
157        assertEquals("host", uri.getHost());
158        assertEquals("/path", uri.getPath());
159    }
160
161    public void testQueryOnly() throws Exception {
162        URI uri = new URI("http://host?query");
163        assertEquals("host", uri.getHost());
164        assertEquals("", uri.getPath());
165        assertEquals("query", uri.getQuery());
166    }
167
168    public void testFragmentOnly() throws Exception {
169        URI uri = new URI("http://host#fragment");
170        assertEquals("host", uri.getHost());
171        assertEquals("", uri.getPath());
172        assertEquals(null, uri.getQuery());
173        assertEquals("fragment", uri.getFragment());
174    }
175
176    public void testAtSignInPath() throws Exception {
177        URI uri = new URI("http://host/file@foo");
178        assertEquals("/file@foo", uri.getPath());
179        assertEquals(null, uri.getUserInfo());
180    }
181
182
183    public void testColonInPath() throws Exception {
184        URI uri = new URI("http://host/file:colon");
185        assertEquals("/file:colon", uri.getPath());
186    }
187
188    public void testSlashInQuery() throws Exception {
189        URI uri = new URI("http://host/file?query/path");
190        assertEquals("/file", uri.getPath());
191        assertEquals("query/path", uri.getQuery());
192    }
193
194    public void testQuestionMarkInQuery() throws Exception {
195        URI uri = new URI("http://host/file?query?another");
196        assertEquals("/file", uri.getPath());
197        assertEquals("query?another", uri.getQuery());
198    }
199
200    public void testAtSignInQuery() throws Exception {
201        URI uri = new URI("http://host/file?query@at");
202        assertEquals("/file", uri.getPath());
203        assertEquals("query@at", uri.getQuery());
204    }
205
206    public void testColonInQuery() throws Exception {
207        URI uri = new URI("http://host/file?query:colon");
208        assertEquals("/file", uri.getPath());
209        assertEquals("query:colon", uri.getQuery());
210    }
211
212    public void testQuestionMarkInFragment() throws Exception {
213        URI uri = new URI("http://host/file#fragment?query");
214        assertEquals("/file", uri.getPath());
215        assertEquals(null, uri.getQuery());
216        assertEquals("fragment?query", uri.getFragment());
217    }
218
219    public void testColonInFragment() throws Exception {
220        URI uri = new URI("http://host/file#fragment:80");
221        assertEquals("/file", uri.getPath());
222        assertEquals(-1, uri.getPort());
223        assertEquals("fragment:80", uri.getFragment());
224    }
225
226    public void testSlashInFragment() throws Exception {
227        URI uri = new URI("http://host/file#fragment/path");
228        assertEquals("/file", uri.getPath());
229        assertEquals("fragment/path", uri.getFragment());
230    }
231
232    public void testHashInFragment() throws Exception {
233        try {
234            // This is not consistent with java.net.URL
235            new URI("http://host/file#fragment#another");
236            fail();
237        } catch (URISyntaxException expected) {
238        }
239    }
240
241    public void testEmptyPort() throws Exception {
242        URI uri = new URI("http://host:/");
243        assertEquals(-1, uri.getPort());
244    }
245
246    public void testNonNumericPort() throws Exception {
247        URI uri = new URI("http://host:x/");
248        // From the RI. This is curious
249        assertEquals(null, uri.getHost());
250        assertEquals(-1, uri.getPort());
251    }
252
253    public void testNegativePort() throws Exception {
254        URI uri = new URI("http://host:-2/");
255        // From the RI. This is curious
256        assertEquals(null, uri.getHost());
257        assertEquals(-1, uri.getPort());
258    }
259
260    public void testNegativePortEqualsPlaceholder() throws Exception {
261        URI uri = new URI("http://host:-1/");
262        // From the RI. This is curious
263        assertEquals(null, uri.getHost());
264        assertEquals(-1, uri.getPort());
265    }
266
267    public void testRelativePathOnQuery() throws Exception {
268        URI base = new URI("http://host/file?query/x");
269        URI uri = base.resolve("another");
270        assertEquals("http://host/another", uri.toString());
271        assertEquals("/another", uri.getPath());
272        assertEquals(null, uri.getQuery());
273        assertEquals(null, uri.getFragment());
274    }
275
276    public void testRelativeFragmentOnQuery() throws Exception {
277        URI base = new URI("http://host/file?query/x#fragment");
278        URI uri = base.resolve("#another");
279        assertEquals("http://host/file?query/x#another", uri.toString());
280        assertEquals("/file", uri.getPath());
281        assertEquals("query/x", uri.getQuery());
282        assertEquals("another", uri.getFragment());
283    }
284
285    public void testPathContainsRelativeParts() throws Exception {
286        URI uri = new URI("http://host/a/b/../c");
287//        assertEquals("http://host/a/c", uri.toString()); // RI doesn't canonicalize
288    }
289
290    public void testRelativePathAndFragment() throws Exception {
291        URI base = new URI("http://host/file");
292        assertEquals("http://host/another#fragment", base.resolve("another#fragment").toString());
293    }
294
295    public void testRelativeParentDirectory() throws Exception {
296        URI base = new URI("http://host/a/b/c");
297        assertEquals("http://host/a/d", base.resolve("../d").toString());
298    }
299
300    public void testRelativeChildDirectory() throws Exception {
301        URI base = new URI("http://host/a/b/c");
302        assertEquals("http://host/a/b/d/e", base.resolve("d/e").toString());
303    }
304
305    public void testRelativeRootDirectory() throws Exception {
306        URI base = new URI("http://host/a/b/c");
307        assertEquals("http://host/d", base.resolve("/d").toString());
308    }
309
310    public void testRelativeFullUrl() throws Exception {
311        URI base = new URI("http://host/a/b/c");
312        assertEquals("http://host2/d/e", base.resolve("http://host2/d/e").toString());
313        assertEquals("https://host2/d/e", base.resolve("https://host2/d/e").toString());
314    }
315
316    public void testRelativeDifferentScheme() throws Exception {
317        URI base = new URI("http://host/a/b/c");
318        assertEquals("https://host2/d/e", base.resolve("https://host2/d/e").toString());
319    }
320
321    public void testRelativeDifferentAuthority() throws Exception {
322        URI base = new URI("http://host/a/b/c");
323        assertEquals("http://another/d/e", base.resolve("//another/d/e").toString());
324    }
325
326    public void testRelativeWithScheme() throws Exception {
327        URI base = new URI("http://host/a/b/c");
328        try {
329            base.resolve("http:");
330            fail();
331        } catch (IllegalArgumentException expected) {
332        }
333        assertEquals("http:/", base.resolve("http:/").toString());
334    }
335
336    public void testMalformedUrlsRefusedByFirefoxAndChrome() throws Exception {
337        URI base = new URI("http://host/a/b/c");
338        try {
339            base.resolve("http://");
340            fail();
341        } catch (IllegalArgumentException expected) {
342        }
343        try {
344            base.resolve("//");
345            fail();
346        } catch (IllegalArgumentException expected) {
347        }
348        try {
349            base.resolve("https:");
350            fail();
351        } catch (IllegalArgumentException expected) {
352        }
353        assertEquals("https:/", base.resolve("https:/").toString());
354        try {
355            base.resolve("https://");
356            fail();
357        } catch (IllegalArgumentException expected) {
358        }
359    }
360
361    public void testRfc1808NormalExamples() throws Exception {
362        URI base = new URI("http://a/b/c/d;p?q");
363        assertEquals("https:h", base.resolve("https:h").toString());
364        assertEquals("http://a/b/c/g", base.resolve("g").toString());
365        assertEquals("http://a/b/c/g", base.resolve("./g").toString());
366        assertEquals("http://a/b/c/g/", base.resolve("g/").toString());
367        assertEquals("http://a/g", base.resolve("/g").toString());
368        assertEquals("http://g", base.resolve("//g").toString());
369        assertEquals("http://a/b/c/d;p?y", base.resolve("?y").toString()); // RI fails; loses file
370        assertEquals("http://a/b/c/g?y", base.resolve("g?y").toString());
371        assertEquals("http://a/b/c/d;p?q#s", base.resolve("#s").toString());
372        assertEquals("http://a/b/c/g#s", base.resolve("g#s").toString());
373        assertEquals("http://a/b/c/g?y#s", base.resolve("g?y#s").toString());
374        assertEquals("http://a/b/c/;x", base.resolve(";x").toString());
375        assertEquals("http://a/b/c/g;x", base.resolve("g;x").toString());
376        assertEquals("http://a/b/c/g;x?y#s", base.resolve("g;x?y#s").toString());
377        assertEquals("http://a/b/c/d;p?q", base.resolve("").toString()); // RI returns http://a/b/c/
378        assertEquals("http://a/b/c/", base.resolve(".").toString());
379        assertEquals("http://a/b/c/", base.resolve("./").toString());
380        assertEquals("http://a/b/", base.resolve("..").toString());
381        assertEquals("http://a/b/", base.resolve("../").toString());
382        assertEquals("http://a/b/g", base.resolve("../g").toString());
383        assertEquals("http://a/", base.resolve("../..").toString());
384        assertEquals("http://a/", base.resolve("../../").toString());
385        assertEquals("http://a/g", base.resolve("../../g").toString());
386    }
387
388    public void testRfc1808AbnormalExampleTooManyDotDotSequences() throws Exception {
389        URI base = new URI("http://a/b/c/d;p?q");
390        assertEquals("http://a/g", base.resolve("../../../g").toString()); // RI doesn't normalize
391        assertEquals("http://a/g", base.resolve("../../../../g").toString()); // fails on RI
392    }
393
394    public void testRfc1808AbnormalExampleRemoveDotSegments() throws Exception {
395        URI base = new URI("http://a/b/c/d;p?q");
396        assertEquals("http://a/g", base.resolve("/./g").toString()); // RI doesn't normalize
397        assertEquals("http://a/g", base.resolve("/../g").toString()); // fails on RI
398        assertEquals("http://a/b/c/g.", base.resolve("g.").toString());
399        assertEquals("http://a/b/c/.g", base.resolve(".g").toString());
400        assertEquals("http://a/b/c/g..", base.resolve("g..").toString());
401        assertEquals("http://a/b/c/..g", base.resolve("..g").toString());
402    }
403
404    public void testRfc1808AbnormalExampleNonsensicalDots() throws Exception {
405        URI base = new URI("http://a/b/c/d;p?q");
406        assertEquals("http://a/b/g", base.resolve("./../g").toString());
407        assertEquals("http://a/b/c/g/", base.resolve("./g/.").toString());
408        assertEquals("http://a/b/c/g/h", base.resolve("g/./h").toString());
409        assertEquals("http://a/b/c/h", base.resolve("g/../h").toString());
410        assertEquals("http://a/b/c/g;x=1/y", base.resolve("g;x=1/./y").toString());
411        assertEquals("http://a/b/c/y", base.resolve("g;x=1/../y").toString());
412    }
413
414    public void testRfc1808AbnormalExampleRelativeScheme() throws Exception {
415        URI base = new URI("http://a/b/c/d;p?q");
416        URI uri = base.resolve("http:g");
417        assertEquals("http:g", uri.toString()); // this is an opaque URI
418        assertEquals(true, uri.isOpaque());
419        assertEquals(true, uri.isAbsolute());
420    }
421
422    public void testRfc1808AbnormalExampleQueryOrFragmentDots() throws Exception {
423        URI base = new URI("http://a/b/c/d;p?q");
424        assertEquals("http://a/b/c/g?y/./x", base.resolve("g?y/./x").toString());
425        assertEquals("http://a/b/c/g?y/../x", base.resolve("g?y/../x").toString());
426        assertEquals("http://a/b/c/g#s/./x", base.resolve("g#s/./x").toString());
427        assertEquals("http://a/b/c/g#s/../x", base.resolve("g#s/../x").toString());
428    }
429
430    public void testSquareBracketsInUserInfo() throws Exception {
431        try {
432            new URI("http://user:[::1]@host");
433            fail();
434        } catch (URISyntaxException expected) {
435        }
436    }
437
438    public void testFileUriExtraLeadingSlashes() throws Exception {
439        URI uri = new URI("file:////foo");
440        assertEquals(null, uri.getAuthority());
441        assertEquals("//foo", uri.getPath());
442        assertEquals("file:////foo", uri.toString());
443    }
444
445    public void testFileUrlWithAuthority() throws Exception {
446        URI uri = new URI("file://x/foo");
447        assertEquals("x", uri.getAuthority());
448        assertEquals("/foo", uri.getPath());
449        assertEquals("file://x/foo", uri.toString());
450    }
451
452    public void testEmptyAuthority() throws Exception {
453        URI uri = new URI("http:///foo");
454        assertEquals(null, uri.getAuthority());
455        assertEquals("/foo", uri.getPath());
456        assertEquals("http:///foo", uri.toString());
457    }
458
459    public void testHttpUrlExtraLeadingSlashes() throws Exception {
460        URI uri = new URI("http:////foo");
461        assertEquals(null, uri.getAuthority());
462        assertEquals("//foo", uri.getPath());
463        assertEquals("http:////foo", uri.toString());
464    }
465
466    public void testFileUrlRelativePath() throws Exception {
467        URI base = new URI("file:/a/b/c");
468        assertEquals("file:/a/b/d", base.resolve("d").toString());
469    }
470
471    public void testFileUrlDottedPath() throws Exception {
472        URI url = new URI("file:../a/b");
473        assertTrue(url.isOpaque());
474        assertNull(url.getPath());
475    }
476
477    /**
478     * Regression test for http://b/issue?id=2604061
479     */
480    public void testParsingDotAsHostname() throws Exception {
481        assertEquals(null, new URI("http://./").getHost());
482    }
483
484    public void testSquareBracketsWithIPv4() throws Exception {
485        try {
486            new URI("http://[192.168.0.1]/");
487            fail();
488        } catch (URISyntaxException e) {
489        }
490    }
491
492    public void testSquareBracketsWithHostname() throws Exception {
493        try {
494            new URI("http://[google.com]/");
495            fail();
496        } catch (URISyntaxException e) {
497        }
498    }
499
500    public void testIPv6WithoutSquareBrackets() throws Exception {
501        assertEquals(null, new URI("http://fe80::1234/").getHost());
502    }
503
504    public void testEqualityWithNoPath() throws Exception {
505        assertFalse(new URI("http://android.com").equals(new URI("http://android.com/")));
506    }
507
508    public void testRelativize() throws Exception {
509        URI a = new URI("http://host/a/b");
510        URI b = new URI("http://host/a/b/c");
511        assertEquals("b/c", a.relativize(b).toString()); // RI assumes a directory
512    }
513
514    public void testParseServerAuthorityInvalidAuthority() throws Exception {
515        URI uri = new URI("http://host:-2/");
516        assertEquals("host:-2", uri.getAuthority());
517        assertNull(uri.getHost());
518        assertEquals(-1, uri.getPort());
519        try {
520            uri.parseServerAuthority();
521            fail();
522        } catch (URISyntaxException expected) {
523        }
524    }
525
526    public void testParseServerAuthorityOmittedAuthority() throws Exception {
527        URI uri = new URI("http:file");
528        uri.parseServerAuthority(); // does nothing!
529        assertNull(uri.getAuthority());
530        assertNull(uri.getHost());
531        assertEquals(-1, uri.getPort());
532    }
533
534    public void testEncodingParts() throws Exception {
535        URI uri = new URI("http", "user:pa55w?rd", "host", 80, "/doc|search",
536                "q=green robots", "over 6\"");
537        assertEquals("http", uri.getScheme());
538        assertEquals("user:pa55w?rd@host:80", uri.getAuthority());
539        assertEquals("user:pa55w%3Frd@host:80", uri.getRawAuthority());
540        assertEquals("user:pa55w?rd", uri.getUserInfo());
541        assertEquals("user:pa55w%3Frd", uri.getRawUserInfo());
542        assertEquals("/doc|search", uri.getPath());
543        assertEquals("/doc%7Csearch", uri.getRawPath());
544        assertEquals("q=green robots", uri.getQuery());
545        assertEquals("q=green%20robots", uri.getRawQuery());
546        assertEquals("over 6\"", uri.getFragment());
547        assertEquals("over%206%22", uri.getRawFragment());
548        assertEquals("//user:pa55w?rd@host:80/doc|search?q=green robots",
549                uri.getSchemeSpecificPart());
550        assertEquals("//user:pa55w%3Frd@host:80/doc%7Csearch?q=green%20robots",
551                uri.getRawSchemeSpecificPart());
552        assertEquals("http://user:pa55w%3Frd@host:80/doc%7Csearch?q=green%20robots#over%206%22",
553                uri.toString());
554    }
555
556    public void testSchemeCaseIsNotCanonicalized() throws Exception {
557        URI uri = new URI("HTTP://host/path");
558        assertEquals("HTTP", uri.getScheme());
559    }
560
561    public void testEmptyAuthorityWithPath() throws Exception {
562        URI uri = new URI("http:///path");
563        assertEquals(null, uri.getAuthority());
564        assertEquals("/path", uri.getPath());
565    }
566
567    public void testEmptyAuthorityWithQuery() throws Exception {
568        URI uri = new URI("http://?query");
569        assertEquals(null, uri.getAuthority());
570        assertEquals("", uri.getPath());
571        assertEquals("query", uri.getQuery());
572    }
573
574    public void testEmptyAuthorityWithFragment() throws Exception {
575        URI uri = new URI("http://#fragment");
576        assertEquals(null, uri.getAuthority());
577        assertEquals("", uri.getPath());
578        assertEquals("fragment", uri.getFragment());
579    }
580
581    public void testEncodingConstructorsRefuseRelativePath() throws Exception {
582        try {
583            new URI("http", "host", "relative", null);
584            fail();
585        } catch (URISyntaxException expected) {
586        }
587        try {
588            new URI("http", "host", "relative", null, null);
589            fail();
590        } catch (URISyntaxException expected) {
591        }
592        try {
593            new URI("http", null, "host", -1, "relative", null, null);
594            fail();
595        } catch (URISyntaxException expected) {
596        }
597    }
598
599    public void testEncodingConstructorsAcceptEmptyPath() throws Exception {
600        assertEquals("", new URI("http", "host", "", null).getPath());
601        assertEquals("", new URI("http", "host", "", null, null).getPath());
602        assertEquals("", new URI("http", null, "host", -1, "", null, null).getPath());
603    }
604
605    // Adding a new test? Consider adding an equivalent test to URLTest.java
606}
607