All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.htmlparser.http.ConnectionManager Maven / Gradle / Ivy

Go to download

bboss is a j2ee framework include aop/ioc,mvc,persistent,taglib,rpc,event ,bean-xml serializable and so on.http://www.bbossgroups.com

The newest version!
// HTMLParser Library $Name: v1_5 $ - A java-based parser for HTML
// http://sourceforge.org/projects/htmlparser
// Copyright (C) 2004 Derrick Oswald
//
// Revision Control Information
//
// $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/http/ConnectionManager.java,v $
// $Author: derrickoswald $
// $Date: 2005/05/15 11:49:04 $
// $Revision: 1.4 $
//
// 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.1 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
//

package org.htmlparser.http;

import org.htmlparser.util.ParserException;

import java.io.File;
import java.io.IOException;
import java.net.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * Handles proxies, password protected URLs and request properties
 * including cookies.
 */
public class ConnectionManager
{
    /**
     * Default Request header fields.
     * So far this is just "User-Agent" and "Accept-Encoding".
     */
    protected static HashMap mDefaultRequestProperties = new HashMap ();
    static
    {
        mDefaultRequestProperties.put ("User-Agent", "HTMLParser/"
            + org.htmlparser.Parser.VERSION_NUMBER);
        mDefaultRequestProperties.put ("Accept-Encoding", "gzip, deflate");
    }

    /**
     * Messages for page not there (404).
     */
    private static final String[] FOUR_OH_FOUR =
    {
        "The web site you seek cannot be located,"
            + " but countless more exist",
        "You step in the stream, but the water has moved on."
            + " This page is not here.",
        "Yesterday the page existed. Today it does not."
            + " The internet is like that.",
        "That page was so big. It might have been very useful."
            + " But now it is gone.",
        "Three things are certain: death, taxes and broken links."
            + " Guess which has occured.",
        "Chaos reigns within. Reflect, repent and enter the correct URL."
            + " Order shall return.",
        "Stay the patient course. Of little worth is your ire."
            + " The page is not found.",
        "A non-existant URL reduces your expensive computer to a simple stone.",
        "Many people have visited that page."
            + " Today, you are not one of the lucky ones.",
        "Cutting the wind with a knife. Bookmarking a URL."
            + " Both are ephemeral.",
    };

    /**
     * Base 64 character translation table.
     */
    private static final char[] BASE64_CHAR_TABLE =
         ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        + "abcdefghijklmnopqrstuvwxyz0123456789+/").toCharArray ();

    /**
     * Request header fields.
     */
    protected HashMap mRequestProperties;

    /**
     * The proxy server name.
     */
    protected String mProxyHost;

    /**
     * The proxy port number.
     */
    protected int mProxyPort;

    /**
     * The proxy username name.
     */
    protected String mProxyUser;

    /**
     * The proxy user password.
     */
    protected String mProxyPassword;

    /**
     * The username name for accessing the URL.
     */
    protected String mUser;

    /**
     * The user password for accessing the URL.
     */
    protected String mPassword;

    /**
     * Cookie storage, a HashMap (by site or host) of Lists of Cookies.
     * This will be null if cookie processing is disabled (default).
     */
    protected HashMap mCookieJar;

    /**
     * The object to be notified prior to and after each connection.
     */
    protected ConnectionMonitor mMonitor;

    /**
     * Create a connection manager.
     */
    public ConnectionManager ()
    {
        this (getDefaultRequestProperties ());
    }

    /**
     * Create a connection manager with the given connection properties.
     * @param properties Name/value pairs to be added to the HTTP request.
     */
    public ConnectionManager (HashMap properties)
    {
        mRequestProperties = properties;
        mProxyHost = null;
        mProxyPort = 0;
        mProxyUser = null;
        mProxyPassword = null;
        mUser = null;
        mPassword = null;
        mCookieJar = null;
        mMonitor = null;
    }

    //
    // static methods
    //

    /**
     * Get the current default request header properties.
     * A String-to-String map of header keys and values.
     * These fields are set by the parser when creating a connection.
     * @return The default set of request header properties that will
     * currently be used.
     * @see #mDefaultRequestProperties
     * @see #setRequestProperties
     */
    public static HashMap getDefaultRequestProperties ()
    {
        return (mDefaultRequestProperties);
    }

    /**
     * Set the default request header properties.
     * A String-to-String map of header keys and values.
     * These fields are set by the parser when creating a connection.
     * Some of these can be set directly on a URLConnection,
     * i.e. If-Modified-Since is set with setIfModifiedSince(long),
     * but since the parser transparently opens the connection on behalf
     * of the developer, these properties are not available before the
     * connection is fetched. Setting these request header fields affects all
     * subsequent connections opened by the parser. For more direct control
     * create a URLConnection massage it the way you want and
     * then set it on the parser.

* From * RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1: *

     * 5.3 Request Header Fields
     *
     *    The request-header fields allow the client to pass additional
     *    information about the request, and about the client itself, to the
     *    server. These fields act as request modifiers, with semantics
     *    equivalent to the parameters on a programming language method
     *    invocation.
     *
     *        request-header = Accept                   ; Section 14.1
     *                       | Accept-Charset           ; Section 14.2
     *                       | Accept-Encoding          ; Section 14.3
     *                       | Accept-Language          ; Section 14.4
     *                       | Authorization            ; Section 14.8
     *                       | Expect                   ; Section 14.20
     *                       | From                     ; Section 14.22
     *                       | Host                     ; Section 14.23
     *                       | If-Match                 ; Section 14.24
     *                       | If-Modified-Since        ; Section 14.25
     *                       | If-None-Match            ; Section 14.26
     *                       | If-Range                 ; Section 14.27
     *                       | If-Unmodified-Since      ; Section 14.28
     *                       | Max-Forwards             ; Section 14.31
     *                       | Proxy-Authorization      ; Section 14.34
     *                       | Range                    ; Section 14.35
     *                       | Referer                  ; Section 14.36
     *                       | TE                       ; Section 14.39
     *                       | User-Agent               ; Section 14.43
     *
     *    Request-header field names can be extended reliably only in
     *    combination with a change in the protocol version. However, new or
     *    experimental header fields MAY be given the semantics of request-
     *    header fields if all parties in the communication recognize them to
     *    be request-header fields. Unrecognized header fields are treated as
     *    entity-header fields.
     * 
* @param properties The new set of default request header properties to * use. This affects all subsequently created connections. * @see #mDefaultRequestProperties * @see #setRequestProperties */ public static void setDefaultRequestProperties (HashMap properties) { mDefaultRequestProperties = properties; } /** * Gets the request header for the connection. * This header is generated from the contents of the connection * and may not be exactly the same as the request that will be sent. * @param connection The connection to convert into an HTTP request header. * @return The string that would be sent by the HTTP request. */ public static String getRequestHeader (HttpURLConnection connection) { // dump it StringBuilder buffer; Map map; String key; List items; buffer = new StringBuilder (1024); buffer.append (connection.getRequestMethod ()); buffer.append (" "); buffer.append (connection.getURL ()); buffer.append (" HTTP/1.1\n"); map = connection.getRequestProperties (); for (Iterator iter = map.keySet ().iterator (); iter.hasNext (); ) { key = (String)iter.next (); items = (List)map.get (key); buffer.append (key); buffer.append (": "); for (int i = 0; i < items.size (); i++) { if (0 != i) buffer.append (", "); buffer.append (items.get (i)); } buffer.append ("\n"); } return (buffer.toString ()); } /** * Gets the response header for the connection. * Calling this method on an un-connected connection will * generate an error, as will an attempt to get information * from a connected but invalid connection. * This header is generated from the contents of the connection * and may not be exactly the same as the response that was received. * @param conn The connection to convert into an HTTP response header. * @return The string that was sent as the HTTP response. */ public static String getResponseHeader (HttpURLConnection conn) { // dump it StringBuilder buffer; int code; String message; String key; String value; buffer = new StringBuilder (1024); try { code = conn.getResponseCode (); if (-1 != code) { message = conn.getResponseMessage (); buffer.append ("HTTP/1.1 "); buffer.append (code); buffer.append (" "); buffer.append (message); buffer.append ("\n"); for (int i = 0; null != (value = conn.getHeaderField (i)); i++) { key = conn.getHeaderFieldKey (i); if (null != key) { buffer.append (key); buffer.append (": "); buffer.append (value); buffer.append ("\n"); } } } } catch (IOException ioe) { buffer.append (ioe.toString ()); } return (buffer.toString ()); } /** * Get the current request header properties. * A String-to-String map of header keys and values, * excluding proxy items, cookies and URL authorization. * @return The request header properties for this connection manager. */ public HashMap getRequestProperties () { return (mRequestProperties); } /** * Set the current request properties. * Replaces the current set of fixed request properties with the given set. * This does not replace the Proxy-Authorization property which is * constructed from the values of {@link #setProxyUser} * and {@link #setProxyPassword} values or the Authorization property * which is constructed from the {@link #setUser} * and {@link #setPassword} values. Nor does it replace the * Cookie property which is constructed from the current cookie jar. * @param properties The new fixed properties. */ public void setRequestProperties (HashMap properties) { mRequestProperties = properties; } /** * Get the proxy host name, if any. * @return Returns the proxy host. */ public String getProxyHost () { return (mProxyHost); } /** * Set the proxy host to use. * @param host The host to use for proxy access. * Note: You must also set the proxy {@link #setProxyPort port}. */ public void setProxyHost (String host) { mProxyHost = host; } /** * Get the proxy port number. * @return Returns the proxy port. */ public int getProxyPort () { return (mProxyPort); } /** * Set the proxy port number. * @param port The proxy port. * Note: You must also set the proxy {@link #setProxyHost host}. */ public void setProxyPort (int port) { mProxyPort = port; } /** * Get the user name for proxy authorization, if any. * @return Returns the proxy user, * or null if no proxy authorization is required. */ public String getProxyUser () { return (mProxyUser); } /** * Set the user name for proxy authorization. * @param user The proxy user name. * Note: You must also set the proxy {@link #setProxyPassword password}. */ public void setProxyUser (String user) { mProxyUser = user; } /** * Set the proxy user's password. * @return Returns the proxy password. */ public String getProxyPassword () { return (mProxyPassword); } /** * Get the proxy user's password. * @param password The password for the proxy user. * Note: You must also set the proxy {@link #setProxyUser user}. */ public void setProxyPassword (String password) { mProxyPassword = password; } /** * Get the user name to access the URL. * @return Returns the username that will be used to access the URL, * or null if no authorization is required. */ public String getUser () { return (mUser); } /** * Set the user name to access the URL. * @param user The user name for accessing the URL. * Note: You must also set the {@link #setPassword password}. */ public void setUser (String user) { mUser = user; } /** * Get the URL users's password. * @return Returns the URL password. */ public String getPassword () { return (mPassword); } /** * Set the URL users's password. * @param password The password for the URL. */ public void setPassword (String password) { mPassword = password; } /** * Predicate to determine if cookie processing is currently enabled. * @return true if cookies are being processed. */ public boolean getCookieProcessingEnabled () { return (null != mCookieJar); } /** * Enables and disabled cookie processing. * @param enable if true cookie processing will occur, * else cookie processing will be turned off. */ public void setCookieProcessingEnabled (boolean enable) { if (enable) mCookieJar = (null == mCookieJar) ? new HashMap () : mCookieJar; else mCookieJar = null; } /** * Adds a cookie to the cookie jar. * @param cookie The cookie to add. * @param domain The domain to use in case the cookie has no domain attribute. */ public void setCookie (Cookie cookie, String domain) { String path; List cookies; Cookie probe; if (null != cookie.getDomain ()) domain = cookie.getDomain (); path = cookie.getPath (); if (null == mCookieJar) mCookieJar = new HashMap (); // turn on cookie processing cookies = (List)mCookieJar.get (domain); if (null != cookies) { for (int j = 0; j < cookies.size (); j++) { probe = (Cookie)cookies.get (j); if (probe.getName ().equalsIgnoreCase (cookie.getName ())) { // we keep paths sorted most specific to least if (probe.getPath ().equals (path)) { cookies.set (j,cookie); // replace break; } else if (path.startsWith (probe.getPath ())) { cookies.add (j,cookie); break; } } } } else { // new cookie list needed cookies = new ArrayList (); cookies.add (cookie); mCookieJar.put (domain, cookies); } } /** * Get the monitoring object, if any. * @return Returns the monitor, or null if none has been assigned. */ public ConnectionMonitor getMonitor () { return (mMonitor); } /** * Set the monitoring object. * @param monitor The monitor to set. */ public void setMonitor (ConnectionMonitor monitor) { mMonitor = monitor; } /** * Opens a connection using the given url. * @param url The url to open. * @return The connection. * @exception ParserException if an i/o exception occurs accessing the url. */ public URLConnection openConnection (URL url) throws ParserException { Properties sysprops; HashMap properties; Iterator enumeration; String key; String value; String set = null; // old proxySet value String host = null; // old proxyHost value String port = null; // old proxyPort value String host2 = null; // old http.proxyHost value String port2 = null; // old http.proxyPort value HttpURLConnection http; String auth; String encoded; URLConnection ret; try { try { // set up for proxy if ((null != getProxyHost ()) && (0 != getProxyPort ())) { sysprops = System.getProperties (); set = (String)sysprops.put ("proxySet", "true"); host = (String)sysprops.put ("proxyHost", getProxyHost ()); port = (String)sysprops.put ("proxyPort", Integer.toString (getProxyPort ())); // see http://java.sun.com/j2se/1.4.2/docs/guide/net/properties.html host2 = (String)sysprops.put ("http.proxyHost", getProxyHost ()); port2 = (String)sysprops.put ("http.proxyPort", Integer.toString (getProxyPort ())); System.setProperties (sysprops); } // open the connection... but don't connect yet ret = url.openConnection (); if (ret instanceof HttpURLConnection) { http = (HttpURLConnection)ret; // set the fixed request properties properties = getRequestProperties (); if (null != properties) for (enumeration = properties.entrySet().iterator(); enumeration.hasNext();) { Map.Entry entry = (Entry) enumeration.next(); key = (String)entry.getKey(); value = (String)entry.getValue(); ret.setRequestProperty (key, value); } // set the proxy name and password if ((null != getProxyUser ()) && (null != getProxyPassword ())) { auth = getProxyUser () + ":" + getProxyPassword (); encoded = encode (auth.getBytes("ISO-8859-1")); ret.setRequestProperty ("Proxy-Authorization", encoded); } // set the URL name and password if ((null != getUser ()) && (null != getPassword ())) { auth = getUser () + ":" + getPassword (); encoded = encode (auth.getBytes("ISO-8859-1")); ret.setRequestProperty ("Authorization", "Basic " + encoded); } // set the cookies based on the url addCookies (ret); if (null != getMonitor ()) getMonitor ().preConnect (http); } else http = null; try { ret.connect (); if (null != http) { if (null != getMonitor ()) getMonitor ().postConnect (http); parseCookies (ret); } } catch (UnknownHostException uhe) { int message = (int)(Math.random () * FOUR_OH_FOUR.length); throw new ParserException (FOUR_OH_FOUR[message], uhe); } catch (IOException ioe) { throw new ParserException (ioe.getMessage (), ioe); } } finally { if ((null != getProxyHost ()) && (0 != getProxyPort ())) { sysprops = System.getProperties (); if (null != set) sysprops.put ("proxySet", set); else sysprops.remove ("proxySet"); if (null != host) sysprops.put ("proxyHost", host); else sysprops.remove ("proxyHost"); if (null != port) sysprops.put ("proxyPort", port); else sysprops.remove ("proxyPort"); if (null != host2) sysprops.put ("http.proxyHost", host2); else sysprops.remove ("http.proxyHost"); if (null != port2) sysprops.put ("http.proxyPort", port2); else sysprops.remove ("http.proxyPort"); System.setProperties (sysprops); } } } catch (IOException ioe) { String msg = "Error in opening a connection to " + url.toExternalForm (); ParserException ex = new ParserException (msg, ioe); throw ex; } return (ret); } /** * Encodes a byte array into BASE64 in accordance with * RFC 2045. * @param array The bytes to convert. * @return A BASE64 encoded string. */ public final static String encode (byte[] array) { int last; // last byte int count; // character count int separators; // line separator count int length; // length of returned string char[] encoded; // encoded characters int left; // bytes left int end; int block; // encoding buffer int r; // shift count int n; // byte to encode int index; // index into output array String ret; if ((null != array) && (0 != array.length)) { last = array.length - 1; count = (last / 3 + 1) << 2; separators = (count - 1) / 76; length = count + separators; encoded = new char[length]; index = 0; separators = 0; for (int i = 0; i <= last; i += 3) { left = last - i; end = (left > 1 ? 2 : left); // collect 1 to 3 bytes to encode block = 0; r = 16; for (int j = 0; j <= end; j++) { n = array[i + j]; block += (n < 0 ? n + 256 : n) << r; r -= 8; } // encode into 2-4 chars padding with '=' if no data left encoded[index++] = BASE64_CHAR_TABLE[(block >>> 18) & 0x3f]; encoded[index++] = BASE64_CHAR_TABLE[(block >>> 12) & 0x3f]; encoded[index++] = left > 0 ? BASE64_CHAR_TABLE[(block >>> 6) & 0x3f] : '='; encoded[index++] = left > 1 ? BASE64_CHAR_TABLE[block & 0x3f] : '='; if ((0 == (index - separators) % 76) && (index < length)) { encoded[index++] = '\n'; separators += 1; } } ret = new String (encoded); } else ret = ""; return (ret); } /** * Turn spaces into %20. * ToDo: make this more generic * (see RFE #1010593 provide URL encoding/decoding utilities). * @param url The url containing spaces. * @return The URL with spaces as %20 sequences. */ public String fixSpaces (String url) { int index; int length; char ch; StringBuilder buffer; index = url.indexOf (' '); if (-1 != index) { length = url.length (); buffer = new StringBuilder (length * 3); buffer.append (url.substring (0, index)); for (int i = index; i < length; i++) { ch = url.charAt (i); if (ch==' ') buffer.append ("%20"); else buffer.append (ch); } url = buffer.toString (); } return (url); } /** * Opens a connection based on a given string. * The string is either a file, in which case file://localhost * is prepended to a canonical path derived from the string, or a url that * begins with one of the known protocol strings, i.e. http://. * Embedded spaces are silently converted to %20 sequences. * @param string The name of a file or a url. * @return The connection. * @exception ParserException if the string is not a valid url or file. */ public URLConnection openConnection (String string) throws ParserException { final String prefix = "file://localhost"; String resource; URL url; StringBuilder buffer; URLConnection ret; try { url = new URL (fixSpaces (string)); ret = openConnection (url); } catch (MalformedURLException murle) { // try it as a file try { File file = new File (string); resource = file.getCanonicalPath (); buffer = new StringBuilder (prefix.length () + resource.length ()); buffer.append (prefix); if (!resource.startsWith ("/")) buffer.append ("/"); buffer.append (resource); url = new URL (fixSpaces (buffer.toString ())); ret = openConnection (url); } catch (MalformedURLException murle2) { String msg = "Error in opening a connection to " + string; ParserException ex = new ParserException (msg, murle2); throw ex; } catch (IOException ioe) { String msg = "Error in opening a connection to " + string; ParserException ex = new ParserException (msg, ioe); throw ex; } } return (ret); } /** * Generate a HTTP cookie header value string from the cookie jar. *
     *   The syntax for the header is:
     *
     *    cookie          =       "Cookie:" cookie-version
     *                            1*((";" | ",") cookie-value)
     *    cookie-value    =       NAME "=" VALUE [";" path] [";" domain]
     *    cookie-version  =       "$Version" "=" value
     *    NAME            =       attr
     *    VALUE           =       value
     *    path            =       "$Path" "=" value
     *    domain          =       "$Domain" "=" value
     *
     * 
* @param connection The connection being accessed. * @see RFC 2109 * @see RFC 2396 */ public void addCookies (URLConnection connection) { List list; URL url; String host; String path; String domain; if (null != mCookieJar) { list = null; // get the site from the URL url = connection.getURL (); host = url.getHost (); path = url.getPath (); if (0 == path.length ()) path = "/"; if (null != host) { // http://www.objectsdevelopment.com/portal/modules/freecontent/content/javawebserver.html list = addCookies ((List)mCookieJar.get (host), path, list); domain = getDomain (host); if (null != domain) list = addCookies ((List)mCookieJar.get (domain), path, list); else // maybe it is the domain we're accessing list = addCookies ((List)mCookieJar.get ("." + host), path, list); } if (null != list) connection.setRequestProperty ("Cookie", generateCookieProperty (list)); } } /** * Add qualified cookies from cookies into list. * @param cookies The list of cookies to check (may be null). * @param path The path being accessed. * @param list The list of qualified cookies. * @return The list of qualified cookies. */ protected List addCookies (List cookies, String path, List list) { Cookie cookie; Date expires; Date now; if (null != cookies) { now = new Date (); for (int i = 0; i < cookies.size (); i++) { cookie = (Cookie)cookies.get (i); expires = cookie.getExpiryDate (); if ((null != expires) && expires.before (now)) { cookies.remove (i); i--; // dick with the loop variable } else if (path.startsWith (cookie.getPath ())) { if (null == list) list = new ArrayList (); list.add (cookie); } } } return (list); } /** * Get the domain from a host. * @param host The supposed host name. * @return The domain (with the leading dot), * or null if the domain cannot be determined. */ protected String getDomain (String host) { StringTokenizer tokenizer; int count; String server; int length; boolean ok; char c; String ret; ret = null; tokenizer = new StringTokenizer (host, "."); count = tokenizer.countTokens (); if (3 <= count) { // have at least two dots, // check if we were handed an IP address by mistake length = host.length (); ok = false; for (int i = 0; i < length && !ok; i++) { c = host.charAt (i); if (!(Character.isDigit (c) || (c == '.'))) ok = true; } if (ok) { // so take everything after the first token server = tokenizer.nextToken (); length = server.length (); ret = host.substring (length); } } return (ret); } /** * Creates the cookie request property value from the list of * valid cookies for the domain. * @param cookies The list of valid cookies to be encoded in the request. * @return A string suitable for inclusion as the value of * the "Cookie:" request property. */ protected String generateCookieProperty (List cookies) { int version; Cookie cookie; StringBuilder buffer; String ret; ret = null; buffer = new StringBuilder (); version = 0; for (int i = 0; i < cookies.size (); i++) version = Math.max (version, ((Cookie)cookies.get (i)).getVersion ()); if (0 != version) { buffer.append ("$Version=\""); buffer.append (version); buffer.append ("\""); } for (int i = 0; i < cookies.size (); i++) { cookie = (Cookie)cookies.get (i); if (0 != buffer.length ()) buffer.append ("; "); buffer.append (cookie.getName ()); buffer.append ("="); if (0 != version) buffer.append ("\""); buffer.append (cookie.getValue ()); if (0 != version) buffer.append ("\""); if (0 != version) { if ((null != cookie.getPath ()) && (0 != cookie.getPath ().length ())) { buffer.append ("; $Path=\""); buffer.append (cookie.getPath ()); buffer.append ("\""); } if ((null != cookie.getDomain ()) && (0 != cookie.getDomain ().length ())) { buffer.append ("; $Domain=\""); buffer.append (cookie.getDomain ()); buffer.append ("\""); } } } if (0 != buffer.length ()) ret = buffer.toString (); return (ret); } /** * Check for cookie and parse into cookie jar. * @param connection The connection to extract cookie information from. */ public void parseCookies (URLConnection connection) { String string; List cookies; StringTokenizer tokenizer; String token; int index; String name; String key; String value; Cookie cookie; string = connection.getHeaderField ("Set-Cookie"); if (null != string) { // set-cookie = "Set-Cookie:" cookies // cookies = 1#cookie // cookie = NAME "=" VALUE *(";" cookie-av) // NAME = attr // VALUE = value // cookie-av = "Comment" "=" value // | "Domain" "=" value // | "Max-Age" "=" value // | "Path" "=" value // | "Secure" // | "Version" "=" 1*DIGIT cookies = new ArrayList (); tokenizer = new StringTokenizer (string, ";,", true); cookie = null; while (tokenizer.hasMoreTokens ()) { token = tokenizer.nextToken ().trim (); if (token.equals (";")) continue; else if (token.equals (",")) { cookie = null; continue; } index = token.indexOf ('='); if (-1 == index) { name = token; value = null; if (null == cookie) throw new IllegalStateException ("no cookie value"); key = name.toLowerCase (); } else { name = token.substring (0, index); value = token.substring (index + 1); key = name.toLowerCase (); } if (null == cookie) { cookie = new Cookie (name, value); cookies.add (cookie); } else { if (key.equals ("expires")) // Wdy, DD-Mon-YY HH:MM:SS GMT { String comma = tokenizer.nextToken (); String rest = tokenizer.nextToken (); SimpleDateFormat format = new SimpleDateFormat ( "EEE, dd-MMM-yy kk:mm:ss z"); try { Date date = format.parse (value + comma + rest); cookie.setExpiryDate (date); } catch (ParseException pe) { // ok now what cookie.setExpiryDate (null); } } else if (key.equals ("domain")) cookie.setDomain (value); else if (key.equals ("path")) cookie.setPath (value); else if (key.equals ("secure")) cookie.setSecure (true); else if (key.equals ("comment")) cookie.setComment (value); else if (key.equals ("version")) cookie.setVersion ( Integer.parseInt (value)); else if (key.equals ("max-age")) { Date date = new Date (); long then = date.getTime () + Integer.parseInt (value) * 1000; date.setTime (then); cookie.setExpiryDate (date); } else { // error,? unknown attribute, // maybe just another cookie // not separated by a comma cookie = new Cookie (name, value); cookies.add (cookie); } } } if (0 != cookies.size ()) saveCookies (cookies, connection); } } /** * Save the cookies received in the response header. * @param list The list of cookies extracted from the response header. * @param connection The connection (used when a cookie has no domain). */ protected void saveCookies (List list, URLConnection connection) { Cookie cookie; String domain; for (int i = 0; i < list.size (); i++) { cookie = (Cookie)list.get (i); domain = cookie.getDomain (); if (null == domain) domain = connection.getURL ().getHost (); setCookie (cookie, domain); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy