1 17 18 19 package org.apache.catalina.util; 20 21 22 import java.io.Serializable ; 23 import java.net.MalformedURLException ; 24 25 26 47 48 public final class URL implements Serializable { 49 50 51 53 54 62 public URL(String spec) throws MalformedURLException { 63 64 this(null, spec); 65 66 } 67 68 69 81 public URL(URL context, String spec) throws MalformedURLException { 82 83 String original = spec; 84 int i, limit, c; 85 int start = 0; 86 String newProtocol = null; 87 boolean aRef = false; 88 89 try { 90 91 limit = spec.length(); 93 while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) { 94 limit--; 95 } 96 while ((start < limit) && (spec.charAt(start) <= ' ')) { 97 start++; 98 } 99 100 if (spec.regionMatches(true, start, "url:", 0, 4)) { 102 start += 4; 103 } 104 105 if ((start < spec.length()) && (spec.charAt(start) == '#')) { 107 aRef = true; 108 } 109 110 for (i = start; !aRef && (i < limit) && 112 ((c = spec.charAt(i)) != '/'); i++) { 113 if (c == ':') { 114 String s = spec.substring(start, i).toLowerCase(); 115 newProtocol = s; 117 start = i + 1; 118 break; 119 } 120 } 121 122 protocol = newProtocol; 124 if ((context != null) && ((newProtocol == null) || 125 newProtocol.equalsIgnoreCase(context.getProtocol()))) { 126 if ((context.getPath() != null) && 131 (context.getPath().startsWith("/"))) 132 newProtocol = null; 133 if (newProtocol == null) { 134 protocol = context.getProtocol(); 135 authority = context.getAuthority(); 136 userInfo = context.getUserInfo(); 137 host = context.getHost(); 138 port = context.getPort(); 139 file = context.getFile(); 140 int question = file.lastIndexOf("?"); 141 if (question < 0) 142 path = file; 143 else 144 path = file.substring(0, question); 145 } 146 } 147 148 if (protocol == null) 149 throw new MalformedURLException ("no protocol: " + original); 150 151 i = spec.indexOf('#', start); 153 if (i >= 0) { 154 ref = spec.substring(i + 1, limit); 155 limit = i; 156 } 157 158 parse(spec, start, limit); 160 if (context != null) 161 normalize(); 162 163 164 } catch (MalformedURLException e) { 165 throw e; 166 } catch (Exception e) { 167 throw new MalformedURLException (e.toString()); 168 } 169 170 } 171 172 173 174 175 176 187 public URL(String protocol, String host, String file) 188 throws MalformedURLException { 189 190 this(protocol, host, -1, file); 191 192 } 193 194 195 209 public URL(String protocol, String host, int port, String file) 210 throws MalformedURLException { 211 212 this.protocol = protocol; 213 this.host = host; 214 this.port = port; 215 216 int hash = file.indexOf('#'); 217 this.file = hash < 0 ? file : file.substring(0, hash); 218 this.ref = hash < 0 ? null : file.substring(hash + 1); 219 int question = file.lastIndexOf('?'); 220 if (question >= 0) { 221 query = file.substring(question + 1); 222 path = file.substring(0, question); 223 } else 224 path = file; 225 226 if ((host != null) && (host.length() > 0)) 227 authority = (port == -1) ? host : host + ":" + port; 228 229 } 230 231 232 234 235 238 private String authority = null; 239 240 241 244 private String file = null; 245 246 247 250 private String host = null; 251 252 253 256 private String path = null; 257 258 259 262 private int port = -1; 263 264 265 268 private String protocol = null; 269 270 271 274 private String query = null; 275 276 277 280 private String ref = null; 281 282 283 286 private String userInfo = null; 287 288 289 291 292 302 public boolean equals(Object obj) { 303 304 if (obj == null) 305 return (false); 306 if (!(obj instanceof URL)) 307 return (false); 308 URL other = (URL) obj; 309 if (!sameFile(other)) 310 return (false); 311 return (compare(ref, other.getRef())); 312 313 } 314 315 316 319 public String getAuthority() { 320 321 return (this.authority); 322 323 } 324 325 326 332 public String getFile() { 333 334 if (file == null) 335 return (""); 336 return (this.file); 337 338 } 339 340 341 344 public String getHost() { 345 346 return (this.host); 347 348 } 349 350 351 354 public String getPath() { 355 356 if (this.path == null) 357 return (""); 358 return (this.path); 359 360 } 361 362 363 366 public int getPort() { 367 368 return (this.port); 369 370 } 371 372 373 376 public String getProtocol() { 377 378 return (this.protocol); 379 380 } 381 382 383 386 public String getQuery() { 387 388 return (this.query); 389 390 } 391 392 393 396 public String getRef() { 397 398 return (this.ref); 399 400 } 401 402 403 406 public String getUserInfo() { 407 408 return (this.userInfo); 409 410 } 411 412 413 424 public void normalize() throws MalformedURLException { 425 426 if (path == null) { 428 if (query != null) 429 file = "?" + query; 430 else 431 file = ""; 432 return; 433 } 434 435 String normalized = path; 437 if (normalized.equals("/.")) { 438 path = "/"; 439 if (query != null) 440 file = path + "?" + query; 441 else 442 file = path; 443 return; 444 } 445 446 if (normalized.indexOf('\\') >= 0) 448 normalized = normalized.replace('\\', '/'); 449 if (!normalized.startsWith("/")) 450 normalized = "/" + normalized; 451 452 while (true) { 454 int index = normalized.indexOf("//"); 455 if (index < 0) 456 break; 457 normalized = normalized.substring(0, index) + 458 normalized.substring(index + 1); 459 } 460 461 while (true) { 463 int index = normalized.indexOf("/./"); 464 if (index < 0) 465 break; 466 normalized = normalized.substring(0, index) + 467 normalized.substring(index + 2); 468 } 469 470 while (true) { 472 int index = normalized.indexOf("/../"); 473 if (index < 0) 474 break; 475 if (index == 0) 476 throw new MalformedURLException 477 ("Invalid relative URL reference"); 478 int index2 = normalized.lastIndexOf('/', index - 1); 479 normalized = normalized.substring(0, index2) + 480 normalized.substring(index + 3); 481 } 482 483 if (normalized.endsWith("/.")) 485 normalized = normalized.substring(0, normalized.length() - 1); 486 487 if (normalized.endsWith("/..")) { 489 int index = normalized.length() - 3; 490 int index2 = normalized.lastIndexOf('/', index - 1); 491 if (index2 < 0) 492 throw new MalformedURLException 493 ("Invalid relative URL reference"); 494 normalized = normalized.substring(0, index2 + 1); 495 } 496 497 path = normalized; 499 if (query != null) 500 file = path + "?" + query; 501 else 502 file = path; 503 504 } 505 506 507 513 public boolean sameFile(URL other) { 514 515 if (!compare(protocol, other.getProtocol())) 516 return (false); 517 if (!compare(host, other.getHost())) 518 return (false); 519 if (port != other.getPort()) 520 return (false); 521 if (!compare(file, other.getFile())) 522 return (false); 523 return (true); 524 525 } 526 527 528 532 public String toExternalForm() { 533 534 StringBuffer sb = new StringBuffer (); 535 if (protocol != null) { 536 sb.append(protocol); 537 sb.append(":"); 538 } 539 if (authority != null) { 540 sb.append("//"); 541 sb.append(authority); 542 } 543 if (path != null) 544 sb.append(path); 545 if (query != null) { 546 sb.append('?'); 547 sb.append(query); 548 } 549 if (ref != null) { 550 sb.append('#'); 551 sb.append(ref); 552 } 553 return (sb.toString()); 554 555 } 556 557 558 561 public String toString() { 562 563 StringBuffer sb = new StringBuffer ("URL["); 564 sb.append("authority="); 565 sb.append(authority); 566 sb.append(", file="); 567 sb.append(file); 568 sb.append(", host="); 569 sb.append(host); 570 sb.append(", port="); 571 sb.append(port); 572 sb.append(", protocol="); 573 sb.append(protocol); 574 sb.append(", query="); 575 sb.append(query); 576 sb.append(", ref="); 577 sb.append(ref); 578 sb.append(", userInfo="); 579 sb.append(userInfo); 580 sb.append("]"); 581 return (sb.toString()); 582 583 585 } 586 587 588 590 591 598 private boolean compare(String first, String second) { 599 600 if (first == null) { 601 if (second == null) 602 return (true); 603 else 604 return (false); 605 } else { 606 if (second == null) 607 return (false); 608 else 609 return (first.equals(second)); 610 } 611 612 } 613 614 615 632 private void parse(String spec, int start, int limit) 633 throws MalformedURLException { 634 635 int question = spec.lastIndexOf('?', limit - 1); 637 if ((question >= 0) && (question < limit)) { 638 query = spec.substring(question + 1, limit); 639 limit = question; 640 } else { 641 query = null; 642 } 643 644 if (spec.indexOf("//", start) == start) { 646 int pathStart = spec.indexOf("/", start + 2); 647 if ((pathStart >= 0) && (pathStart < limit)) { 648 authority = spec.substring(start + 2, pathStart); 649 start = pathStart; 650 } else { 651 authority = spec.substring(start + 2, limit); 652 start = limit; 653 } 654 if (authority.length() > 0) { 655 int at = authority.indexOf('@'); 656 if( at >= 0 ) { 657 userInfo = authority.substring(0,at); 658 } 659 int colon = authority.indexOf(':',at+1); 660 if (colon >= 0) { 661 try { 662 port = 663 Integer.parseInt(authority.substring(colon + 1)); 664 } catch (NumberFormatException e) { 665 throw new MalformedURLException (e.toString()); 666 } 667 host = authority.substring(at+1, colon); 668 } else { 669 host = authority.substring(at+1); 670 port = -1; 671 } 672 } 673 } 674 675 if (spec.indexOf("/", start) == start) { path = spec.substring(start, limit); 678 if (query != null) 679 file = path + "?" + query; 680 else 681 file = path; 682 return; 683 } 684 685 if (path == null) { 687 if (query != null) 688 file = "?" + query; 689 else 690 file = null; 691 return; 692 } 693 if (!path.startsWith("/")) 694 throw new MalformedURLException 695 ("Base path does not start with '/'"); 696 if (!path.endsWith("/")) 697 path += "/../"; 698 path += spec.substring(start, limit); 699 if (query != null) 700 file = path + "?" + query; 701 else 702 file = path; 703 return; 704 705 } 706 707 708 } 709 | Popular Tags |