1 /* 2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @summary Unit test for java.net.URI 26 * @bug 4464135 4505046 4503239 4438319 4991359 4866303 7023363 27 * @author Mark Reinhold 28 */ 29 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.IOException; 33 import java.io.ObjectInputStream; 34 import java.io.ObjectOutputStream; 35 import java.io.PrintStream; 36 import java.net.URI; 37 import java.net.URISyntaxException; 38 import java.net.URL; 39 import java.net.MalformedURLException; 40 41 42 public class Test { 43 44 static PrintStream out = System.out; 45 static int testCount = 0; 46 47 // Properties that we check 48 static final int PARSEFAIL = 1 << 0; 49 static final int SCHEME = 1 << 1; 50 static final int SSP = 1 << 2; 51 static final int SSP_D = 1 << 3; // Decoded form 52 static final int OPAQUEPART = 1 << 4; // SSP, and URI is opaque 53 static final int USERINFO = 1 << 5; 54 static final int USERINFO_D = 1 << 6; // Decoded form 55 static final int HOST = 1 << 7; 56 static final int PORT = 1 << 8; 57 static final int REGISTRY = 1 << 9; 58 static final int REGISTRY_D = 1 << 10; // Decoded form 59 static final int PATH = 1 << 11; 60 static final int PATH_D = 1 << 12; // Decoded form 61 static final int QUERY = 1 << 13; 62 static final int QUERY_D = 1 << 14; // Decoded form 63 static final int FRAGMENT = 1 << 15; 64 static final int FRAGMENT_D = 1 << 16; // Decoded form 65 static final int TOASCII = 1 << 17; 66 static final int IDENT_STR = 1 << 18; // Identities 67 static final int IDENT_URI1 = 1 << 19; 68 static final int IDENT_URI3 = 1 << 20; 69 static final int IDENT_URI5 = 1 << 21; 70 static final int IDENT_URI7 = 1 << 22; 71 static final int TOSTRING = 1 << 23; 72 73 String input; 74 URI uri = null; 75 URI originalURI; 76 URI base = null; // Base for resolution/relativization 77 String op = null; // Op performed if uri != originalURI 78 int checked = 0; // Mask for checked properties 79 int failed = 0; // Mask for failed properties 80 Exception exc = null; 81 82 private Test(String s) { 83 testCount++; 84 input = s; 85 try { 86 uri = new URI(s); 87 } catch (URISyntaxException x) { 88 exc = x; 89 } 90 originalURI = uri; 91 } 92 93 static Test test(String s) { 94 return new Test(s); 95 } 96 97 private Test(String s, String u, String h, int n, 98 String p, String q, String f) 99 { 100 testCount++; 101 try { 102 uri = new URI(s, u, h, n, p, q, f); 103 } catch (URISyntaxException x) { 104 exc = x; 105 input = x.getInput(); 106 } 107 if (uri != null) 108 input = uri.toString(); 109 originalURI = uri; 110 } 111 112 static Test test(String s, String u, String h, int n, 113 String p, String q, String f) { 114 return new Test(s, u, h, n, p, q, f); 115 } 116 117 private Test(String s, String a, 118 String p, String q, String f) 119 { 120 testCount++; 121 try { 122 uri = new URI(s, a, p, q, f); 123 } catch (URISyntaxException x) { 124 exc = x; 125 input = x.getInput(); 126 } 127 if (uri != null) 128 input = uri.toString(); 129 originalURI = uri; 130 } 131 132 static Test test(String s, String a, 133 String p, String q, String f) { 134 return new Test(s, a, p, q, f); 135 } 136 137 private Test(String s, String h, String p, String f) { 138 testCount++; 139 try { 140 uri = new URI(s, h, p, f); 141 } catch (URISyntaxException x) { 142 exc = x; 143 input = x.getInput(); 144 } 145 if (uri != null) 146 input = uri.toString(); 147 originalURI = uri; 148 } 149 150 static Test test(String s, String h, String p, String f) { 151 return new Test(s, h, p, f); 152 } 153 154 private Test(String s, String ssp, String f) { 155 testCount++; 156 try { 157 uri = new URI(s, ssp, f); 158 } catch (URISyntaxException x) { 159 exc = x; 160 input = x.getInput(); 161 } 162 if (uri != null) 163 input = uri.toString(); 164 originalURI = uri; 165 } 166 167 static Test test(String s, String ssp, String f) { 168 return new Test(s, ssp, f); 169 } 170 171 private Test(String s, boolean xxx) { 172 testCount++; 173 try { 174 uri = URI.create(s); 175 } catch (IllegalArgumentException x) { 176 exc = x; 177 } 178 if (uri != null) 179 input = uri.toString(); 180 originalURI = uri; 181 } 182 183 static Test testCreate(String s) { 184 return new Test(s, false); 185 } 186 187 boolean parsed() { 188 return uri != null; 189 } 190 191 boolean resolved() { 192 return base != null; 193 } 194 195 URI uri() { 196 return uri; 197 } 198 199 200 // Operations on Test instances 201 // 202 // These are short so as to make test cases compact. 203 // 204 // s Scheme 205 // sp Scheme-specific part 206 // spd Scheme-specific part, decoded 207 // o Opaque part (isOpaque() && ssp matches) 208 // g reGistry (authority matches, and host is not defined) 209 // gd reGistry, decoded 210 // u User info 211 // ud User info, decoded 212 // h Host 213 // n port Number 214 // p Path 215 // pd Path, decoded 216 // q Query 217 // qd Query, decoded 218 // f Fragment 219 // fd Fragment, decoded 220 // 221 // rslv Resolve against given base 222 // rtvz Relativize 223 // psa Parse server Authority 224 // norm Normalize 225 // ta ASCII form 226 // 227 // x Check that parse failed as expected 228 // z End -- ensure that unchecked components are null 229 230 private boolean check1(int prop) { 231 checked |= prop; 232 if (!parsed()) { 233 failed |= prop; 234 return false; 235 } 236 return true; 237 } 238 239 private void check2(String s, String ans, int prop) { 240 if ((s == null) || !s.equals(ans)) 241 failed |= prop; 242 } 243 244 Test s(String s) { 245 if (check1(SCHEME)) check2(uri.getScheme(), s, SCHEME); 246 return this; 247 } 248 249 Test u(String s) { 250 if (check1(USERINFO)) check2(uri.getRawUserInfo(), s, USERINFO); 251 return this; 252 } 253 254 Test ud(String s) { 255 if (check1(USERINFO_D)) { 256 check2(uri.getUserInfo(), s, USERINFO_D); 257 } 258 return this; 259 } 260 261 Test h(String s) { 262 if (check1(HOST)) check2(uri.getHost(), s, HOST); 263 return this; 264 } 265 266 Test g(String s) { 267 if (check1(REGISTRY)) { 268 if (uri.getHost() != null) 269 failed |= REGISTRY; 270 else 271 check2(uri.getRawAuthority(), s, REGISTRY); 272 } 273 return this; 274 } 275 276 Test gd(String s) { 277 if (check1(REGISTRY_D)) { 278 if (uri.getHost() != null) 279 failed |= REGISTRY_D; 280 else 281 check2(uri.getAuthority(), s, REGISTRY_D); 282 } 283 return this; 284 } 285 286 Test n(int n) { 287 checked |= PORT; 288 if (!parsed() || (uri.getPort() != n)) 289 failed |= PORT; 290 return this; 291 } 292 293 Test p(String s) { 294 if (check1(PATH)) check2(uri.getRawPath(), s, PATH); 295 return this; 296 } 297 298 Test pd(String s) { 299 if (check1(PATH_D)) check2(uri.getPath(), s, PATH_D); 300 return this; 301 } 302 303 Test o(String s) { 304 if (check1(OPAQUEPART)) { 305 if (!uri.isOpaque()) 306 failed |= OPAQUEPART; 307 else 308 check2(uri.getSchemeSpecificPart(), s, OPAQUEPART); 309 } 310 return this; 311 } 312 313 Test sp(String s) { 314 if (check1(SSP)) check2(uri.getRawSchemeSpecificPart(), s, SSP); 315 return this; 316 } 317 318 Test spd(String s) { 319 if (check1(SSP_D)) check2(uri.getSchemeSpecificPart(), s, SSP_D); 320 return this; 321 } 322 323 Test q(String s) { 324 if (check1(QUERY)) check2(uri.getRawQuery(), s, QUERY); 325 return this; 326 } 327 328 Test qd(String s) { 329 if (check1(QUERY_D)) check2(uri.getQuery(), s, QUERY_D); 330 return this; 331 } 332 333 Test f(String s) { 334 if (check1(FRAGMENT)) check2(uri.getRawFragment(), s, FRAGMENT); 335 return this; 336 } 337 338 Test fd(String s) { 339 if (check1(FRAGMENT_D)) check2(uri.getFragment(), s, FRAGMENT_D); 340 return this; 341 } 342 343 Test ta(String s) { 344 if (check1(TOASCII)) 345 check2(uri.toASCIIString(), s, TOASCII); 346 return this; 347 } 348 349 Test ts(String s) { 350 if (check1(TOSTRING)) 351 check2(uri.toString(), s, TOSTRING); 352 return this; 353 } 354 355 Test x() { 356 checked |= PARSEFAIL; 357 if (parsed()) 358 failed |= PARSEFAIL; 359 return this; 360 } 361 362 Test rslv(URI base) { 363 if (!parsed()) 364 return this; 365 this.base = base; 366 op = "rslv"; 367 URI u = uri; 368 uri = null; 369 try { 370 this.uri = base.resolve(u); 371 } catch (IllegalArgumentException x) { 372 exc = x; 373 } 374 checked = 0; 375 failed = 0; 376 return this; 377 } 378 379 Test norm() { 380 if (!parsed()) 381 return this; 382 op = "norm"; 383 uri = uri.normalize(); 384 return this; 385 } 386 387 Test rtvz(URI base) { 388 if (!parsed()) 389 return this; 390 this.base = base; 391 op = "rtvz"; 392 uri = base.relativize(uri); 393 checked = 0; 394 failed = 0; 395 return this; 396 } 397 398 Test psa() { 399 try { 400 uri.parseServerAuthority(); 401 } catch (URISyntaxException x) { 402 exc = x; 403 uri = null; 404 } 405 checked = 0; 406 failed = 0; 407 return this; 408 } 409 410 private void checkEmpty(String s, int prop) { 411 if (((checked & prop) == 0) && (s != null)) 412 failed |= prop; 413 } 414 415 // Check identity for the seven-argument URI constructor 416 // 417 void checkURI7() { 418 // Only works on hierarchical URIs 419 if (uri.isOpaque()) 420 return; 421 // Only works with server-based authorities 422 if ((uri.getAuthority() == null) 423 != ((uri.getUserInfo() == null) && (uri.getHost() == null))) 424 return; 425 // Not true if non-US-ASCII chars are encoded unnecessarily 426 if (uri.getPath().indexOf('\u20AC') >= 0) 427 return; 428 try { 429 URI u2 = new URI(uri.getScheme(), uri.getUserInfo(), 430 uri.getHost(), uri.getPort(), uri.getPath(), 431 uri.getQuery(), uri.getFragment()); 432 if (!uri.equals(u2)) 433 failed |= IDENT_URI7; 434 } catch (URISyntaxException x) { 435 failed |= IDENT_URI7; 436 } 437 } 438 439 // Check identity for the five-argument URI constructor 440 // 441 void checkURI5() { 442 // Only works on hierarchical URIs 443 if (uri.isOpaque()) 444 return; 445 try { 446 URI u2 = new URI(uri.getScheme(), uri.getAuthority(), 447 uri.getPath(), uri.getQuery(), uri.getFragment()); 448 if (!uri.equals(u2)) 449 failed |= IDENT_URI5; 450 } catch (URISyntaxException x) { 451 failed |= IDENT_URI5; 452 } 453 } 454 455 // Check identity for the three-argument URI constructor 456 // 457 void checkURI3() { 458 try { 459 URI u2 = new URI(uri.getScheme(), 460 uri.getSchemeSpecificPart(), 461 uri.getFragment()); 462 if (!uri.equals(u2)) 463 failed |= IDENT_URI3; 464 } catch (URISyntaxException x) { 465 failed |= IDENT_URI3; 466 } 467 } 468 469 // Check all identities mentioned in the URI class specification 470 // 471 void checkIdentities() { 472 if (input != null) { 473 if (!uri.toString().equals(input)) 474 failed |= IDENT_STR; 475 } 476 try { 477 if (!(new URI(uri.toString())).equals(uri)) 478 failed |= IDENT_URI1; 479 } catch (URISyntaxException x) { 480 failed |= IDENT_URI1; 481 } 482 483 // Remaining identities fail if "//" given but authority is undefined 484 if ((uri.getAuthority() == null) 485 && (uri.getSchemeSpecificPart() != null) 486 && (uri.getSchemeSpecificPart().startsWith("///") 487 || uri.getSchemeSpecificPart().startsWith("//?") 488 || uri.getSchemeSpecificPart().equals("//"))) 489 return; 490 491 // Remaining identities fail if ":" given but port is undefined 492 if ((uri.getHost() != null) 493 && (uri.getAuthority() != null) 494 && (uri.getAuthority().equals(uri.getHost() + ":"))) 495 return; 496 497 // Remaining identities fail if non-US-ASCII chars are encoded 498 // unnecessarily 499 if ((uri.getPath() != null) && uri.getPath().indexOf('\u20AC') >= 0) 500 return; 501 502 checkURI3(); 503 checkURI5(); 504 checkURI7(); 505 } 506 507 // Check identities, check that unchecked component properties are not 508 // defined, and report any failures 509 // 510 Test z() { 511 if (!parsed()) { 512 report(); 513 return this; 514 } 515 516 if (op == null) 517 checkIdentities(); 518 519 // Check that unchecked components are undefined 520 checkEmpty(uri.getScheme(), SCHEME); 521 checkEmpty(uri.getUserInfo(), USERINFO); 522 checkEmpty(uri.getHost(), HOST); 523 if (((checked & PORT) == 0) && (uri.getPort() != -1)) failed |= PORT; 524 checkEmpty(uri.getPath(), PATH); 525 checkEmpty(uri.getQuery(), QUERY); 526 checkEmpty(uri.getFragment(), FRAGMENT); 527 528 // Report failures 529 report(); 530 return this; 531 } 532 533 534 // Summarization and reporting 535 536 static void header(String s) { 537 out.println(); 538 out.println(); 539 out.println("-- " + s + " --"); 540 } 541 542 static void show(String prefix, URISyntaxException x) { 543 out.println(uquote(x.getInput())); 544 if (x.getIndex() >= 0) { 545 for (int i = 0; i < x.getIndex(); i++) { 546 if (x.getInput().charAt(i) >= '\u0080') 547 out.print(" "); // Skip over \u1234 548 else 549 out.print(" "); 550 } 551 out.println("^"); 552 } 553 out.println(prefix + ": " + x.getReason()); 554 } 555 556 private void summarize() { 557 out.println(); 558 StringBuffer sb = new StringBuffer(); 559 if (input.length() == 0) 560 sb.append("\"\""); 561 else 562 sb.append(input); 563 if (base != null) { 564 sb.append(" "); 565 sb.append(base); 566 } 567 if (!parsed()) { 568 String s = (((checked & PARSEFAIL) != 0) 569 ? "Correct exception" : "UNEXPECTED EXCEPTION"); 570 if (exc instanceof URISyntaxException) 571 show(s, (URISyntaxException)exc); 572 else { 573 out.println(uquote(sb.toString())); 574 out.print(s + ": "); 575 exc.printStackTrace(out); 576 } 577 } else { 578 if (uri != originalURI) { 579 sb.append(" "); 580 sb.append(op); 581 sb.append(" --> "); 582 sb.append(uri); 583 } 584 out.println(uquote(sb.toString())); 585 } 586 } 587 588 public static String uquote(String str) { 589 if (str == null) 590 return str; 591 StringBuffer sb = new StringBuffer(); 592 int n = str.length(); 593 for (int i = 0; i < n; i++) { 594 char c = str.charAt(i); 595 if ((c >= ' ') && (c < 0x7f)) { 596 sb.append(c); 597 continue; 598 } 599 sb.append("\\u"); 600 String s = Integer.toHexString(c).toUpperCase(); 601 while (s.length() < 4) 602 s = "0" + s; 603 sb.append(s); 604 } 605 return sb.toString(); 606 } 607 608 static void show(String n, String v) { 609 out.println(" " + n 610 + " = ".substring(n.length()) 611 + uquote(v)); 612 } 613 614 static void show(String n, String v, String vd) { 615 if ((v == null) || v.equals(vd)) 616 show(n, v); 617 else { 618 out.println(" " + n 619 + " = ".substring(n.length()) 620 + uquote(v) 621 + " = " + uquote(vd)); 622 } 623 } 624 625 public static void show(URI u) { 626 show("opaque", "" + u.isOpaque()); 627 show("scheme", u.getScheme()); 628 show("ssp", u.getRawSchemeSpecificPart(), u.getSchemeSpecificPart()); 629 show("authority", u.getRawAuthority(), u.getAuthority()); 630 show("userinfo", u.getRawUserInfo(), u.getUserInfo()); 631 show("host", u.getHost()); 632 show("port", "" + u.getPort()); 633 show("path", u.getRawPath(), u.getPath()); 634 show("query", u.getRawQuery(), u.getQuery()); 635 show("fragment", u.getRawFragment(), u.getFragment()); 636 if (!u.toString().equals(u.toASCIIString())) 637 show("toascii", u.toASCIIString()); 638 } 639 640 private void report() { 641 summarize(); 642 if (failed == 0) return; 643 StringBuffer sb = new StringBuffer(); 644 sb.append("FAIL:"); 645 if ((failed & PARSEFAIL) != 0) sb.append(" parsefail"); 646 if ((failed & SCHEME) != 0) sb.append(" scheme"); 647 if ((failed & SSP) != 0) sb.append(" ssp"); 648 if ((failed & OPAQUEPART) != 0) sb.append(" opaquepart"); 649 if ((failed & USERINFO) != 0) sb.append(" userinfo"); 650 if ((failed & USERINFO_D) != 0) sb.append(" userinfod"); 651 if ((failed & HOST) != 0) sb.append(" host"); 652 if ((failed & PORT) != 0) sb.append(" port"); 653 if ((failed & REGISTRY) != 0) sb.append(" registry"); 654 if ((failed & PATH) != 0) sb.append(" path"); 655 if ((failed & PATH_D) != 0) sb.append(" pathd"); 656 if ((failed & QUERY) != 0) sb.append(" query"); 657 if ((failed & QUERY_D) != 0) sb.append(" queryd"); 658 if ((failed & FRAGMENT) != 0) sb.append(" fragment"); 659 if ((failed & FRAGMENT_D) != 0) sb.append(" fragmentd"); 660 if ((failed & TOASCII) != 0) sb.append(" toascii"); 661 if ((failed & IDENT_STR) != 0) sb.append(" ident-str"); 662 if ((failed & IDENT_URI1) != 0) sb.append(" ident-uri1"); 663 if ((failed & IDENT_URI3) != 0) sb.append(" ident-uri3"); 664 if ((failed & IDENT_URI5) != 0) sb.append(" ident-uri5"); 665 if ((failed & IDENT_URI7) != 0) sb.append(" ident-uri7"); 666 if ((failed & TOSTRING) != 0) sb.append(" tostring"); 667 out.println(sb.toString()); 668 if (uri != null) show(uri); 669 throw new RuntimeException("Test failed"); 670 } 671 672 673 674 // -- Tests -- 675 676 static void rfc2396() { 677 678 679 header("RFC2396: Basic examples"); 680 681 test("ftp://ftp.is.co.za/rfc/rfc1808.txt") 682 .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z(); 683 684 test("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles") 685 .s("gopher").h("spinaltap.micro.umn.edu") 686 .p("/00/Weather/California/Los%20Angeles").z(); 687 688 test("http://www.math.uio.no/faq/compression-faq/part1.html") 689 .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z(); 690 691 test("mailto:mduerst@ifi.unizh.ch") 692 .s("mailto").o("mduerst@ifi.unizh.ch").z(); 693 694 test("news:comp.infosystems.www.servers.unix") 695 .s("news").o("comp.infosystems.www.servers.unix").z(); 696 697 test("telnet://melvyl.ucop.edu/") 698 .s("telnet").h("melvyl.ucop.edu").p("/").z(); 699 700 test("http://www.w3.org/Addressing/") 701 .s("http").h("www.w3.org").p("/Addressing/").z(); 702 703 test("ftp://ds.internic.net/rfc/") 704 .s("ftp").h("ds.internic.net").p("/rfc/").z(); 705 706 test("http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING") 707 .s("http").h("www.ics.uci.edu").p("/pub/ietf/uri/historical.html") 708 .f("WARNING").z(); 709 710 test("http://www.ics.uci.edu/pub/ietf/uri/#Related") 711 .s("http").h("www.ics.uci.edu").p("/pub/ietf/uri/") 712 .f("Related").z(); 713 714 715 header("RFC2396: Normal relative-URI examples (appendix C)"); 716 717 URI base = (test("http://a/b/c/d;p?q") 718 .s("http").h("a").p("/b/c/d;p").q("q").z().uri()); 719 720 // g:h g:h 721 test("g:h") 722 .s("g").o("h").z() 723 .rslv(base).s("g").o("h").z(); 724 725 // g http://a/b/c/g 726 test("g") 727 .p("g").z() 728 .rslv(base).s("http").h("a").p("/b/c/g").z(); 729 730 // ./g http://a/b/c/g 731 test("./g") 732 .p("./g").z() 733 .rslv(base).s("http").h("a").p("/b/c/g").z(); 734 735 // g/ http://a/b/c/g/ 736 test("g/") 737 .p("g/").z() 738 .rslv(base).s("http").h("a").p("/b/c/g/").z(); 739 740 // /g http://a/g 741 test("/g") 742 .p("/g").z() 743 .rslv(base).s("http").h("a").p("/g").z(); 744 745 // //g http://g 746 test("//g") 747 .h("g").p("").z() 748 .rslv(base).s("http").h("g").p("").z(); 749 750 // ?y http://a/b/c/?y 751 test("?y") 752 .p("").q("y").z() 753 .rslv(base).s("http").h("a").p("/b/c/").q("y").z(); 754 755 // g?y http://a/b/c/g?y 756 test("g?y") 757 .p("g").q("y").z() 758 .rslv(base).s("http").h("a").p("/b/c/g").q("y").z(); 759 760 // #s (current document)#s 761 // DEVIATION: Lone fragment parses as relative URI with empty path 762 test("#s") 763 .p("").f("s").z() 764 .rslv(base).s("http").h("a").p("/b/c/d;p").f("s").q("q").z(); 765 766 // g#s http://a/b/c/g#s 767 test("g#s") 768 .p("g").f("s").z() 769 .rslv(base).s("http").h("a").p("/b/c/g").f("s").z(); 770 771 // g?y#s http://a/b/c/g?y#s 772 test("g?y#s") 773 .p("g").q("y").f("s").z() 774 .rslv(base).s("http").h("a").p("/b/c/g").q("y").f("s").z(); 775 776 // ;x http://a/b/c/;x 777 test(";x") 778 .p(";x").z() 779 .rslv(base).s("http").h("a").p("/b/c/;x").z(); 780 781 // g;x http://a/b/c/g;x 782 test("g;x") 783 .p("g;x").z() 784 .rslv(base).s("http").h("a").p("/b/c/g;x").z(); 785 786 // g;x?y#s http://a/b/c/g;x?y#s 787 test("g;x?y#s") 788 .p("g;x").q("y").f("s").z() 789 .rslv(base).s("http").h("a").p("/b/c/g;x").q("y").f("s").z(); 790 791 // . http://a/b/c/ 792 test(".") 793 .p(".").z() 794 .rslv(base).s("http").h("a").p("/b/c/").z(); 795 796 // ./ http://a/b/c/ 797 test("./") 798 .p("./").z() 799 .rslv(base).s("http").h("a").p("/b/c/").z(); 800 801 // .. http://a/b/ 802 test("..") 803 .p("..").z() 804 .rslv(base).s("http").h("a").p("/b/").z(); 805 806 // ../ http://a/b/ 807 test("../") 808 .p("../").z() 809 .rslv(base).s("http").h("a").p("/b/").z(); 810 811 // ../g http://a/b/g 812 test("../g") 813 .p("../g").z() 814 .rslv(base).s("http").h("a").p("/b/g").z(); 815 816 // ../.. http://a/ 817 test("../..") 818 .p("../..").z() 819 .rslv(base).s("http").h("a").p("/").z(); 820 821 // ../../ http://a/ 822 test("../../") 823 .p("../../").z() 824 .rslv(base).s("http").h("a").p("/").z(); 825 826 // ../../g http://a/g 827 test("../../g") 828 .p("../../g").z() 829 .rslv(base).s("http").h("a").p("/g").z(); 830 831 832 header("RFC2396: Abnormal relative-URI examples (appendix C)"); 833 834 // ../../../g = http://a/../g 835 test("../../../g") 836 .p("../../../g").z() 837 .rslv(base).s("http").h("a").p("/../g").z(); 838 839 // ../../../../g = http://a/../../g 840 test("../../../../g") 841 .p("../../../../g").z() 842 .rslv(base).s("http").h("a").p("/../../g").z(); 843 844 845 // /./g = http://a/./g 846 test("/./g") 847 .p("/./g").z() 848 .rslv(base).s("http").h("a").p("/./g").z(); 849 850 // /../g = http://a/../g 851 test("/../g") 852 .p("/../g").z() 853 .rslv(base).s("http").h("a").p("/../g").z(); 854 855 // g. = http://a/b/c/g. 856 test("g.") 857 .p("g.").z() 858 .rslv(base).s("http").h("a").p("/b/c/g.").z(); 859 860 // .g = http://a/b/c/.g 861 test(".g") 862 .p(".g").z() 863 .rslv(base).s("http").h("a").p("/b/c/.g").z(); 864 865 // g.. = http://a/b/c/g.. 866 test("g..") 867 .p("g..").z() 868 .rslv(base).s("http").h("a").p("/b/c/g..").z(); 869 870 // ..g = http://a/b/c/..g 871 test("..g") 872 .p("..g").z() 873 .rslv(base).s("http").h("a").p("/b/c/..g").z(); 874 875 // ./../g = http://a/b/g 876 test("./../g") 877 .p("./../g").z() 878 .rslv(base).s("http").h("a").p("/b/g").z(); 879 880 // ./g/. = http://a/b/c/g/ 881 test("./g/.") 882 .p("./g/.").z() 883 .rslv(base).s("http").h("a").p("/b/c/g/").z(); 884 885 // g/./h = http://a/b/c/g/h 886 test("g/./h") 887 .p("g/./h").z() 888 .rslv(base).s("http").h("a").p("/b/c/g/h").z(); 889 890 // g/../h = http://a/b/c/h 891 test("g/../h") 892 .p("g/../h").z() 893 .rslv(base).s("http").h("a").p("/b/c/h").z(); 894 895 // g;x=1/./y = http://a/b/c/g;x=1/y 896 test("g;x=1/./y") 897 .p("g;x=1/./y").z() 898 .rslv(base).s("http").h("a").p("/b/c/g;x=1/y").z(); 899 900 // g;x=1/../y = http://a/b/c/y 901 test("g;x=1/../y") 902 .p("g;x=1/../y").z() 903 .rslv(base).s("http").h("a").p("/b/c/y").z(); 904 905 // g?y/./x = http://a/b/c/g?y/./x 906 test("g?y/./x") 907 .p("g").q("y/./x").z() 908 .rslv(base).s("http").h("a").p("/b/c/g").q("y/./x").z(); 909 910 // g?y/../x = http://a/b/c/g?y/../x 911 test("g?y/../x") 912 .p("g").q("y/../x").z() 913 .rslv(base).s("http").h("a").p("/b/c/g").q("y/../x").z(); 914 915 // g#s/./x = http://a/b/c/g#s/./x 916 test("g#s/./x") 917 .p("g").f("s/./x").z() 918 .rslv(base).s("http").h("a").p("/b/c/g").f("s/./x").z(); 919 920 // g#s/../x = http://a/b/c/g#s/../x 921 test("g#s/../x") 922 .p("g").f("s/../x").z() 923 .rslv(base).s("http").h("a").p("/b/c/g").f("s/../x").z(); 924 925 // http:g = http:g 926 test("http:g") 927 .s("http").o("g").z() 928 .rslv(base).s("http").o("g").z(); 929 930 } 931 932 933 static void ip() { 934 935 header("IP addresses"); 936 937 test("http://1.2.3.4:5") 938 .s("http").h("1.2.3.4").n(5).p("").z(); 939 940 // From RFC2732 941 942 test("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html") 943 .s("http").h("[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]") 944 .n(80).p("/index.html").z(); 945 946 test("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:10%12]:80/index.html") 947 .s("http").h("[FEDC:BA98:7654:3210:FEDC:BA98:7654:10%12]") 948 .n(80).p("/index.html").z(); 949 950 test("http://[1080:0:0:0:8:800:200C:417A]/index.html") 951 .s("http").h("[1080:0:0:0:8:800:200C:417A]").p("/index.html").z(); 952 953 test("http://[1080:0:0:0:8:800:200C:417A%1]/index.html") 954 .s("http").h("[1080:0:0:0:8:800:200C:417A%1]").p("/index.html").z(); 955 956 test("http://[3ffe:2a00:100:7031::1]") 957 .s("http").h("[3ffe:2a00:100:7031::1]").p("").z(); 958 959 test("http://[1080::8:800:200C:417A]/foo") 960 .s("http").h("[1080::8:800:200C:417A]").p("/foo").z(); 961 962 test("http://[::192.9.5.5]/ipng") 963 .s("http").h("[::192.9.5.5]").p("/ipng").z(); 964 965 test("http://[::192.9.5.5%interface]/ipng") 966 .s("http").h("[::192.9.5.5%interface]").p("/ipng").z(); 967 968 test("http://[::FFFF:129.144.52.38]:80/index.html") 969 .s("http").h("[::FFFF:129.144.52.38]").n(80).p("/index.html").z(); 970 971 test("http://[2010:836B:4179::836B:4179]") 972 .s("http").h("[2010:836B:4179::836B:4179]").p("").z(); 973 974 // From RFC2373 975 976 test("http://[FF01::101]") 977 .s("http").h("[FF01::101]").p("").z(); 978 979 test("http://[::1]") 980 .s("http").h("[::1]").p("").z(); 981 982 test("http://[::]") 983 .s("http").h("[::]").p("").z(); 984 985 test("http://[::%hme0]") 986 .s("http").h("[::%hme0]").p("").z(); 987 988 test("http://[0:0:0:0:0:0:13.1.68.3]") 989 .s("http").h("[0:0:0:0:0:0:13.1.68.3]").p("").z(); 990 991 test("http://[0:0:0:0:0:FFFF:129.144.52.38]") 992 .s("http").h("[0:0:0:0:0:FFFF:129.144.52.38]").p("").z(); 993 994 test("http://[0:0:0:0:0:FFFF:129.144.52.38%33]") 995 .s("http").h("[0:0:0:0:0:FFFF:129.144.52.38%33]").p("").z(); 996 997 test("http://[0:0:0:0:0:ffff:1.2.3.4]") 998 .s("http").h("[0:0:0:0:0:ffff:1.2.3.4]").p("").z(); 999 1000 test("http://[::13.1.68.3]") 1001 .s("http").h("[::13.1.68.3]").p("").z(); 1002 1003 // Optional IPv6 brackets in constructors 1004 1005 test("s", null, "1:2:3:4:5:6:7:8", -1, null, null, null) 1006 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1007 1008 test("s", null, "[1:2:3:4:5:6:7:8]", -1, null, null, null) 1009 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1010 1011 test("s", null, "[1:2:3:4:5:6:7:8]", -1, null, null, null) 1012 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1013 1014 test("s", "1:2:3:4:5:6:7:8", null, null) 1015 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1016 1017 test("s", "1:2:3:4:5:6:7:8%hme0", null, null) 1018 .s("s").h("[1:2:3:4:5:6:7:8%hme0]").p("").z(); 1019 1020 test("s", "1:2:3:4:5:6:7:8%1", null, null) 1021 .s("s").h("[1:2:3:4:5:6:7:8%1]").p("").z(); 1022 1023 test("s", "[1:2:3:4:5:6:7:8]", null, null) 1024 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1025 1026 test("s", "[1:2:3:4:5:6:7:8]", null, null, null) 1027 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z(); 1028 1029 test("s", "1:2:3:4:5:6:7:8", null, null, null) 1030 .s("s").g("1:2:3:4:5:6:7:8").p("").z(); 1031 1032 // Error cases 1033 1034 test("http://[ff01:234/foo").x().z(); 1035 test("http://[ff01:234:zzz]/foo").x().z(); 1036 test("http://[foo]").x().z(); 1037 test("http://[]").x().z(); 1038 test("http://[129.33.44.55]").x().z(); 1039 test("http://[ff:ee:dd:cc:bb::aa:9:8]").x().z(); 1040 test("http://[fffff::1]").x().z(); 1041 test("http://[ff::ee::8]").x().z(); 1042 test("http://[1:2:3:4::5:6:7:8]").x().z(); 1043 test("http://[1:2]").x().z(); 1044 test("http://[1:2:3:4:5:6:7:8:9]").x().z(); 1045 test("http://[1:2:3:4:5:6:7:8%]").x().z(); 1046 test("http://[1:2:3:4:5:6:7:8%!/]").x().z(); 1047 test("http://[::1.2.3.300]").x().z(); 1048 test("http://1.2.3").psa().x().z(); 1049 test("http://1.2.3.300").psa().x().z(); 1050 test("http://1.2.3.4.5").psa().x().z(); 1051 test("http://[1.2.3.4:5]").x().z(); 1052 test("http://1:2:3:4:5:6:7:8").psa().x().z(); 1053 test("http://[1.2.3.4]/").x().z(); 1054 test("http://[1.2.3.4/").x().z(); 1055 test("http://[foo]/").x().z(); 1056 test("http://[foo/").x().z(); 1057 test("s", "[foo]", "/", null, null).x().z(); 1058 test("s", "[foo", "/", null, null).x().z(); 1059 test("s", "[::foo", "/", null, null).x().z(); 1060 1061 // Test hostnames that might initially look like IPv4 addresses 1062 1063 test("s://1.2.3.com").psa().s("s").h("1.2.3.com").p("").z(); 1064 test("s://1.2.3.4me.com").psa().s("s").h("1.2.3.4me.com").p("").z(); 1065 1066 test("s://7up.com").psa().s("s").h("7up.com").p("").z(); 1067 test("s://7up.com/p").psa().s("s").h("7up.com").p("/p").z(); 1068 test("s://7up").psa().s("s").h("7up").p("").z(); 1069 test("s://7up/p").psa().s("s").h("7up").p("/p").z(); 1070 test("s://7up.").psa().s("s").h("7up.").p("").z(); 1071 test("s://7up./p").psa().s("s").h("7up.").p("/p").z(); 1072 } 1073 1074 1075 static void misc() throws URISyntaxException { 1076 1077 URI base = new URI("s://h/a/b"); 1078 URI rbase = new URI("a/b/c/d"); 1079 1080 1081 header("Corner cases"); 1082 1083 // The empty URI parses as a relative URI with an empty path 1084 test("").p("").z() 1085 .rslv(base).s("s").h("h").p("/a/").z(); 1086 1087 // Resolving solo queries and fragments 1088 test("#f").p("").f("f").z() 1089 .rslv(base).s("s").h("h").p("/a/b").f("f").z(); 1090 test("?q").p("").q("q").z() 1091 .rslv(base).s("s").h("h").p("/a/").q("q").z(); 1092 1093 // Fragment is not part of ssp 1094 test("p#f").p("p").f("f").sp("p").z(); 1095 test("s:p#f").s("s").o("p").f("f").z(); 1096 test("p#f") 1097 .rslv(base).s("s").h("h").p("/a/p").f("f").sp("//h/a/p").z(); 1098 test("").p("").sp("").z(); 1099 1100 1101 1102 header("Emptiness"); 1103 1104 // Components that may be empty 1105 test("///p").p("/p").z(); // Authority (w/ path) 1106 test("//@h/p").u("").h("h").p("/p").z(); // User info 1107 test("//h:/p").h("h").p("/p").z(); // Port 1108 test("//h").h("h").p("").z(); // Path 1109 test("//h?q").h("h").p("").q("q").z(); // Path (w/query) 1110 test("//?q").p("").q("q").z(); // Authority (w/query) 1111 test("//#f").p("").f("f").z(); // Authority (w/fragment) 1112 test("p?#").p("p").q("").f("").z(); // Query & fragment 1113 1114 // Components that may not be empty 1115 test(":").x().z(); // Scheme 1116 test("x:").x().z(); // Hier/opaque 1117 test("//").x().z(); // Authority (w/o path) 1118 1119 1120 header("Resolution, normalization, and relativization"); 1121 1122 // Resolving relative paths 1123 test("../e/f").p("../e/f").z() 1124 .rslv(rbase).p("a/b/e/f").z(); 1125 test("../../../../d").p("../../../../d").z() 1126 .rslv(rbase).p("../d").z(); 1127 test("../../../d:e").p("../../../d:e").z() 1128 .rslv(rbase).p("./d:e").z(); 1129 test("../../../d:e/f").p("../../../d:e/f").z() 1130 .rslv(rbase).p("./d:e/f").z(); 1131 1132 // Normalization 1133 test("a/./c/../d/f").p("a/./c/../d/f").z() 1134 .norm().p("a/d/f").z(); 1135 test("http://a/./b/c/../d?q#f") 1136 .s("http").h("a").p("/./b/c/../d").q("q").f("f").z() 1137 .norm().s("http").h("a").p("/b/d").q("q").f("f").z(); 1138 test("a/../b").p("a/../b").z(). 1139 norm().p("b"); 1140 test("a/../b:c").p("a/../b:c").z() 1141 .norm().p("./b:c").z(); 1142 1143 // Normalization of already normalized URI should yield the 1144 // same URI 1145 URI u1 = URI.create("s://h/../p"); 1146 URI u2 = u1.normalize(); 1147 eq(u1, u2); 1148 eqeq(u1, u2); 1149 1150 // Relativization 1151 test("/a/b").p("/a/b").z() 1152 .rtvz(new URI("/a")).p("b").z(); 1153 test("/a/b").p("/a/b").z() 1154 .rtvz(new URI("/a/")).p("b").z(); 1155 test("a/b").p("a/b").z() 1156 .rtvz(new URI("a")).p("b").z(); 1157 test("/a/b").p("/a/b").z() 1158 .rtvz(new URI("/a/b")).p("").z(); // Result is empty path 1159 test("a/../b:c/d").p("a/../b:c/d").z() 1160 .rtvz(new URI("./b:c/")).p("d").z(); 1161 1162 test("http://a/b/d/e?q#f") 1163 .s("http").h("a").p("/b/d/e").q("q").f("f").z() 1164 .rtvz(new URI("http://a/b/?r#g")) 1165 .p("d/e").q("q").f("f").z(); 1166 1167 // parseServerAuthority 1168 test("/a/b").psa().p("/a/b").z(); 1169 test("s://u@h:1/p") 1170 .psa().s("s").u("u").h("h").n(1).p("/p").z(); 1171 test("s://u@h:-foo/p").s("s").g("u@h:-foo").p("/p").z() 1172 .psa().x().z(); 1173 test("s://h:999999999999999999999999").psa().x().z(); 1174 test("s://:/b").psa().x().z(); 1175 1176 1177 header("Constructors and factories"); 1178 1179 test("s", null, null, -1, "p", null, null).x().z(); 1180 test(null, null, null, -1, null, null, null).p("").z(); 1181 test(null, null, null, -1, "p", null, null).p("p").z(); 1182 test(null, null, "foo%20bar", -1, null, null, null).x().z(); 1183 test(null, null, "foo", -100, null, null, null).x().z(); 1184 test("s", null, null, -1, "", null, null).x().z(); 1185 test("s", null, null, -1, "/p", null, null).s("s").p("/p").z(); 1186 test("s", "u", "h", 10, "/p", "q", "f") 1187 .s("s").u("u").h("h").n(10).p("/p").q("q").f("f").z(); 1188 test("s", "a:b", "/p", "q", "f") 1189 .s("s").g("a:b").p("/p").q("q").f("f").z(); 1190 test("s", "h", "/p", "f") 1191 .s("s").h("h").p("/p").f("f").z(); 1192 test("s", "p", "f").s("s").o("p").f("f").z(); 1193 test("s", "/p", "f").s("s").p("/p").f("f").z(); 1194 testCreate("s://u@h/p?q#f") 1195 .s("s").u("u").h("h").p("/p").q("q").f("f").z(); 1196 } 1197 1198 static void npes() throws URISyntaxException { 1199 1200 header("NullPointerException"); 1201 1202 URI base = URI.create("mailto:root@foobar.com"); 1203 1204 out.println(); 1205 1206 try { 1207 base.resolve((URI)null); 1208 throw new RuntimeException("NullPointerException not thrown"); 1209 } catch (NullPointerException x) { 1210 out.println("resolve((URI)null) -->"); 1211 out.println("Correct exception: " + x); 1212 } 1213 1214 out.println(); 1215 1216 try { 1217 base.resolve((String)null); 1218 throw new RuntimeException("NullPointerException not thrown"); 1219 } catch (NullPointerException x) { 1220 out.println("resolve((String)null) -->"); 1221 out.println("Correct exception: " + x); 1222 } 1223 1224 out.println(); 1225 1226 try { 1227 base.relativize((URI)null); 1228 throw new RuntimeException("NullPointerException not thrown"); 1229 } catch (NullPointerException x) { 1230 out.println("relativize((String)null) -->"); 1231 out.println("Correct exception: " + x); 1232 } 1233 1234 testCount += 3; 1235 } 1236 1237 1238 static void chars() throws URISyntaxException { 1239 1240 header("Escapes and non-US-ASCII characters"); 1241 1242 URI uri; 1243 1244 // Escape pairs 1245 test("%0a%0A%0f%0F%01%09zz") 1246 .p("%0a%0A%0f%0F%01%09zz").z(); 1247 test("foo%1").x().z(); 1248 test("foo%z").x().z(); 1249 test("foo%9z").x().z(); 1250 1251 // Escapes not permitted in scheme, host 1252 test("s%20t://a").x().z(); 1253 test("//a%20b").g("a%20b").p("").z(); // Parses as registry 1254 1255 // Escapes permitted in opaque part, userInfo, registry, path, 1256 // query, and fragment 1257 test("//u%20v@a").u("u%20v").h("a").p("").z(); 1258 test("/p%20q").p("/p%20q").z(); 1259 test("/p?q%20").p("/p").q("q%20").z(); 1260 test("/p#%20f").p("/p").f("%20f").z(); 1261 1262 // Non-US-ASCII chars 1263 test("s\u00a7t://a").x().z(); 1264 test("//\u00a7/b").g("\u00a7").p("/b").z(); // Parses as registry 1265 test("//u\u00a7v@a").u("u\u00a7v").h("a").p("").z(); 1266 test("/p\u00a7q").p("/p\u00a7q").z(); 1267 test("/p?q\u00a7").p("/p").q("q\u00a7").z(); 1268 test("/p#\u00a7f").p("/p").f("\u00a7f").z(); 1269 1270 // 4648111 - Escapes quoted by toString after resolution 1271 uri = new URI("http://a/b/c/d;p?q"); 1272 test("/p%20p") 1273 .rslv(uri).s("http").h("a").p("/p%20p").ts("http://a/p%20p").z(); 1274 1275 // 4464135: Forbid unwise characters throughout opaque part 1276 test("foo:x{bar").x().z(); 1277 test("foo:{bar").x().z(); 1278 1279 // 4438319: Single-argument constructor requires quotation, 1280 // preserves escapes 1281 test("//u%01@h/a/b/%02/c?q%03#f%04") 1282 .u("u%01").ud("u\1") 1283 .h("h") 1284 .p("/a/b/%02/c").pd("/a/b/\2/c") 1285 .q("q%03").qd("q\3") 1286 .f("f%04").fd("f\4") 1287 .z(); 1288 test("/a/b c").x().z(); 1289 1290 // 4438319: Multi-argument constructors quote illegal chars and 1291 // preserve legal non-ASCII chars 1292 // \uA001-\uA009 are visible characters, \u2000 is a space character 1293 test(null, "u\uA001\1", "h", -1, 1294 "/p% \uA002\2\u2000", 1295 "q% \uA003\3\u2000", 1296 "f% \uA004\4\u2000") 1297 .u("u\uA001%01").h("h") 1298 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000") 1299 .q("q%25%20\uA003%03%E2%80%80").qd("q% \uA003\3\u2000") 1300 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z(); 1301 test(null, "g\uA001\1", 1302 "/p% \uA002\2\u2000", 1303 "q% \uA003\3\u2000", 1304 "f% \uA004\4\u2000") 1305 .g("g\uA001%01") 1306 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000") 1307 .q("q%25%20\uA003%03%E2%80%80").qd("q% \uA003\3\u2000") 1308 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z(); 1309 test(null, null, "/p% \uA002\2\u2000", "f% \uA004\4\u2000") 1310 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000") 1311 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z(); 1312 test(null, "/sp% \uA001\1\u2000", "f% \uA004\4\u2000") 1313 .sp("/sp%25%20\uA001%01%E2%80%80").spd("/sp% \uA001\1\u2000") 1314 .p("/sp%25%20\uA001%01%E2%80%80").pd("/sp% \uA001\1\u2000") 1315 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z(); 1316 1317 // 4438319: Non-raw accessors decode all escaped octets 1318 test("/%25%20%E2%82%AC%E2%80%80") 1319 .p("/%25%20%E2%82%AC%E2%80%80").pd("/% \u20Ac\u2000").z(); 1320 1321 // 4438319: toASCIIString 1322 test("/\uCAFE\uBABE") 1323 .p("/\uCAFE\uBABE").ta("/%EC%AB%BE%EB%AA%BE").z(); 1324 1325 // 4991359 and 4866303: bad quoting by defineSchemeSpecificPart() 1326 URI base = new URI ("http://host/foo%20bar/a/b/c/d"); 1327 test ("resolve") 1328 .rslv(base).spd("//host/foo bar/a/b/c/resolve") 1329 .sp("//host/foo%20bar/a/b/c/resolve").s("http") 1330 .pd("/foo bar/a/b/c/resolve").h("host") 1331 .p("/foo%20bar/a/b/c/resolve").z(); 1332 1333 // 6773270: java.net.URI fails to escape u0000 1334 test("s", "a", "/\u0000", null) 1335 .s("s").p("/%00").h("a") 1336 .ta("s://a/%00").z(); 1337 } 1338 1339 1340 static void eq0(Comparable u, Comparable v) throws URISyntaxException { 1341 testCount++; 1342 if (!u.equals(v)) 1343 throw new RuntimeException("Not equal: " + u + " " + v); 1344 int uh = u.hashCode(); 1345 int vh = v.hashCode(); 1346 if (uh != vh) 1347 throw new RuntimeException("Hash codes not equal: " 1348 + u + " " + Integer.toHexString(uh) + " " 1349 + v + " " + Integer.toHexString(vh)); 1350 out.println(); 1351 out.println(u + " == " + v 1352 + " [" + Integer.toHexString(uh) + "]"); 1353 } 1354 1355 static void cmp0(Comparable u, Comparable v, boolean same) 1356 throws URISyntaxException 1357 { 1358 int c = u.compareTo(v); 1359 if ((c == 0) != same) 1360 throw new RuntimeException("Comparison inconsistent: " + u + " " + v 1361 + " " + c); 1362 } 1363 1364 static void eq(Comparable u, Comparable v) throws URISyntaxException { 1365 eq0(u, v); 1366 cmp0(u, v, true); 1367 } 1368 1369 static void eqeq(Comparable u, Comparable v) { 1370 testCount++; 1371 if (u != v) 1372 throw new RuntimeException("Not ==: " + u + " " + v); 1373 } 1374 1375 static void ne0(Comparable u, Comparable v) throws URISyntaxException { 1376 testCount++; 1377 if (u.equals(v)) 1378 throw new RuntimeException("Equal: " + u + " " + v); 1379 out.println(); 1380 out.println(u + " != " + v 1381 + " [" + Integer.toHexString(u.hashCode()) 1382 + " " + Integer.toHexString(v.hashCode()) 1383 + "]"); 1384 } 1385 1386 static void ne(Comparable u, Comparable v) throws URISyntaxException { 1387 ne0(u, v); 1388 cmp0(u, v, false); 1389 } 1390 1391 static void lt(Comparable u, Comparable v) throws URISyntaxException { 1392 ne0(u, v); 1393 int c = u.compareTo(v); 1394 if (c >= 0) { 1395 show((URI)u); 1396 show((URI)v); 1397 throw new RuntimeException("Not less than: " + u + " " + v 1398 + " " + c); 1399 } 1400 out.println(u + " < " + v); 1401 } 1402 1403 static void lt(String s, String t) throws URISyntaxException { 1404 lt(new URI(s), new URI(t)); 1405 } 1406 1407 static void gt(Comparable u, Comparable v) throws URISyntaxException { 1408 lt(v, u); 1409 } 1410 1411 static void eqHashComp() throws URISyntaxException { 1412 1413 header("Equality, hashing, and comparison"); 1414 1415 URI o = new URI("mailto:foo@bar.com"); 1416 URI r = new URI("reg://some%20registry/b/c/d?q#f"); 1417 URI s = new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#f"); 1418 eq(o, o); 1419 lt(o, r); 1420 lt(s, o); 1421 lt(s, r); 1422 eq(o, new URI("MaILto:foo@bar.com")); 1423 gt(o, new URI("mailto:foo@bar.COM")); 1424 eq(r, new URI("rEg://some%20registry/b/c/d?q#f")); 1425 gt(r, new URI("reg://Some%20Registry/b/c/d?q#f")); 1426 gt(r, new URI("reg://some%20registry/b/c/D?q#f")); 1427 eq(s, new URI("hTtP://jag:cafebabe@Java.Sun.COM:94/b/c/d?q#f")); 1428 gt(s, new URI("http://jag:CafeBabe@java.sun.com:94/b/c/d?q#f")); 1429 lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?r#f")); 1430 lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g")); 1431 1432 lt("p", "s:p"); 1433 lt("s:p", "T:p"); 1434 lt("S:p", "t:p"); 1435 lt("s:/p", "s:p"); 1436 lt("s:p", "s:q"); 1437 lt("s:p#f", "s:p#g"); 1438 lt("s://u@h:1", "s://v@h:1"); 1439 lt("s://u@h:1", "s://u@i:1"); 1440 lt("s://u@h:1", "s://v@h:2"); 1441 lt("s://a%20b", "s://a%20c"); 1442 lt("s://a%20b", "s://aab"); 1443 lt("s://AA", "s://A_"); 1444 lt("s:/p", "s:/q"); 1445 lt("s:/p?q", "s:/p?r"); 1446 lt("s:/p#f", "s:/p#g"); 1447 1448 lt("s://h", "s://h/p"); 1449 lt("s://h/p", "s://h/p?q"); 1450 1451 } 1452 1453 1454 static void serial(URI u) throws IOException, URISyntaxException { 1455 1456 ByteArrayOutputStream bo = new ByteArrayOutputStream(); 1457 ObjectOutputStream oo = new ObjectOutputStream(bo); 1458 1459 oo.writeObject(u); 1460 oo.close(); 1461 1462 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); 1463 ObjectInputStream oi = new ObjectInputStream(bi); 1464 try { 1465 Object o = oi.readObject(); 1466 eq(u, (Comparable)o); 1467 } catch (ClassNotFoundException x) { 1468 x.printStackTrace(); 1469 throw new RuntimeException(x.toString()); 1470 } 1471 1472 testCount++; 1473 } 1474 1475 static void serial() throws IOException, URISyntaxException { 1476 header("Serialization"); 1477 1478 serial(URI.create("http://java.sun.com/jdk/1.4?release#beta")); 1479 serial(URI.create("s://h/p").resolve("/long%20path/")); 1480 } 1481 1482 1483 static void urls() throws URISyntaxException { 1484 1485 header("URLs"); 1486 1487 URI uri; 1488 URL url; 1489 boolean caught = false; 1490 1491 out.println(); 1492 uri = new URI("http://a/p?q#f"); 1493 try { 1494 url = uri.toURL(); 1495 } catch (MalformedURLException x) { 1496 throw new RuntimeException(x.toString()); 1497 } 1498 if (!url.toString().equals("http://a/p?q#f")) 1499 throw new RuntimeException("Incorrect URL: " + url); 1500 out.println(uri + " url --> " + url); 1501 1502 out.println(); 1503 uri = new URI("a/b"); 1504 try { 1505 out.println(uri + " url --> "); 1506 url = uri.toURL(); 1507 } catch (IllegalArgumentException x) { 1508 caught = true; 1509 out.println("Correct exception: " + x); 1510 } catch (MalformedURLException x) { 1511 caught = true; 1512 throw new RuntimeException("Incorrect exception: " + x); 1513 } 1514 if (!caught) 1515 throw new RuntimeException("Incorrect URL: " + url); 1516 1517 out.println(); 1518 uri = new URI("foo://bar/baz"); 1519 caught = false; 1520 try { 1521 out.println(uri + " url --> "); 1522 url = uri.toURL(); 1523 } catch (MalformedURLException x) { 1524 caught = true; 1525 out.println("Correct exception: " + x); 1526 } catch (IllegalArgumentException x) { 1527 caught = true; 1528 throw new RuntimeException("Incorrect exception: " + x); 1529 } 1530 if (!caught) 1531 throw new RuntimeException("Incorrect URL: " + url); 1532 1533 testCount += 3; 1534 } 1535 1536 1537 static void tests() throws IOException, URISyntaxException { 1538 rfc2396(); 1539 ip(); 1540 misc(); 1541 chars(); 1542 eqHashComp(); 1543 serial(); 1544 urls(); 1545 npes(); 1546 bugs(); 1547 } 1548 1549 1550 // -- Command-line invocation -- 1551 1552 static void usage() { 1553 out.println("Usage:"); 1554 out.println(" java Test -- Runs all tests in this file"); 1555 out.println(" java Test <uri> -- Parses uri, shows components"); 1556 out.println(" java Test <base> <uri> -- Parses uri and base, then resolves"); 1557 out.println(" uri against base"); 1558 } 1559 1560 static void clargs(String base, String uri) { 1561 URI b = null, u; 1562 try { 1563 if (base != null) { 1564 b = new URI(base); 1565 out.println(base); 1566 show(b); 1567 } 1568 u = new URI(uri); 1569 out.println(uri); 1570 show(u); 1571 if (base != null) { 1572 URI r = b.resolve(u); 1573 out.println(r); 1574 show(r); 1575 } 1576 } catch (URISyntaxException x) { 1577 show("ERROR", x); 1578 x.printStackTrace(out); 1579 } 1580 } 1581 1582 1583 // miscellaneous bugs/rfes that don't fit in with the test framework 1584 1585 static void bugs() { 1586 // 6339649 - include detail message from nested exception 1587 try { 1588 URI uri = URI.create("http://nowhere.net/should not be permitted"); 1589 } catch (IllegalArgumentException e) { 1590 if ("".equals(e.getMessage()) || e.getMessage() == null) { 1591 throw new RuntimeException ("No detail message"); 1592 } 1593 } 1594 } 1595 1596 public static void main(String[] args) throws Exception { 1597 switch (args.length) { 1598 1599 case 0: 1600 tests(); 1601 out.println(); 1602 out.println("Test cases: " + testCount); 1603 break; 1604 1605 case 1: 1606 if (args[0].equals("-help")) { 1607 usage(); 1608 break; 1609 } 1610 clargs(null, args[0]); 1611 break; 1612 1613 case 2: 1614 clargs(args[0], args[1]); 1615 break; 1616 1617 default: 1618 usage(); 1619 break; 1620 1621 } 1622 } 1623 1624 }