Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
Util.java
Package: HTTP客户端.zip [view]
Upload User: demmber
Upload Date: 2007-12-22
Package Size: 717k
Code Size: 31k
Category:
Java Develop
Development Platform:
Java
- /*
- * @(#)Util.java 0.3-3 06/05/2001
- *
- * This file is part of the HTTPClient package
- * Copyright (C) 1996-2001 Ronald Tschal鋜
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307, USA
- *
- * For questions, suggestions, bug-reports, enhancement-requests etc.
- * I may be contacted at:
- *
- * ronald@innovation.ch
- *
- * The HTTPClient's home page is located at:
- *
- * http://www.innovation.ch/java/HTTPClient/
- *
- */
- package HTTPClient;
- import java.lang.reflect.Array;
- import java.net.URL;
- import java.util.Date;
- import java.util.BitSet;
- import java.util.Locale;
- import java.util.Vector;
- import java.util.Hashtable;
- import java.util.SimpleTimeZone;
- import java.util.StringTokenizer;
- import java.text.DateFormat;
- import java.text.SimpleDateFormat;
- /**
- * This class holds various utility methods.
- *
- * @version 0.3-3 06/05/2001
- * @author Ronald Tschal鋜
- */
- public class Util
- {
- private static final BitSet Separators = new BitSet(128);
- private static final BitSet TokenChar = new BitSet(128);
- private static final BitSet UnsafeChar = new BitSet(128);
- private static DateFormat http_format;
- private static DateFormat parse_1123;
- private static DateFormat parse_850;
- private static DateFormat parse_asctime;
- private static final Object http_format_lock = new Object();
- private static final Object http_parse_lock = new Object();
- static
- {
- // rfc-2616 tspecial
- Separators.set('(');
- Separators.set(')');
- Separators.set('<');
- Separators.set('>');
- Separators.set('@');
- Separators.set(',');
- Separators.set(';');
- Separators.set(':');
- Separators.set('\');
- Separators.set('"');
- Separators.set('/');
- Separators.set('[');
- Separators.set(']');
- Separators.set('?');
- Separators.set('=');
- Separators.set('{');
- Separators.set('}');
- Separators.set(' ');
- Separators.set('t');
- // rfc-2616 token
- for (int ch=32; ch<127; ch++) TokenChar.set(ch);
- TokenChar.xor(Separators);
- // rfc-1738 unsafe characters, including CTL and SP, and excluding
- // "#" and "%"
- for (int ch=0; ch<32; ch++) UnsafeChar.set(ch);
- UnsafeChar.set(' ');
- UnsafeChar.set('<');
- UnsafeChar.set('>');
- UnsafeChar.set('"');
- UnsafeChar.set('{');
- UnsafeChar.set('}');
- UnsafeChar.set('|');
- UnsafeChar.set('\');
- UnsafeChar.set('^');
- UnsafeChar.set('~');
- UnsafeChar.set('[');
- UnsafeChar.set(']');
- UnsafeChar.set('`');
- UnsafeChar.set(127);
- // rfc-1123 date format (restricted to GMT, as per rfc-2616)
- /* This initialization has been moved to httpDate() because it
- * takes an awfully long time and is often not needed
- *
- http_format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'",
- Locale.US);
- http_format.setTimeZone(new SimpleTimeZone(0, "GMT"));
- */
- }
- // Constructors
- /**
- * This class isn't meant to be instantiated.
- */
- private Util() {}
- // Methods
- final static Object[] resizeArray(Object[] src, int new_size)
- {
- Class compClass = src.getClass().getComponentType();
- Object tmp[] = (Object[]) Array.newInstance(compClass, new_size);
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static NVPair[] resizeArray(NVPair[] src, int new_size)
- {
- NVPair tmp[] = new NVPair[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static AuthorizationInfo[] resizeArray(AuthorizationInfo[] src,
- int new_size)
- {
- AuthorizationInfo tmp[] = new AuthorizationInfo[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static Cookie[] resizeArray(Cookie[] src, int new_size)
- {
- Cookie tmp[] = new Cookie[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static String[] resizeArray(String[] src, int new_size)
- {
- String tmp[] = new String[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static boolean[] resizeArray(boolean[] src, int new_size)
- {
- boolean tmp[] = new boolean[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static byte[] resizeArray(byte[] src, int new_size)
- {
- byte tmp[] = new byte[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static char[] resizeArray(char[] src, int new_size)
- {
- char tmp[] = new char[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- final static int[] resizeArray(int[] src, int new_size)
- {
- int tmp[] = new int[new_size];
- System.arraycopy(src, 0, tmp, 0,
- (src.length < new_size ? src.length : new_size));
- return tmp;
- }
- /**
- * Split a property into an array of Strings, using "|" as the
- * separator.
- */
- static String[] splitProperty(String prop)
- {
- if (prop == null) return new String[0];
- StringTokenizer tok = new StringTokenizer(prop, "|");
- String[] list = new String[tok.countTokens()];
- for (int idx=0; idx<list.length; idx++)
- list[idx] = tok.nextToken().trim();
- return list;
- }
- /**
- * Helper method for context lists used by modules. Returns the
- * list associated with the context if it exists; otherwise it creates
- * a new list and adds it to the context list.
- *
- * @param cntxt_list the list of lists indexed by context
- * @param cntxt the context
- */
- final static Hashtable getList(Hashtable cntxt_list, Object cntxt)
- {
- synchronized (cntxt_list)
- {
- Hashtable list = (Hashtable) cntxt_list.get(cntxt);
- if (list == null)
- {
- list = new Hashtable();
- cntxt_list.put(cntxt, list);
- }
- return list;
- }
- }
- /**
- * Creates an array of distances to speed up the search in findStr().
- * The returned array should be passed as the second argument to
- * findStr().
- *
- * @param search the search string (same as the first argument to
- * findStr()).
- * @return an array of distances (to be passed as the second argument to
- * findStr()).
- */
- final static int[] compile_search(byte[] search)
- {
- int[] cmp = {0, 1, 0, 1, 0, 1};
- int end;
- for (int idx=0; idx<search.length; idx++)
- {
- for (end=idx+1; end<search.length; end++)
- {
- if (search[idx] == search[end]) break;
- }
- if (end < search.length)
- {
- if ((end-idx) > cmp[1])
- {
- cmp[4] = cmp[2];
- cmp[5] = cmp[3];
- cmp[2] = cmp[0];
- cmp[3] = cmp[1];
- cmp[0] = idx;
- cmp[1] = end - idx;
- }
- else if ((end-idx) > cmp[3])
- {
- cmp[4] = cmp[2];
- cmp[5] = cmp[3];
- cmp[2] = idx;
- cmp[3] = end - idx;
- }
- else if ((end-idx) > cmp[3])
- {
- cmp[4] = idx;
- cmp[5] = end - idx;
- }
- }
- }
- cmp[1] += cmp[0];
- cmp[3] += cmp[2];
- cmp[5] += cmp[4];
- return cmp;
- }
- /**
- * Search for a string. Use compile_search() to first generate the second
- * argument. This uses a Knuth-Morris-Pratt like algorithm.
- *
- * @param search the string to search for.
- * @param cmp the the array returned by compile_search.
- * @param str the string in which to look for <var>search</var>.
- * @param beg the position at which to start the search in
- * <var>str</var>.
- * @param end the position at which to end the search in <var>str</var>,
- * noninclusive.
- * @return the position in <var>str</var> where <var>search</var> was
- * found, or -1 if not found.
- */
- final static int findStr(byte[] search, int[] cmp, byte[] str,
- int beg, int end)
- {
- int c1f = cmp[0],
- c1l = cmp[1],
- d1 = c1l - c1f,
- c2f = cmp[2],
- c2l = cmp[3],
- d2 = c2l - c2f,
- c3f = cmp[4],
- c3l = cmp[5],
- d3 = c3l - c3f;
- Find: while (beg+search.length <= end)
- {
- if (search[c1l] == str[beg+c1l])
- {
- /* This is correct, but Visual J++ can't cope with it...
- Comp: if (search[c1f] == str[beg+c1f])
- {
- for (int idx=0; idx<search.length; idx++)
- if (search[idx] != str[beg+idx]) break Comp;
- break Find; // we found it
- }
- * so here is the replacement: */
- if (search[c1f] == str[beg+c1f])
- {
- boolean same = true;
- for (int idx=0; idx<search.length; idx++)
- if (search[idx] != str[beg+idx])
- {
- same = false;
- break;
- }
- if (same)
- break Find; // we found it
- }
- beg += d1;
- }
- else if (search[c2l] == str[beg+c2l])
- beg += d2;
- else if (search[c3l] == str[beg+c3l])
- beg += d3;
- else
- beg++;
- }
- if (beg+search.length > end)
- return -1;
- else
- return beg;
- }
- /**
- * Replace quoted characters by their unquoted version. Quoted characters
- * are characters preceded by a slash. E.g. "c" would be replaced by "c".
- * This is used in parsing http headers where quoted-characters are
- * allowed in quoted-strings and often used to quote the quote character
- * <">.
- *
- * @param str the string do dequote
- * @return the string do with all quoted characters replaced by their
- * true value.
- */
- public final static String dequoteString(String str)
- {
- if (str.indexOf('\') == -1) return str;
- char[] buf = str.toCharArray();
- int pos = 0, num_deq = 0;
- while (pos < buf.length)
- {
- if (buf[pos] == '\' && pos+1 < buf.length)
- {
- System.arraycopy(buf, pos+1, buf, pos, buf.length-pos-1);
- num_deq++;
- }
- pos++;
- }
- return new String(buf, 0, buf.length-num_deq);
- }
- /**
- * Replace given characters by their quoted version. Quoted characters
- * are characters preceded by a slash. E.g. "c" would be replaced by "c".
- * This is used in generating http headers where certain characters need
- * to be quoted, such as the quote character <">.
- *
- * @param str the string do quote
- * @param qlist the list of characters to quote
- * @return the string do with all characters replaced by their
- * quoted version.
- */
- public final static String quoteString(String str, String qlist)
- {
- char[] list = qlist.toCharArray();
- int idx;
- for (idx=0; idx<list.length; idx++)
- if (str.indexOf(list[idx]) != -1) break;
- if (idx == list.length) return str;
- int len = str.length();
- char[] buf = new char[len*2];
- str.getChars(0, len, buf, 0);
- int pos = 0;
- while (pos < len)
- {
- if (qlist.indexOf(buf[pos], 0) != -1)
- {
- if (len == buf.length)
- buf = Util.resizeArray(buf, len+str.length());
- System.arraycopy(buf, pos, buf, pos+1, len-pos);
- len++;
- buf[pos++] = '\';
- }
- pos++;
- }
- return new String(buf, 0, len);
- }
- /**
- * This parses the value part of a header. All quoted strings are
- * dequoted.
- *
- * @see #parseHeader(java.lang.String, boolean)
- * @param header the value part of the header.
- * @return a Vector containing all the elements; each entry is an
- * instance of <var>HttpHeaderElement</var>.
- * @exception ParseException if the syntax rules are violated.
- */
- public final static Vector parseHeader(String header) throws ParseException
- {
- return parseHeader(header, true);
- }
- /**
- * This parses the value part of a header. The result is a Vector of
- * HttpHeaderElement's. The syntax the header must conform to is:
- *
- * <PRE>
- * header = [ element ] *( "," [ element ] )
- * element = name [ "=" [ value ] ] *( ";" [ param ] )
- * param = name [ "=" [ value ] ]
- *
- * name = token
- * value = ( token | quoted-string )
- *
- * token = 1*<any char except "=", ",", ";", <"> and
- * white space>
- * quoted-string = <"> *( text | quoted-char ) <">
- * text = any char except <">
- * quoted-char = "" char
- * </PRE>
- *
- * Any amount of white space is allowed between any part of the header,
- * element or param and is ignored. A missing value in any element or
- * param will be stored as the empty string; if the "=" is also missing
- * <var>null</var> will be stored instead.
- *
- * @param header the value part of the header.
- * @param dequote if true all quoted strings are dequoted.
- * @return a Vector containing all the elements; each entry is an
- * instance of <var>HttpHeaderElement</var>.
- * @exception ParseException if the above syntax rules are violated.
- * @see HTTPClient.HttpHeaderElement
- */
- public final static Vector parseHeader(String header, boolean dequote)
- throws ParseException
- {
- if (header == null) return null;
- char[] buf = header.toCharArray();
- Vector elems = new Vector();
- boolean first = true;
- int beg = -1, end = 0, len = buf.length, abeg[] = new int[1];
- String elem_name, elem_value;
- elements: while (true)
- {
- if (!first) // find required ","
- {
- beg = skipSpace(buf, end);
- if (beg == len) break;
- if (buf[beg] != ',')
- throw new ParseException("Bad header format: '" + header +
- "'nExpected "," at position " +
- beg);
- }
- first = false;
- beg = skipSpace(buf, beg+1);
- if (beg == len) break elements;
- if (buf[beg] == ',') // skip empty elements
- {
- end = beg;
- continue elements;
- }
- if (buf[beg] == '=' || buf[beg] == ';' || buf[beg] == '"')
- throw new ParseException("Bad header format: '" + header +
- "'nEmpty element name at position " +
- beg);
- end = beg+1; // extract element name
- while (end < len && !Character.isWhitespace(buf[end]) &&
- buf[end] != '=' && buf[end] != ',' && buf[end] != ';')
- end++;
- elem_name = new String(buf, beg, end-beg);
- beg = skipSpace(buf, end);
- if (beg < len && buf[beg] == '=') // element value
- {
- abeg[0] = beg+1;
- elem_value = parseValue(buf, abeg, header, dequote);
- end = abeg[0];
- }
- else
- {
- elem_value = null;
- end = beg;
- }
- NVPair[] params = new NVPair[0];
- params: while (true)
- {
- String param_name, param_value;
- beg = skipSpace(buf, end); // expect ";"
- if (beg == len || buf[beg] != ';')
- break params;
- beg = skipSpace(buf, beg+1);
- if (beg == len || buf[beg] == ',')
- {
- end = beg;
- break params;
- }
- if (buf[beg] == ';') // skip empty parameters
- {
- end = beg;
- continue params;
- }
- if (buf[beg] == '=' || buf[beg] == '"')
- throw new ParseException("Bad header format: '" + header +
- "'nEmpty parameter name at position "+
- beg);
- end = beg+1; // extract param name
- while (end < len && !Character.isWhitespace(buf[end]) &&
- buf[end] != '=' && buf[end] != ',' && buf[end] != ';')
- end++;
- param_name = new String(buf, beg, end-beg);
- beg = skipSpace(buf, end);
- if (beg < len && buf[beg] == '=') // element value
- {
- abeg[0] = beg+1;
- param_value = parseValue(buf, abeg, header, dequote);
- end = abeg[0];
- }
- else
- {
- param_value = null;
- end = beg;
- }
- params = Util.resizeArray(params, params.length+1);
- params[params.length-1] = new NVPair(param_name, param_value);
- }
- elems.addElement(
- new HttpHeaderElement(elem_name, elem_value, params));
- }
- return elems;
- }
- /**
- * Parse the value part. Accepts either token or quoted string.
- */
- private static String parseValue(char[] buf, int[] abeg, String header,
- boolean dequote)
- throws ParseException
- {
- int beg = abeg[0], end = beg, len = buf.length;
- String value;
- beg = skipSpace(buf, beg);
- if (beg < len && buf[beg] == '"') // it's a quoted-string
- {
- beg++;
- end = beg;
- char[] deq_buf = null;
- int deq_pos = 0, lst_pos = beg;
- while (end < len && buf[end] != '"')
- {
- if (buf[end] == '\')
- {
- if (dequote) // dequote char
- {
- if (deq_buf == null)
- deq_buf = new char[buf.length];
- System.arraycopy(buf, lst_pos, deq_buf, deq_pos,
- end-lst_pos);
- deq_pos += end-lst_pos;
- lst_pos = ++end;
- }
- else
- end++; // skip quoted char
- }
- end++;
- }
- if (end == len)
- throw new ParseException("Bad header format: '" + header +
- "'nClosing <"> for quoted-string"+
- " starting at position " +
- (beg-1) + " not found");
- if (deq_buf != null)
- {
- System.arraycopy(buf, lst_pos, deq_buf, deq_pos, end-lst_pos);
- deq_pos += end-lst_pos;
- value = new String(deq_buf, 0, deq_pos);
- }
- else
- value = new String(buf, beg, end-beg);
- end++;
- }
- else // it's a simple token value
- {
- end = beg;
- while (end < len && !Character.isWhitespace(buf[end]) &&
- buf[end] != ',' && buf[end] != ';')
- end++;
- value = new String(buf, beg, end-beg);
- }
- abeg[0] = end;
- return value;
- }
- /**
- * Determines if the given header contains a certain token. The header
- * must conform to the rules outlined in parseHeader().
- *
- * @see #parseHeader(java.lang.String)
- * @param header the header value.
- * @param token the token to find; the match is case-insensitive.
- * @return true if the token is present, false otherwise.
- * @exception ParseException if this is thrown parseHeader().
- */
- public final static boolean hasToken(String header, String token)
- throws ParseException
- {
- if (header == null)
- return false;
- else
- return parseHeader(header).contains(new HttpHeaderElement(token));
- }
- /**
- * Get the HttpHeaderElement with the name <var>name</var>.
- *
- * @param header a vector of HttpHeaderElement's, such as is returned
- * from <code>parseHeader()</code>
- * @param name the name of element to retrieve; matching is
- * case-insensitive
- * @return the request element, or null if none found.
- * @see #parseHeader(java.lang.String)
- */
- public final static HttpHeaderElement getElement(Vector header, String name)
- {
- int idx = header.indexOf(new HttpHeaderElement(name));
- if (idx == -1)
- return null;
- else
- return (HttpHeaderElement) header.elementAt(idx);
- }
- /**
- * retrieves the value associated with the parameter <var>param</var> in
- * a given header string. It parses the header using
- * <code>parseHeader()</code> and then searches the first element for the
- * given parameter. This is used especially in headers like
- * 'Content-type' and 'Content-Disposition'.
- *
- * <P>quoted characters ("x") in a quoted string are dequoted.
- *
- * @see #parseHeader(java.lang.String)
- * @param param the parameter name
- * @param hdr the header value
- * @return the value for this parameter, or null if not found.
- * @exception ParseException if the above syntax rules are violated.
- */
- public final static String getParameter(String param, String hdr)
- throws ParseException
- {
- NVPair[] params = ((HttpHeaderElement) parseHeader(hdr).firstElement()).
- getParams();
- for (int idx=0; idx<params.length; idx++)
- {
- if (params[idx].getName().equalsIgnoreCase(param))
- return params[idx].getValue();
- }
- return null;
- }
- /**
- * Assembles a Vector of HttpHeaderElements into a full header string.
- * The individual header elements are seperated by a ", ".
- *
- * @param the parsed header
- * @return a string containing the assembled header
- */
- public final static String assembleHeader(Vector pheader)
- {
- StringBuffer hdr = new StringBuffer(200);
- int len = pheader.size();
- for (int idx=0; idx<len; idx++)
- {
- ((HttpHeaderElement) pheader.elementAt(idx)).appendTo(hdr);
- hdr.append(", ");
- }
- hdr.setLength(hdr.length()-2);
- return hdr.toString();
- }
- /**
- * returns the position of the first non-space character in a char array
- * starting a position pos.
- *
- * @param str the char array
- * @param pos the position to start looking
- * @return the position of the first non-space character
- */
- final static int skipSpace(char[] str, int pos)
- {
- int len = str.length;
- while (pos < len && Character.isWhitespace(str[pos])) pos++;
- return pos;
- }
- /**
- * returns the position of the first space character in a char array
- * starting a position pos.
- *
- * @param str the char array
- * @param pos the position to start looking
- * @return the position of the first space character, or the length of
- * the string if not found
- */
- final static int findSpace(char[] str, int pos)
- {
- int len = str.length;
- while (pos < len && !Character.isWhitespace(str[pos])) pos++;
- return pos;
- }
- /**
- * returns the position of the first non-token character in a char array
- * starting a position pos.
- *
- * @param str the char array
- * @param pos the position to start looking
- * @return the position of the first non-token character, or the length
- * of the string if not found
- */
- final static int skipToken(char[] str, int pos)
- {
- int len = str.length;
- while (pos < len && TokenChar.get(str[pos])) pos++;
- return pos;
- }
- /**
- * Does the string need to be quoted when sent in a header? I.e. does
- * it contain non-token characters?
- *
- * @param str the string
- * @return true if it needs quoting (i.e. it contains non-token chars)
- */
- final static boolean needsQuoting(String str)
- {
- int len = str.length(), pos = 0;
- while (pos < len && TokenChar.get(str.charAt(pos))) pos++;
- return (pos < len);
- }
- /**
- * Compares two http urls for equality. This exists because the method
- * <code>java.net.URL.sameFile()</code> is broken (an explicit port 80
- * doesn't compare equal to an implicit port, and it doesn't take
- * escapes into account).
- *
- * <P>Two http urls are considered equal if they have the same protocol
- * (case-insensitive match), the same host (case-insensitive), the
- * same port and the same file (after decoding escaped characters).
- *
- * @param url1 the first url
- * @param url1 the second url
- * @return true if <var>url1</var> and <var>url2</var> compare equal
- */
- public final static boolean sameHttpURL(URL url1, URL url2)
- {
- if (!url1.getProtocol().equalsIgnoreCase(url2.getProtocol()))
- return false;
- if (!url1.getHost().equalsIgnoreCase(url2.getHost()))
- return false;
- int port1 = url1.getPort(), port2 = url2.getPort();
- if (port1 == -1) port1 = URI.defaultPort(url1.getProtocol());
- if (port2 == -1) port2 = URI.defaultPort(url1.getProtocol());
- if (port1 != port2)
- return false;
- try
- { return URI.unescape(url1.getFile(), null).equals(URI.unescape(url2.getFile(), null)); }
- catch (ParseException pe)
- { return url1.getFile().equals(url2.getFile());}
- }
- /**
- * Return the default port used by a given protocol.
- *
- * @param protocol the protocol
- * @return the port number, or 0 if unknown
- * @deprecated use URI.defaultPort() instead
- * @see HTTPClient.URI#defaultPort(java.lang.String)
- */
- public final static int defaultPort(String protocol)
- {
- return URI.defaultPort(protocol);
- }
- /**
- * Parse the http date string. java.util.Date will do this fine, but
- * is deprecated, so we use SimpleDateFormat instead.
- *
- * @param dstr the date string to parse
- * @return the Date object
- */
- final static Date parseHttpDate(String dstr)
- {
- synchronized (http_parse_lock)
- {
- if (parse_1123 == null)
- setupParsers();
- }
- try
- { return parse_1123.parse(dstr); }
- catch (java.text.ParseException pe)
- { }
- try
- { return parse_850.parse(dstr); }
- catch (java.text.ParseException pe)
- { }
- try
- { return parse_asctime.parse(dstr); }
- catch (java.text.ParseException pe)
- { throw new IllegalArgumentException(pe.toString()); }
- }
- private static final void setupParsers()
- {
- parse_1123 =
- new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
- parse_850 =
- new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss 'GMT'", Locale.US);
- parse_asctime =
- new SimpleDateFormat("EEE MMM d HH:mm:ss yyyy", Locale.US);
- parse_1123.setTimeZone(new SimpleTimeZone(0, "GMT"));
- parse_850.setTimeZone(new SimpleTimeZone(0, "GMT"));
- parse_asctime.setTimeZone(new SimpleTimeZone(0, "GMT"));
- parse_1123.setLenient(true);
- parse_850.setLenient(true);
- parse_asctime.setLenient(true);
- }
- /**
- * This returns a string containing the date and time in <var>date</var>
- * formatted according to a subset of RFC-1123. The format is defined in
- * the HTTP/1.0 spec (RFC-1945), section 3.3, and the HTTP/1.1 spec
- * (RFC-2616), section 3.3.1. Note that Date.toGMTString() is close, but
- * is missing the weekday and supresses the leading zero if the day is
- * less than the 10th. Instead we use the SimpleDateFormat class.
- *
- * <P>Some versions of JDK 1.1.x are bugged in that their GMT uses
- * daylight savings time... Therefore we use our own timezone
- * definitions.
- *
- * @param date the date and time to be converted
- * @return a string containg the date and time as used in http
- */
- public static final String httpDate(Date date)
- {
- synchronized (http_format_lock)
- {
- if (http_format == null)
- setupFormatter();
- }
- return http_format.format(date);
- }
- private static final void setupFormatter()
- {
- http_format =
- new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
- http_format.setTimeZone(new SimpleTimeZone(0, "GMT"));
- }
- /**
- * Escape unsafe characters in a path.
- *
- * @param path the original path
- * @return the path with all unsafe characters escaped
- */
- final static String escapeUnsafeChars(String path)
- {
- int len = path.length();
- char[] buf = new char[3*len];
- int dst = 0;
- for (int src=0; src<len; src++)
- {
- char ch = path.charAt(src);
- if (ch >= 128 || UnsafeChar.get(ch))
- {
- buf[dst++] = '%';
- buf[dst++] = hex_map[(ch & 0xf0) >>> 4];
- buf[dst++] = hex_map[ch & 0x0f];
- }
- else
- buf[dst++] = ch;
- }
- if (dst > len)
- return new String(buf, 0, dst);
- else
- return path;
- }
- static final char[] hex_map =
- {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
- /**
- * Extract the path from an http resource.
- *
- * <P>The "resource" part of an HTTP URI can contain a number of parts,
- * some of which are not always of interest. These methods here will
- * extract the various parts, assuming the following syntanx (taken from
- * RFC-2616):
- *
- * <PRE>
- * resource = [ "/" ] [ path ] [ ";" params ] [ "?" query ] [ "#" fragment ]
- * </PRE>
- *
- * @param the resource to split
- * @return the path, including any leading "/"
- * @see #getParams
- * @see #getQuery
- * @see #getFragment
- */
- public final static String getPath(String resource)
- {
- int p, end = resource.length();
- if ((p = resource.indexOf('#')) != -1) // find fragment
- end = p;
- if ((p = resource.indexOf('?')) != -1 && p < end) // find query
- end = p;
- if ((p = resource.indexOf(';')) != -1 && p < end) // find params
- end = p;
- return resource.substring(0, end);
- }
- /**
- * Extract the params part from an http resource.
- *
- * @param the resource to split
- * @return the params, or null if there are none
- * @see #getPath
- */
- public final static String getParams(String resource)
- {
- int beg, f, q;
- if ((beg = resource.indexOf(';')) == -1) // find params
- return null;
- if ((f = resource.indexOf('#')) != -1 && f < beg) // find fragment
- return null;
- if ((q = resource.indexOf('?')) != -1 && q < beg) // find query
- return null;
- if (q == -1 && f == -1)
- return resource.substring(beg+1);
- if (f == -1 || (q != -1 && q < f))
- return resource.substring(beg+1, q);
- else
- return resource.substring(beg+1, f);
- }
- /**
- * Extract the query string from an http resource.
- *
- * @param the resource to split
- * @return the query, or null if there was none
- * @see #getPath
- */
- public final static String getQuery(String resource)
- {
- int beg, f;
- if ((beg = resource.indexOf('?')) == -1) // find query
- return null;
- if ((f = resource.indexOf('#')) != -1 && f < beg) // find fragment
- return null; // '?' is in fragment
- if (f == -1)
- return resource.substring(beg+1); // no fragment
- else
- return resource.substring(beg+1, f); // strip fragment
- }
- /**
- * Extract the fragment part from an http resource.
- *
- * @param the resource to split
- * @return the fragment, or null if there was none
- * @see #getPath
- */
- public final static String getFragment(String resource)
- {
- int beg;
- if ((beg = resource.indexOf('#')) == -1) // find fragment
- return null;
- else
- return resource.substring(beg+1);
- }
- /**
- * Match <var>pattern</var> against <var>name</var>, where
- * <var>pattern</var> may contain wildcards ('*').
- *
- * @param pattern the pattern to match; may contain '*' which match
- * any number (0 or more) of any character (think file
- * globbing)
- * @param name the name to match against the pattern
- * @return true if the name matches the pattern; false otherwise
- */
- public static final boolean wildcardMatch(String pattern, String name)
- {
- return
- wildcardMatch(pattern, name, 0, 0, pattern.length(), name.length());
- }
- private static final boolean wildcardMatch(String pattern, String name,
- int ppos, int npos, int plen,
- int nlen)
- {
- // find wildcard
- int star = pattern.indexOf('*', ppos);
- if (star < 0)
- {
- return ((plen-ppos) == (nlen-npos) &&
- pattern.regionMatches(ppos, name, npos, plen-ppos));
- }
- // match prefix
- if (!pattern.regionMatches(ppos, name, npos, star-ppos))
- return false;
- // match suffix
- if (star == plen-1)
- return true;
- while(!wildcardMatch(pattern, name, star+1, npos, plen, nlen) &&
- npos < nlen)
- npos++;
- return (npos < nlen);
- }
- }