1 28 29 package HTTPClient; 30 31 import java.net.URL ; 32 import java.util.Date ; 33 import java.util.BitSet ; 34 import java.util.Vector ; 35 import java.util.Hashtable ; 36 import java.util.SimpleTimeZone ; 37 import java.util.StringTokenizer ; 38 import java.text.SimpleDateFormat ; 39 import java.util.Locale ; 40 41 42 48 49 public class Util 50 { 51 private static final BitSet Separators = new BitSet (128); 52 private static final BitSet TokenChar = new BitSet (128); 53 private static final BitSet UnsafeChar = new BitSet (128); 54 private static SimpleDateFormat http_format; 55 56 static 57 { 58 Separators.set('('); 60 Separators.set(')'); 61 Separators.set('<'); 62 Separators.set('>'); 63 Separators.set('@'); 64 Separators.set(','); 65 Separators.set(';'); 66 Separators.set(':'); 67 Separators.set('\\'); 68 Separators.set('"'); 69 Separators.set('/'); 70 Separators.set('['); 71 Separators.set(']'); 72 Separators.set('?'); 73 Separators.set('='); 74 Separators.set('{'); 75 Separators.set('}'); 76 Separators.set(' '); 77 Separators.set('\t'); 78 79 for (int ch=32; ch<127; ch++) TokenChar.set(ch); 81 TokenChar.xor(Separators); 82 83 for (int ch=0; ch<32; ch++) UnsafeChar.set(ch); 86 UnsafeChar.set(' '); 87 UnsafeChar.set('<'); 88 UnsafeChar.set('>'); 89 UnsafeChar.set('"'); 90 UnsafeChar.set('{'); 91 UnsafeChar.set('}'); 92 UnsafeChar.set('|'); 93 UnsafeChar.set('\\'); 94 UnsafeChar.set('^'); 95 UnsafeChar.set('~'); 96 UnsafeChar.set('['); 97 UnsafeChar.set(']'); 98 UnsafeChar.set('`'); 99 UnsafeChar.set(127); 100 101 109 } 110 111 112 114 117 private Util() {} 118 119 120 122 final static Object [] resizeArray(Object [] src, int new_size) 124 { 125 Object tmp[] = new Object [new_size]; 126 System.arraycopy(src, 0, tmp, 0, 127 (src.length < new_size ? src.length : new_size)); 128 return tmp; 129 } 130 131 final static NVPair[] resizeArray(NVPair[] src, int new_size) 132 { 133 NVPair tmp[] = new NVPair[new_size]; 134 System.arraycopy(src, 0, tmp, 0, 135 (src.length < new_size ? src.length : new_size)); 136 return tmp; 137 } 138 139 final static AuthorizationInfo[] resizeArray(AuthorizationInfo[] src, 140 int new_size) 141 { 142 AuthorizationInfo tmp[] = new AuthorizationInfo[new_size]; 143 System.arraycopy(src, 0, tmp, 0, 144 (src.length < new_size ? src.length : new_size)); 145 return tmp; 146 } 147 148 final static Cookie[] resizeArray(Cookie[] src, int new_size) 149 { 150 Cookie tmp[] = new Cookie[new_size]; 151 System.arraycopy(src, 0, tmp, 0, 152 (src.length < new_size ? src.length : new_size)); 153 return tmp; 154 } 155 156 final static String [] resizeArray(String [] src, int new_size) 157 { 158 String tmp[] = new String [new_size]; 159 System.arraycopy(src, 0, tmp, 0, 160 (src.length < new_size ? src.length : new_size)); 161 return tmp; 162 } 163 164 final static boolean[] resizeArray(boolean[] src, int new_size) 165 { 166 boolean tmp[] = new boolean[new_size]; 167 System.arraycopy(src, 0, tmp, 0, 168 (src.length < new_size ? src.length : new_size)); 169 return tmp; 170 } 171 172 final static byte[] resizeArray(byte[] src, int new_size) 173 { 174 byte tmp[] = new byte[new_size]; 175 System.arraycopy(src, 0, tmp, 0, 176 (src.length < new_size ? src.length : new_size)); 177 return tmp; 178 } 179 180 final static char[] resizeArray(char[] src, int new_size) 181 { 182 char tmp[] = new char[new_size]; 183 System.arraycopy(src, 0, tmp, 0, 184 (src.length < new_size ? src.length : new_size)); 185 return tmp; 186 } 187 188 final static int[] resizeArray(int[] src, int new_size) 189 { 190 int tmp[] = new int[new_size]; 191 System.arraycopy(src, 0, tmp, 0, 192 (src.length < new_size ? src.length : new_size)); 193 return tmp; 194 } 195 196 197 201 static String [] splitProperty(String prop) 202 { 203 if (prop == null) return new String [0]; 204 205 StringTokenizer tok = new StringTokenizer (prop, "|"); 206 String [] list = new String [tok.countTokens()]; 207 for (int idx=0; idx<list.length; idx++) 208 list[idx] = tok.nextToken().trim(); 209 210 return list; 211 } 212 213 214 222 final static Hashtable getList(Hashtable cntxt_list, Object cntxt) 223 { 224 Hashtable list = (Hashtable ) cntxt_list.get(cntxt); 225 if (list == null) 226 { 227 synchronized(cntxt_list) { 229 list = (Hashtable ) cntxt_list.get(cntxt); 230 if (list == null) { 232 list = new Hashtable (); 233 cntxt_list.put(cntxt, list); 234 } 235 } 236 } 237 238 return list; 239 } 240 241 242 252 final static int[] compile_search(byte[] search) 253 { 254 int[] cmp = {0, 1, 0, 1, 0, 1}; 255 int end; 256 257 for (int idx=0; idx<search.length; idx++) 258 { 259 for (end=idx+1; end<search.length; end++) 260 { 261 if (search[idx] == search[end]) break; 262 } 263 if (end < search.length) 264 { 265 if ((end-idx) > cmp[1]) 266 { 267 cmp[4] = cmp[2]; 268 cmp[5] = cmp[3]; 269 cmp[2] = cmp[0]; 270 cmp[3] = cmp[1]; 271 cmp[0] = idx; 272 cmp[1] = end - idx; 273 } 274 else if ((end-idx) > cmp[3]) 275 { 276 cmp[4] = cmp[2]; 277 cmp[5] = cmp[3]; 278 cmp[2] = idx; 279 cmp[3] = end - idx; 280 } 281 else if ((end-idx) > cmp[3]) 282 { 283 cmp[4] = idx; 284 cmp[5] = end - idx; 285 } 286 } 287 } 288 289 cmp[1] += cmp[0]; 290 cmp[3] += cmp[2]; 291 cmp[5] += cmp[4]; 292 return cmp; 293 } 294 295 309 final static int findStr(byte[] search, int[] cmp, byte[] str, 310 int beg, int end) 311 { 312 int c1f = cmp[0], 313 c1l = cmp[1], 314 d1 = c1l - c1f, 315 c2f = cmp[2], 316 c2l = cmp[3], 317 d2 = c2l - c2f, 318 c3f = cmp[4], 319 c3l = cmp[5], 320 d3 = c3l - c3f; 321 322 Find: while (beg+search.length <= end) 323 { 324 if (search[c1l] == str[beg+c1l]) 325 { 326 335 if (search[c1f] == str[beg+c1f]) 336 { 337 boolean same = true; 338 339 for (int idx=0; idx<search.length; idx++) 340 if (search[idx] != str[beg+idx]) 341 { 342 same = false; 343 break; 344 } 345 346 if (same) 347 break Find; } 349 350 beg += d1; 351 } 352 else if (search[c2l] == str[beg+c2l]) 353 beg += d2; 354 else if (search[c3l] == str[beg+c3l]) 355 beg += d3; 356 else 357 beg++; 358 } 359 360 if (beg+search.length > end) 361 return -1; 362 else 363 return beg; 364 } 365 366 367 378 public final static String dequoteString(String str) 379 { 380 if (str.indexOf('\\') == -1) return str; 381 382 char[] buf = str.toCharArray(); 383 int pos = 0, num_deq = 0; 384 while (pos < buf.length) 385 { 386 if (buf[pos] == '\\' && pos+1 < buf.length) 387 { 388 System.arraycopy(buf, pos+1, buf, pos, buf.length-pos-1); 389 num_deq++; 390 } 391 pos++; 392 } 393 394 return new String (buf, 0, buf.length-num_deq); 395 } 396 397 398 409 public final static String quoteString(String str, String qlist) 410 { 411 char[] list = qlist.toCharArray(); 412 int idx; 413 for (idx=0; idx<list.length; idx++) 414 if (str.indexOf(list[idx]) != -1) break; 415 if (idx == list.length) return str; 416 417 int len = str.length(); 418 char[] buf = new char[len*2]; 419 str.getChars(0, len, buf, 0); 420 int pos = 0; 421 while (pos < len) 422 { 423 if (qlist.indexOf(buf[pos], 0) != -1) 424 { 425 if (len == buf.length) 426 buf = Util.resizeArray(buf, len+str.length()); 427 428 System.arraycopy(buf, pos, buf, pos+1, len-pos); 429 len++; 430 buf[pos++] = '\\'; 431 } 432 pos++; 433 } 434 435 return new String (buf, 0, len); 436 } 437 438 439 449 public final static Vector parseHeader(String header) throws ParseException 450 { 451 return parseHeader(header, true); 452 } 453 454 455 486 public final static Vector parseHeader(String header, boolean dequote) 487 throws ParseException 488 { 489 if (header == null) return null; 490 char[] buf = header.toCharArray(); 491 Vector elems = new Vector (); 492 boolean first = true; 493 int beg = -1, end = 0, len = buf.length, abeg[] = new int[1]; 494 String elem_name, elem_value; 495 496 497 elements: while (true) 498 { 499 if (!first) { 501 beg = skipSpace(buf, end); 502 if (beg == len) break; 503 if (buf[beg] != ',') 504 throw new ParseException("Bad header format: '" + header + 505 "'\nExpected \",\" at position " + 506 beg); 507 } 508 first = false; 509 510 beg = skipSpace(buf, beg+1); 511 if (beg == len) break elements; 512 if (buf[beg] == ',') { 514 end = beg; 515 continue elements; 516 } 517 518 if (buf[beg] == '=' || buf[beg] == ';' || buf[beg] == '"') 519 throw new ParseException("Bad header format: '" + header + 520 "'\nEmpty element name at position " + 521 beg); 522 523 end = beg+1; while (end < len && !Character.isSpace(buf[end]) && 525 buf[end] != '=' && buf[end] != ',' && buf[end] != ';') 526 end++; 527 elem_name = new String (buf, beg, end-beg); 528 529 beg = skipSpace(buf, end); 530 if (beg < len && buf[beg] == '=') { 532 abeg[0] = beg+1; 533 elem_value = parseValue(buf, abeg, header, dequote); 534 end = abeg[0]; 535 } 536 else 537 { 538 elem_value = null; 539 end = beg; 540 } 541 542 NVPair[] params = new NVPair[0]; 543 params: while (true) 544 { 545 String param_name, param_value; 546 547 beg = skipSpace(buf, end); if (beg == len || buf[beg] != ';') 549 break params; 550 551 beg = skipSpace(buf, beg+1); 552 if (beg == len || buf[beg] == ',') 553 { 554 end = beg; 555 break params; 556 } 557 if (buf[beg] == ';') { 559 end = beg; 560 continue params; 561 } 562 563 if (buf[beg] == '=' || buf[beg] == '"') 564 throw new ParseException("Bad header format: '" + header + 565 "'\nEmpty parameter name at position "+ 566 beg); 567 568 end = beg+1; while (end < len && !Character.isSpace(buf[end]) && 570 buf[end] != '=' && buf[end] != ',' && buf[end] != ';') 571 end++; 572 param_name = new String (buf, beg, end-beg); 573 574 beg = skipSpace(buf, end); 575 if (beg < len && buf[beg] == '=') { 577 abeg[0] = beg+1; 578 param_value = parseValue(buf, abeg, header, dequote); 579 end = abeg[0]; 580 } 581 else 582 { 583 param_value = null; 584 end = beg; 585 } 586 587 params = Util.resizeArray(params, params.length+1); 588 params[params.length-1] = new NVPair(param_name, param_value); 589 } 590 591 elems.addElement( 592 new HttpHeaderElement(elem_name, elem_value, params)); 593 } 594 595 return elems; 596 } 597 598 599 602 private static String parseValue(char[] buf, int[] abeg, String header, 603 boolean dequote) 604 throws ParseException 605 { 606 int beg = abeg[0], end = beg, len = buf.length; 607 String value; 608 609 610 beg = skipSpace(buf, beg); 611 612 if (beg < len && buf[beg] == '"') { 614 beg++; 615 end = beg; 616 char[] deq_buf = null; 617 int deq_pos = 0, lst_pos = beg; 618 619 while (end < len && buf[end] != '"') 620 { 621 if (buf[end] == '\\') 622 { 623 if (dequote) { 625 if (deq_buf == null) 626 deq_buf = new char[buf.length]; 627 System.arraycopy(buf, lst_pos, deq_buf, deq_pos, 628 end-lst_pos); 629 deq_pos += end-lst_pos; 630 lst_pos = ++end; 631 } 632 else 633 end++; } 635 636 end++; 637 } 638 if (end == len) 639 throw new ParseException("Bad header format: '" + header + 640 "'\nClosing <\"> for quoted-string"+ 641 " starting at position " + 642 (beg-1) + " not found"); 643 if (deq_buf != null) 644 { 645 System.arraycopy(buf, lst_pos, deq_buf, deq_pos, end-lst_pos); 646 deq_pos += end-lst_pos; 647 value = new String (deq_buf, 0, deq_pos); 648 } 649 else 650 value = new String (buf, beg, end-beg); 651 end++; 652 } 653 else { 655 end = beg; 656 while (end < len && !Character.isSpace(buf[end]) && 657 buf[end] != ',' && buf[end] != ';') 658 end++; 659 660 value = new String (buf, beg, end-beg); 661 } 662 663 abeg[0] = end; 664 return value; 665 } 666 667 668 678 public final static boolean hasToken(String header, String token) 679 throws ParseException 680 { 681 if (header == null) 682 return false; 683 else 684 return parseHeader(header).contains(new HttpHeaderElement(token)); 685 } 686 687 688 698 public final static HttpHeaderElement getElement(Vector header, String name) 699 { 700 int idx = header.indexOf(new HttpHeaderElement(name)); 701 if (idx == -1) 702 return null; 703 else 704 return (HttpHeaderElement) header.elementAt(idx); 705 } 706 707 708 723 public final static String getParameter(String param, String hdr) 724 throws ParseException 725 { 726 NVPair[] params = ((HttpHeaderElement) parseHeader(hdr).firstElement()). 727 getParams(); 728 729 for (int idx=0; idx<params.length; idx++) 730 { 731 if (params[idx].getName().equalsIgnoreCase(param)) 732 return params[idx].getValue(); 733 } 734 735 return null; 736 } 737 738 739 746 public final static String assembleHeader(Vector pheader) 747 { 748 StringBuffer hdr = new StringBuffer (200); 749 int len = pheader.size(); 750 751 for (int idx=0; idx<len; idx++) 752 { 753 ((HttpHeaderElement) pheader.elementAt(idx)).appendTo(hdr); 754 hdr.append(", "); 755 } 756 hdr.setLength(hdr.length()-2); 757 758 return hdr.toString(); 759 } 760 761 762 770 final static int skipSpace(char[] str, int pos) 771 { 772 int len = str.length; 773 while (pos < len && Character.isSpace(str[pos])) pos++; 774 return pos; 775 } 776 777 786 final static int findSpace(char[] str, int pos) 787 { 788 int len = str.length; 789 while (pos < len && !Character.isSpace(str[pos])) pos++; 790 return pos; 791 } 792 793 802 final static int skipToken(char[] str, int pos) 803 { 804 int len = str.length; 805 while (pos < len && TokenChar.get(str[pos])) pos++; 806 return pos; 807 } 808 809 810 817 final static boolean needsQuoting(String str) 818 { 819 int len = str.length(), pos = 0; 820 821 while (pos < len && TokenChar.get(str.charAt(pos))) pos++; 822 return (pos < len); 823 } 824 825 826 840 public final static boolean sameHttpURL(URL url1, URL url2) 841 { 842 if (!url1.getProtocol().equalsIgnoreCase(url2.getProtocol())) 843 return false; 844 845 if (!url1.getHost().equalsIgnoreCase(url2.getHost())) 846 return false; 847 848 int port1 = url1.getPort(), port2 = url2.getPort(); 849 if (port1 == -1) port1 = URI.defaultPort(url1.getProtocol()); 850 if (port2 == -1) port2 = URI.defaultPort(url1.getProtocol()); 851 if (port1 != port2) 852 return false; 853 854 try 855 { return URI.unescape(url1.getFile()).equals(URI.unescape(url2.getFile())); } 856 catch (ParseException pe) 857 { return url1.getFile().equals(url2.getFile());} 858 } 859 860 861 869 public final static int defaultPort(String protocol) 870 { 871 return URI.defaultPort(protocol); 872 } 873 874 875 890 public final static String httpDate(Date date) 891 { 892 if (http_format == null) 893 { 894 synchronized(HTTPClient.Util.class) 895 { 896 if (http_format == null) 897 { 898 http_format = 899 new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss 'GMT'", 900 Locale.US); 901 http_format.setTimeZone(new SimpleTimeZone (0, "GMT")); 902 } 903 } 904 } 905 906 return http_format.format(date); 907 } 908 909 910 916 final static String escapeUnsafeChars(String path) 917 { 918 int len = path.length(); 919 char[] buf = new char[3*len]; 920 921 int dst = 0; 922 for (int SRC=0; src<len; src++) 923 { 924 char ch = path.charAt(src); 925 if (ch >= 128 || UnsafeChar.get(ch)) 926 { 927 buf[dst++] = '%'; 928 buf[dst++] = hex_map[(ch & 0xf0) >>> 4]; 929 buf[dst++] = hex_map[ch & 0x0f]; 930 } 931 else 932 buf[dst++] = ch; 933 } 934 935 if (dst > len) 936 return new String (buf, 0, dst); 937 else 938 return path; 939 } 940 941 static final char[] hex_map = 942 {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; 943 944 945 963 public final static String getPath(String resource) 964 { 965 int p, end = resource.length(); 966 if ((p = resource.indexOf('#')) != -1) end = p; 968 if ((p = resource.indexOf('?')) != -1 && p < end) end = p; 970 if ((p = resource.indexOf(';')) != -1 && p < end) end = p; 972 return resource.substring(0, end); 973 } 974 975 976 983 public final static String getParams(String resource) 984 { 985 int beg, f, q; 986 if ((beg = resource.indexOf(';')) == -1) return null; 988 if ((f = resource.indexOf('#')) != -1 && f < beg) return null; 990 if ((q = resource.indexOf('?')) != -1 && q < beg) return null; 992 if (q == -1 && f == -1) 993 return resource.substring(beg+1); 994 if (f == -1 || (q != -1 && q < f)) 995 return resource.substring(beg+1, q); 996 else 997 return resource.substring(beg+1, f); 998 } 999 1000 1001 1008 public final static String getQuery(String resource) 1009 { 1010 int beg, f; 1011 if ((beg = resource.indexOf('?')) == -1) return null; 1013 if ((f = resource.indexOf('#')) != -1 && f < beg) return null; if (f == -1) 1016 return resource.substring(beg+1); else 1018 return resource.substring(beg+1, f); } 1020 1021 1022 1029 public final static String getFragment(String resource) 1030 { 1031 int beg; 1032 if ((beg = resource.indexOf('#')) == -1) return null; 1034 else 1035 return resource.substring(beg+1); 1036 } 1037} 1038 1039 | Popular Tags |