|
From: <ls...@us...> - 2007-06-25 09:50:33
|
Revision: 3306
http://jnode.svn.sourceforge.net/jnode/?rev=3306&view=rev
Author: lsantha
Date: 2007-06-25 02:32:16 -0700 (Mon, 25 Jun 2007)
Log Message:
-----------
Openjdk integration.
Added Paths:
-----------
trunk/core/src/openjdk/java/java/net/
trunk/core/src/openjdk/java/java/net/CacheRequest.java
trunk/core/src/openjdk/java/java/net/CacheResponse.java
trunk/core/src/openjdk/java/java/net/CookieHandler.java
trunk/core/src/openjdk/java/java/net/CookieManager.java
trunk/core/src/openjdk/java/java/net/CookiePolicy.java
trunk/core/src/openjdk/java/java/net/CookieStore.java
trunk/core/src/openjdk/java/java/net/HttpCookie.java
trunk/core/src/openjdk/java/java/net/HttpRetryException.java
trunk/core/src/openjdk/java/java/net/SecureCacheResponse.java
trunk/core/src/openjdk/java/java/security/AuthProvider.java
trunk/core/src/openjdk/java/java/security/KeyStore.java
trunk/core/src/openjdk/java/java/security/KeyStoreSpi.java
trunk/core/src/openjdk/java/java/security/UnrecoverableEntryException.java
trunk/core/src/openjdk/java/java/security/UnrecoverableKeyException.java
trunk/core/src/openjdk/java/java/util/LocaleISOData.java
trunk/core/src/openjdk/java/java/util/MissingResourceException.java
Added: trunk/core/src/openjdk/java/java/net/CacheRequest.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CacheRequest.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CacheRequest.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Represents channels for storing resources in the
+ * ResponseCache. Instances of such a class provide an
+ * OutputStream object which is called by protocol handlers to
+ * store the resource data into the cache, and also an abort() method
+ * which allows a cache store operation to be interrupted and
+ * abandoned. If an IOException is encountered while reading the
+ * response or writing to the cache, the current cache store operation
+ * will be aborted.
+ *
+ * @version 1.1, 03/09/22
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CacheRequest {
+
+ /**
+ * Returns an OutputStream to which the response body can be
+ * written.
+ *
+ * @return an OutputStream to which the response body can
+ * be written
+ * @throws IOException if an I/O error occurs while
+ * writing the response body
+ */
+ public abstract OutputStream getBody() throws IOException;
+
+ /**
+ * Aborts the attempt to cache the response. If an IOException is
+ * encountered while reading the response or writing to the cache,
+ * the current cache store operation will be abandoned.
+ */
+ public abstract void abort();
+}
Added: trunk/core/src/openjdk/java/java/net/CacheResponse.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CacheResponse.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CacheResponse.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.io.InputStream;
+import java.util.Map;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * Represent channels for retrieving resources from the
+ * ResponseCache. Instances of such a class provide an
+ * InputStream that returns the entity body, and also a
+ * getHeaders() method which returns the associated response headers.
+ *
+ * @version 1.1, 03/09/22
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CacheResponse {
+
+ /**
+ * Returns the response headers as a Map.
+ *
+ * @return An immutable Map from response header field names to
+ * lists of field values. The status line has null as its
+ * field name.
+ * @throws IOException if an I/O error occurs
+ * while getting the response headers
+ */
+ public abstract Map<String, List<String>> getHeaders() throws IOException;
+
+ /**
+ * Returns the response body as an InputStream.
+ *
+ * @return an InputStream from which the response body can
+ * be accessed
+ * @throws IOException if an I/O error occurs while
+ * getting the response body
+ */
+ public abstract InputStream getBody() throws IOException;
+}
Added: trunk/core/src/openjdk/java/java/net/CookieHandler.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CookieHandler.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CookieHandler.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.util.Map;
+import java.util.List;
+import java.io.IOException;
+import sun.security.util.SecurityConstants;
+
+/**
+ * A CookieHandler object provides a callback mechanism to hook up a
+ * HTTP state management policy implementation into the HTTP protocol
+ * handler. The HTTP state management mechanism specifies a way to
+ * create a stateful session with HTTP requests and responses.
+ *
+ * <p>A system-wide CookieHandler that to used by the HTTP protocol
+ * handler can be registered by doing a
+ * CookieHandler.setDefault(CookieHandler). The currently registered
+ * CookieHandler can be retrieved by calling
+ * CookieHandler.getDefault().
+ *
+ * For more information on HTTP state management, see <a
+ * href="http://www.ietf.org/rfc/rfc2965.txt""><i>RFC 2965: HTTP
+ * State Management Mechanism</i></a>
+ *
+ * @version 1.4, 03/08/09
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CookieHandler {
+ /**
+ * The system-wide cookie handler that will apply cookies to the
+ * request headers and manage cookies from the response headers.
+ *
+ * @see setDefault(CookieHandler)
+ * @see getDefault()
+ */
+ private static CookieHandler cookieHandler;
+
+ /**
+ * Gets the system-wide cookie handler.
+ *
+ * @return the system-wide cookie handler; A null return means
+ * there is no system-wide cookie handler currently set.
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link NetPermission}<tt>("getCookieHandler")</tt>
+ * @see #setDefault(CookieHandler)
+ */
+ public synchronized static CookieHandler getDefault() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
+ }
+ return cookieHandler;
+ }
+
+ /**
+ * Sets (or unsets) the system-wide cookie handler.
+ *
+ * Note: non-standard http protocol handlers may ignore this setting.
+ *
+ * @param cHandler The HTTP cookie handler, or
+ * <code>null</code> to unset.
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link NetPermission}<tt>("setCookieHandler")</tt>
+ * @see #getDefault()
+ */
+ public synchronized static void setDefault(CookieHandler cHandler) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
+ }
+ cookieHandler = cHandler;
+ }
+
+ /**
+ * Gets all the applicable cookies from a cookie cache for the
+ * specified uri in the request header.
+ *
+ * HTTP protocol implementers should make sure that this method is
+ * called after all request headers related to choosing cookies
+ * are added, and before the request is sent.
+ *
+ * @param uri a <code>URI</code> to send cookies to in a request
+ * @param requestHeaders - a Map from request header
+ * field names to lists of field values representing
+ * the current request headers
+ * @return an immutable map from state management headers, with
+ * field names "Cookie" or "Cookie2" to a list of
+ * cookies containing state information
+ *
+ * @throws IOException if an I/O error occurs
+ * @throws IllegalArgumentException if either argument is null
+ * @see #put(URI, Map)
+ */
+ public abstract Map<String, List<String>>
+ get(URI uri, Map<String, List<String>> requestHeaders)
+ throws IOException;
+
+ /**
+ * Sets all the applicable cookies, examples are response header
+ * fields that are named Set-Cookie2, present in the response
+ * headers into a cookie cache.
+ *
+ * @param uri a <code>URI</code> where the cookies come from
+ * @param responseHeaders an immutable map from field names to
+ * lists of field values representing the response
+ * header fields returned
+ * @throws IOException if an I/O error occurs
+ * @throws IllegalArgumentException if either argument is null
+ * @see #get(URI, Map)
+ */
+ public abstract void
+ put(URI uri, Map<String, List<String>> responseHeaders)
+ throws IOException;
+}
Added: trunk/core/src/openjdk/java/java/net/CookieManager.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CookieManager.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CookieManager.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Collections;
+import java.util.Comparator;
+import java.io.IOException;
+
+/**
+ * CookieManager provides a concrete implementation of {@link CookieHandler},
+ * which separates the storage of cookies from the policy surrounding accepting
+ * and rejecting cookies. A CookieManager is initialized with a {@link CookieStore}
+ * which manages storage, and a {@link CookiePolicy} object, which makes
+ * policy decisions on cookie acceptance/rejection.
+ *
+ * <p> The HTTP cookie management in java.net package looks like:
+ * <blockquote>
+ * <pre>
+ * use
+ * CookieHandler <------- HttpURLConnection
+ * ^
+ * | impl
+ * | use
+ * CookieManager -------> CookiePolicy
+ * | use
+ * |--------> HttpCookie
+ * | ^
+ * | | use
+ * | use |
+ * |--------> CookieStore
+ * ^
+ * | impl
+ * |
+ * Internal in-memory implementation
+ * </pre>
+ * <ul>
+ * <li>
+ * CookieHandler is at the core of cookie management. User can call
+ * CookieHandler.setDefault to set a concrete CookieHanlder implementation
+ * to be used.
+ * </li>
+ * <li>
+ * CookiePolicy.shouldAccept will be called by CookieManager.put to see whether
+ * or not one cookie should be accepted and put into cookie store. User can use
+ * any of three pre-defined CookiePolicy, namely ACCEPT_ALL, ACCEPT_NONE and
+ * ACCEPT_ORIGINAL_SERVER, or user can define his own CookiePolicy implementation
+ * and tell CookieManager to use it.
+ * </li>
+ * <li>
+ * CookieStore is the place where any accepted HTTP cookie is stored in.
+ * If not specified when created, a CookieManager instance will use an internal
+ * in-memory implementation. Or user can implements one and tell CookieManager
+ * to use it.
+ * </li>
+ * <li>
+ * Currently, only CookieStore.add(URI, HttpCookie) and CookieStore.get(URI)
+ * are used by CookieManager. Others are for completeness and might be needed
+ * by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieSotre.
+ * </li>
+ * </ul>
+ * </blockquote>
+ *
+ * <p>There're various ways user can hook up his own HTTP cookie management behavior, e.g.
+ * <blockquote>
+ * <ul>
+ * <li>Use CookieHandler.setDefault to set a brand new {@link CookieHandler} implementation
+ * <li>Let CookieManager be the default {@link CookieHandler} implementation,
+ * but implement user's own {@link CookieStore} and {@link CookiePolicy}
+ * and tell default CookieManager to use them:
+ * <blockquote><pre>
+ * // this should be done at the beginning of an HTTP session
+ * CookieHandler.setDefault(new CookieManager(new MyCookieStore(), new MyCookiePolicy()));
+ * </pre></blockquote>
+ * <li>Let CookieManager be the default {@link CookieHandler} implementation, but
+ * use customized {@link CookiePolicy}:
+ * <blockquote><pre>
+ * // this should be done at the beginning of an HTTP session
+ * CookieHandler.setDefault(new CookieManager());
+ * // this can be done at any point of an HTTP session
+ * ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(new MyCookiePolicy());
+ * </pre></blockquote>
+ * </ul>
+ * </blockquote>
+ *
+ * <p>The implementation conforms to RFC 2965, section 3.3.
+ *
+ * @version %I%, %E%
+ * @author Edward Wang
+ * @since 1.6
+ */
+public class CookieManager extends CookieHandler
+{
+ /* ---------------- Fields -------------- */
+
+ private CookiePolicy policyCallback;
+
+
+ private CookieStore cookieJar = null;
+
+
+ /* ---------------- Ctors -------------- */
+
+ /**
+ * Create a new cookie manager.
+ *
+ * <p>This constructor will create new cookie manager with default
+ * cookie store and accept policy. The effect is same as
+ * <tt>CookieManager(null, null)</tt>.
+ */
+ public CookieManager() {
+ this(null, null);
+ }
+
+
+ /**
+ * Create a new cookie manager with specified cookie store and cookie policy.
+ *
+ * @param store a <tt>CookieStore</tt> to be used by cookie manager.
+ * if <tt>null</tt>, cookie manager will use a default one,
+ * which is an in-memory CookieStore implmentation.
+ * @param cookiePolicy a <tt>CookiePolicy</tt> instance
+ * to be used by cookie manager as policy callback.
+ * if <tt>null</tt>, ACCEPT_ORIGINAL_SERVER will
+ * be used.
+ */
+ public CookieManager(CookieStore store,
+ CookiePolicy cookiePolicy)
+ {
+ // use default cookie policy if not specify one
+ policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER
+ : cookiePolicy;
+
+ // if not specify CookieStore to use, use default one
+ if (store == null) {
+ cookieJar = new sun.net.www.protocol.http.InMemoryCookieStore();
+ } else {
+ cookieJar = store;
+ }
+ }
+
+
+ /* ---------------- Public operations -------------- */
+
+ /**
+ * To set the cookie policy of this cookie manager.
+ *
+ * <p> A instance of <tt>CookieManager</tt> will have
+ * cookie policy ACCEPT_ORIGINAL_SERVER by default. Users always
+ * can call this method to set another cookie policy.
+ *
+ * @param cookiePolicy the cookie policy. Can be <tt>null</tt>, which
+ * has no effects on current cookie policy.
+ */
+ public void setCookiePolicy(CookiePolicy cookiePolicy) {
+ if (cookiePolicy != null) policyCallback = cookiePolicy;
+ }
+
+
+ /**
+ * To retrieve current cookie store.
+ *
+ * @return the cookie store currently used by cookie manager.
+ */
+ public CookieStore getCookieStore() {
+ return cookieJar;
+ }
+
+
+ public Map<String, List<String>>
+ get(URI uri, Map<String, List<String>> requestHeaders)
+ throws IOException
+ {
+ // pre-condition check
+ if (uri == null || requestHeaders == null) {
+ throw new IllegalArgumentException("Argument is null");
+ }
+
+ Map<String, List<String>> cookieMap =
+ new java.util.HashMap<String, List<String>>();
+ // if there's no default CookieStore, no way for us to get any cookie
+ if (cookieJar == null)
+ return Collections.unmodifiableMap(cookieMap);
+
+ List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
+ for (HttpCookie cookie : cookieJar.get(uri)) {
+ // apply path-matches rule (RFC 2965 sec. 3.3.4)
+ if (pathMatches(uri.getPath(), cookie.getPath())) {
+ cookies.add(cookie);
+ }
+ }
+
+ // apply sort rule (RFC 2965 sec. 3.3.4)
+ List<String> cookieHeader = sortByPath(cookies);
+
+ cookieMap.put("Cookie", cookieHeader);
+ return Collections.unmodifiableMap(cookieMap);
+ }
+
+
+ public void
+ put(URI uri, Map<String, List<String>> responseHeaders)
+ throws IOException
+ {
+ // pre-condition check
+ if (uri == null || responseHeaders == null) {
+ throw new IllegalArgumentException("Argument is null");
+ }
+
+
+ // if there's no default CookieStore, no need to remember any cookie
+ if (cookieJar == null)
+ return;
+
+ for (String headerKey : responseHeaders.keySet()) {
+ // RFC 2965 3.2.2, key must be 'Set-Cookie2'
+ // we also accept 'Set-Cookie' here for backward compatibility
+ if (headerKey == null
+ || !(headerKey.equalsIgnoreCase("Set-Cookie2")
+ || headerKey.equalsIgnoreCase("Set-Cookie")
+ )
+ )
+ {
+ continue;
+ }
+
+ for (String headerValue : responseHeaders.get(headerKey)) {
+ try {
+ List<HttpCookie> cookies = HttpCookie.parse(headerValue);
+ for (HttpCookie cookie : cookies) {
+ if (shouldAcceptInternal(uri, cookie)) {
+ cookieJar.add(uri, cookie);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ // invalid set-cookie header string
+ // no-op
+ }
+ }
+ }
+ }
+
+
+ /* ---------------- Private operations -------------- */
+
+ // to determine whether or not accept this cookie
+ private boolean shouldAcceptInternal(URI uri, HttpCookie cookie) {
+ try {
+ return policyCallback.shouldAccept(uri, cookie);
+ } catch (Exception ignored) { // pretect against malicious callback
+ return false;
+ }
+ }
+
+
+ /*
+ * path-matches algorithm, as defined by RFC 2965
+ */
+ private boolean pathMatches(String path, String pathToMatchWith) {
+ if (path == pathToMatchWith)
+ return true;
+ if (path == null || pathToMatchWith == null)
+ return false;
+ if (path.startsWith(pathToMatchWith))
+ return true;
+
+ return false;
+ }
+
+
+ /*
+ * sort cookies with respect to their path: those with more specific Path attributes
+ * precede those with less specific, as defined in RFC 2965 sec. 3.3.4
+ */
+ private List<String> sortByPath(List<HttpCookie> cookies) {
+ Collections.sort(cookies, new CookiePathComparator());
+
+ List<String> cookieHeader = new java.util.ArrayList<String>();
+ for (HttpCookie cookie : cookies) {
+ // Netscape cookie spec and RFC 2965 have different format of Cookie
+ // header; RFC 2965 requires a leading $Version="1" string while Netscape
+ // does not.
+ // The workaround here is to add a $Version="1" string in advance
+ if (cookies.indexOf(cookie) == 0 && cookie.getVersion() > 0) {
+ cookieHeader.add("$Version=\"1\"");
+ }
+
+ cookieHeader.add(cookie.toString());
+ }
+ return cookieHeader;
+ }
+
+
+ static class CookiePathComparator implements Comparator<HttpCookie> {
+ public int compare(HttpCookie c1, HttpCookie c2) {
+ if (c1 == c2) return 0;
+ if (c1 == null) return -1;
+ if (c2 == null) return 1;
+
+ // path rule only applies to the cookies with same name
+ if (!c1.getName().equals(c2.getName())) return 0;
+
+ // those with more specific Path attributes precede those with less specific
+ if (c1.getPath().startsWith(c2.getPath()))
+ return -1;
+ else if (c2.getPath().startsWith(c1.getPath()))
+ return 1;
+ else
+ return 0;
+ }
+ }
+}
Added: trunk/core/src/openjdk/java/java/net/CookiePolicy.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CookiePolicy.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CookiePolicy.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+/**
+ * CookiePolicy implementations decide which cookies should be accepted
+ * and which should be rejected. Three pre-defined policy implementations
+ * are provided, namely ACCEPT_ALL, ACCEPT_NONE and ACCEPT_ORIGINAL_SERVER.
+ *
+ * <p>See RFC 2965 sec. 3.3 & 7 for more detail.
+ *
+ * @version %I%, %E%
+ * @author Edward Wang
+ * @since 1.6
+ */
+public interface CookiePolicy {
+ /**
+ * One pre-defined policy which accepts all cookies.
+ */
+ public static final CookiePolicy ACCEPT_ALL = new CookiePolicy(){
+ public boolean shouldAccept(URI uri, HttpCookie cookie) {
+ return true;
+ }
+ };
+
+ /**
+ * One pre-defined policy which accepts no cookies.
+ */
+ public static final CookiePolicy ACCEPT_NONE = new CookiePolicy(){
+ public boolean shouldAccept(URI uri, HttpCookie cookie) {
+ return false;
+ }
+ };
+
+ /**
+ * One pre-defined policy which only accepts cookies from original server.
+ */
+ public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){
+ public boolean shouldAccept(URI uri, HttpCookie cookie) {
+ return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost());
+ }
+ };
+
+
+ /**
+ * Will be called to see whether or not this cookie should be accepted.
+ *
+ * @param uri the URI to consult accept policy with
+ * @param cookie the HttpCookie object in question
+ * @return <tt>true</tt> if this cookie should be accepted;
+ * otherwise, <tt>false</tt>
+ */
+ public boolean shouldAccept(URI uri, HttpCookie cookie);
+}
+
Added: trunk/core/src/openjdk/java/java/net/CookieStore.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/CookieStore.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/CookieStore.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A CookieStore object represents a storage for cookie. Can store and retrieve
+ * cookies.
+ *
+ * <p>{@link CookieManager} will call <tt>CookieStore.add</tt> to save cookies
+ * for every incoming HTTP response, and call <tt>CookieStore.get</tt> to
+ * retrieve cookie for every outgoing HTTP request. A CookieStore
+ * is responsible for removing HttpCookie instances which have expired.
+ *
+ * @version 1.9, 07/05/05
+ * @author Edward Wang
+ * @since 1.6
+ */
+public interface CookieStore {
+ /**
+ * Adds one HTTP cookie to the store. This is called for every
+ * incoming HTTP response.
+ *
+ * <p>A cookie to store may or may not be associated with an URI. If it
+ * is not associated with an URI, the cookie's domain and path attribute
+ * will indicate where it comes from. If it is associated with an URI and
+ * its domain and path attribute are not speicifed, given URI will indicate
+ * where this cookie comes from.
+ *
+ * <p>If a cookie corresponding to the given URI already exists,
+ * then it is replaced with the new one.
+ *
+ * @param uri the uri this cookie associated with.
+ * if <tt>null</tt>, this cookie will not be associated
+ * with an URI
+ * @param cookie the cookie to store
+ *
+ * @throws NullPointerException if <tt>cookie</tt> is <tt>null</tt>
+ *
+ * @see #get
+ *
+ */
+ public void add(URI uri, HttpCookie cookie);
+
+
+ /**
+ * Retrieve cookies associated with given URI, or whose domain matches the
+ * given URI. Only cookies that have not expired are returned.
+ * This is called for every outgoing HTTP request.
+ *
+ * @return an immutable list of HttpCookie,
+ * return empty list if no cookies match the given URI
+ *
+ * @throws NullPointerException if <tt>uri</tt> is <tt>null</tt>
+ *
+ * @see #add
+ *
+ */
+ public List<HttpCookie> get(URI uri);
+
+
+ /**
+ * Get all not-expired cookies in cookie store.
+ *
+ * @return an immutable list of http cookies;
+ * return empty list if there's no http cookie in store
+ */
+ public List<HttpCookie> getCookies();
+
+
+ /**
+ * Get all URIs which identify the cookies in this cookie store.
+ *
+ * @return an immutable list of URIs;
+ * return empty list if no cookie in this cookie store
+ * is associated with an URI
+ */
+ public List<URI> getURIs();
+
+
+ /**
+ * Remove a cookie from store.
+ *
+ * @param uri the uri this cookie associated with.
+ * if <tt>null</tt>, the cookie to be removed is not associated
+ * with an URI when added; if not <tt>null</tt>, the cookie
+ * to be removed is associated with the given URI when added.
+ * @param cookie the cookie to remove
+ *
+ * @return <tt>true</tt> if this store contained the specified cookie
+ *
+ * @throws NullPointerException if <tt>cookie</tt> is <tt>null</tt>
+ */
+ public boolean remove(URI uri, HttpCookie cookie);
+
+
+ /**
+ * Remove all cookies in this cookie store.
+ *
+ * @return <tt>true</tt> if this store changed as a result of the call
+ */
+ public boolean removeAll();
+}
+
Added: trunk/core/src/openjdk/java/java/net/HttpCookie.java
===================================================================
--- trunk/core/src/openjdk/java/java/net/HttpCookie.java (rev 0)
+++ trunk/core/src/openjdk/java/java/net/HttpCookie.java 2007-06-25 09:32:16 UTC (rev 3306)
@@ -0,0 +1,1166 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package java.net;
+
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.NoSuchElementException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
+import java.util.Date;
+
+import java.lang.NullPointerException; // for javadoc
+
+/**
+ * An HttpCookie object represents an http cookie, which carries state
+ * information between server and user agent. Cookie is widely adopted
+ * to create stateful sessions.
+ *
+ * <p>There are 3 http cookie specifications:
+ * <blockquote>
+ * Netscape draft<br>
+ * RFC 2109 - <a href="http://www.ietf.org/rfc/rfc2109.txt">
+ * <i>http://www.ietf.org/rfc/rfc2109.txt</i></a><br>
+ * RFC 2965 - <a href="http://www.ietf.org/rfc/rfc2965.txt">
+ * <i>http://www.ietf.org/rfc/rfc2965.txt</i></a>
+ * </blockquote>
+ *
+ * <p>HttpCookie class can accept all these 3 forms of syntax.
+ *
+ * @version 1.11, 07/05/05
+ * @author Edward Wang
+ * @since 1.6
+ */
+public final class HttpCookie implements Cloneable {
+ /* ---------------- Fields -------------- */
+
+ //
+ // The value of the cookie itself.
+ //
+
+ private String name; // NAME= ... "$Name" style is reserved
+ private String value; // value of NAME
+
+ //
+ // Attributes encoded in the header's cookie fields.
+ //
+
+ private String comment; // Comment=VALUE ... describes cookie's use
+ private String commentURL; // CommentURL="http URL" ... describes cookie's use
+ private boolean toDiscard; // Discard ... discard cookie unconditionally
+ private String domain; // Domain=VALUE ... domain that sees cookie
+ private long maxAge = MAX_AGE_UNSPECIFIED; // Max-Age=VALUE ... cookies auto-expire
+ private String path; // Path=VALUE ... URLs that see the cookie
+ private String portlist; // Port[="portlist"] ... the port cookie may be returned to
+ private boolean secure; // Secure ... e.g. use SSL
+ private int version = 1; // Version=1 ... RFC 2965 style
+
+ //
+ // Hold the creation time (in seconds) of the http cookie for later
+ // expiration calculation
+ //
+ private long whenCreated = 0;
+
+
+ //
+ // Since the positive and zero max-age have their meanings,
+ // this value serves as a hint as 'not specify max-age'
+ //
+ private final static long MAX_AGE_UNSPECIFIED = -1;
+
+
+ //
+ // date format used by Netscape's cookie draft
+ //
+ private final static String NETSCAPE_COOKIE_DATE_FORMAT = "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'";
+
+ //
+ // constant strings represent set-cookie header token
+ //
+ private final static String SET_COOKIE = "set-cookie:";
+ private final static String SET_COOKIE2 = "set-cookie2:";
+
+
+ /* ---------------- Ctors -------------- */
+
+ /**
+ * Constructs a cookie with a specified name and value.
+ *
+ * <p>The name must conform to RFC 2965. That means it can contain
+ * only ASCII alphanumeric characters and cannot contain commas,
+ * semicolons, or white space or begin with a $ character. The cookie's
+ * name cannot be changed after creation.
+ *
+ * <p>The value can be anything the server chooses to send. Its
+ * value is probably of interest only to the server. The cookie's
+ * value can be changed after creation with the
+ * <code>setValue</code> method.
+ *
+ * <p>By default, cookies are created according to the RFC 2965
+ * cookie specification. The version can be changed with the
+ * <code>setVersion</code> method.
+ *
+ *
+ * @param name a <code>String</code> specifying the name of the cookie
+ *
+ * @param value a <code>String</code> specifying the value of the cookie
+ *
+ * @throws IllegalArgumentException if the cookie name contains illegal characters
+ * or it is one of the tokens reserved for use
+ * by the cookie protocol
+ * @throws NullPointerException if <tt>name</tt> is <tt>null</tt>
+ * @see #setValue
+ * @see #setVersion
+ *
+ */
+
+ public HttpCookie(String name, String value) {
+ name = name.trim();
+ if (name.length() == 0 || !isToken(name) || isReserved(name)) {
+ throw new IllegalArgumentException("Illegal cookie name");
+ }
+
+ this.name = name;
+ this.value = value;
+ toDiscard = false;
+ secure = false;
+
+ whenCreated = System.currentTimeMillis();
+ }
+
+
+ /**
+ * Constructs cookies from set-cookie or set-cookie2 header string.
+ * RFC 2965 section 3.2.2 set-cookie2 syntax indicates that one header line
+ * may contain more than one cookie definitions, so this is a static
+ * utility method instead of another constructor.
+ *
+ * @param header a <tt>String</tt> specifying the set-cookie header.
+ * The header should start with "set-cookie", or "set-cookie2"
+ * token; or it should have no leading token at all.
+ * @return a List of cookie parsed from header line string
+ * @throws IllegalArgumentException if header string violates the cookie
+ * specification's syntax, or the cookie
+ * name contains llegal characters, or
+ * the cookie name is one of the tokens
+ * reserved for use by the cookie protocol
+ * @throws NullPointerException if the header string is <tt>null</tt>
+ */
+ public static List<HttpCookie> parse(String header) {
+ int version = guessCookieVersion(header);
+
+ // if header start with set-cookie or set-cookie2, strip it off
+ if (startsWithIgnoreCase(header, SET_COOKIE2)) {
+ header = header.substring(SET_COOKIE2.length());
+ } else if (startsWithIgnoreCase(header, SET_COOKIE)) {
+ header = header.substring(SET_COOKIE.length());
+ }
+
+
+ List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
+ // The Netscape cookie may have a comma in its expires attribute,
+ // while the comma is the delimiter in rfc 2965/2109 cookie header string.
+ // so the parse logic is slightly different
+ if (version == 0) {
+ // Netscape draft cookie
+ HttpCookie cookie = parseInternal(header);
+ cookie.setVersion(0);
+ cookies.add(cookie);
+ } else {
+ // rfc2965/2109 cookie
+ // if header string contains more than one cookie,
+ // it'll separate them with comma
+ List<String> cookieStrings = splitMultiCookies(header);
+ for (String cookieStr : cookieStrings) {
+ HttpCookie cookie = parseInternal(cookieStr);
+ cookie.setVersion(1);
+ cookies.add(cookie);
+ }
+ }
+
+ return cookies;
+ }
+
+
+
+
+ /* ---------------- Public operations -------------- */
+
+
+ /**
+ * Reports whether this http cookie has expired or not.
+ *
+ * @return <tt>true</tt> to indicate this http cookie has expired;
+ * otherwise, <tt>false</tt>
+ */
+ public boolean hasExpired() {
+ if (maxAge == 0) return true;
+
+ // if not specify max-age, this cookie should be
+ // discarded when user agent is to be closed, but
+ // it is not expired.
+ if (maxAge == MAX_AGE_UNSPECIFIED) return false;
+
+ long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
+ if (deltaSecond > maxAge)
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ *
+ * Specifies a comment that describes a cookie's purpose.
+ * The comment is useful if the browser presents the cookie
+ * to the user. Comments
+ * are not supported by Netscape Version 0 cookies.
+ *
+ * @param purpose a <code>String</code> specifying the comment
+ * to display to the user
+ *
+ * @see #getComment
+ *
+ */
+
+ public void setComment(String purpose) {
+ comment = purpose;
+ }
+
+
+
+
+ /**
+ * Returns the comment describing the purpose of this cookie, or
+ * <code>null</code> if the cookie has no comment.
+ *
+ * @return a <code>String</code> containing the comment,
+ * or <code>null</code> if none
+ *
+ * @see #setComment
+ *
+ */
+
+ public String getComment() {
+ return comment;
+ }
+
+
+ /**
+ *
+ * Specifies a comment url that describes a cookie's purpose.
+ * The comment url is useful if the browser presents the cookie
+ * to the user. Comment url is RFC 2965 only.
+ *
+ * @param purpose a <code>String</code> specifying the comment url
+ * to display to the user
+ *
+ * @see #getCommentURL
+ *
+ */
+
+ public void setCommentURL(String purpose) {
+ commentURL = purpose;
+ }
+
+
+
+
+ /**
+ * Returns the comment url describing the purpose of this cookie, or
+ * <code>null</code> if the cookie has no comment url.
+ *
+ * @return a <code>String</code> containing the comment url,
+ * or <code>null</code> if none
+ *
+ * @see #setCommentURL
+ *
+ */
+
+ public String getCommentURL() {
+ return commentURL;
+ }
+
+
+ /**
+ * Specify whether user agent should discard the cookie unconditionally.
+ * This is RFC 2965 only attribute.
+ *
+ * @param discard <tt>true</tt> indicates to discard cookie unconditionally
+ *
+ * @see #getDiscard
+ */
+
+ public void setDiscard(boolean discard) {
+ toDiscard = discard;
+ }
+
+
+
+
+ /**
+ * Return the discard attribute of the cookie
+ *
+ * @return a <tt>boolean</tt> to represent this cookie's discard attribute
+ *
+ * @see #setDiscard
+ */
+
+ public boolean getDiscard() {
+ return toDiscard;
+ }
+
+
+ /**
+ * Specify the portlist of the cookie, which restricts the port(s)
+ * to which a cookie may be sent back in a Cookie header.
+ *
+ * @param ports a <tt>String</tt> specify the port list, which is
+ * comma seperated series of digits
+ * @see #getPortlist
+ */
+
+ public void setPortlist(String ports) {
+ portlist = ports;
+ }
+
+
+
+
+ /**
+ * Return the port list attribute of the cookie
+ *
+ * @return a <tt>String</tt> contains the port list
+ * or <tt>null</tt> if none
+ * @see #setPortlist
+ */
+
+ public String getPortlist() {
+ return portlist;
+ }
+
+ /**
+ *
+ * Specifies the domain within which this cookie should be presented.
+ *
+ * <p>The form of the domain name is specified by RFC 2965. A domain
+ * name begins with a dot (<code>.foo.com</code>) and means that
+ * the cookie is visible to servers in a specified Domain Name System
+ * (DNS) zone (for example, <code>www.foo.com</code>, but not
+ * <code>a.b.foo.com</code>). By default, cookies are only returned
+ * to the server that sent them.
+ *
+ *
+ * @param pattern a <code>String</code> containing the domain name
+ * within which this cookie is visible;
+ * form is according to RFC 2965
+ *
+ * @see #getDomain
+ *
+ */
+
+ public void setDomain(String pattern) {
+ if (pattern != null)
+ domain = pattern.toLowerCase();
+ else
+ domain = pattern;
+ }
+
+
+
+
+
+ /**
+ * Returns the domain name set for this cookie. The form of
+ * the domain name is set by RFC 2965.
+ *
+ * @return a <code>String</code> containing the domain name
+ *
+ * @see #setDomain
+ *
+ */
+
+ public String getDomain() {
+ return domain;
+ }
+
+
+ /**
+ * Sets the maximum age of the cookie in seconds.
+ *
+ * <p>A positive value indicates that the cookie will expire
+ * after that many seconds have passed. Note that the value is
+ * the <i>maximum</i> age when the cookie will expire, not the cookie's
+ * current age.
+ *
+ * <p>A negative value means
+ * that the cookie is not stored persistently and will be deleted
+ * when the Web browser exits. A zero value causes the cookie
+ * to be deleted.
+ *
+ * @param expiry an integer specifying the maximum age of the
+ * cookie in seconds; if zero, the cookie
+ * should be discarded immediately;
+ * otherwise, the cookie's max age is unspecified.
+ *
+ * @see #getMaxAge
+ *
+ */
+ public void setMaxAge(long expiry) {
+ maxAge = expiry;
+ }
+
+
+
+
+ /**
+ * Returns the maximum age of the cookie, specified in seconds.
+ * By default, <code>-1</code> indicating the cookie will persist
+ * until browser shutdown.
+ *
+ *
+ * @return an integer specifying the maximum age of the
+ * cookie in seconds
+ *
+ *
+ * @see #setMaxAge
+ *
+ */
+
+ public long getMaxAge() {
+ return maxAge;
+ }
+
+
+
+
+ /**
+ * Specifies a path for the cookie
+ * to which the client should return the cookie.
+ *
+ * <p>The cookie is visible to all the pages in the directory
+ * you specify, and all the pages in that directory's subdirectories.
+ * A cookie's path must include the servlet that set the cookie,
+ * for example, <i>/catalog</i>, which makes the cookie
+ * visible to all directories on the server under <i>/catalog</i>.
+ *
+ * <p>Consult RFC 2965 (available on the Internet) for more
+ * information on setting path names for cookies.
+ *
+ *
+ * @param uri a <code>String</code> specifying a path
+ *
+ *
+ * @see #getPath
+ *
+ */
+
+ public void setPath(String uri) {
+ path = uri;
+ }
+
+
+
+
+ /**
+ * Returns the path on the server
+ * to which the browser returns this cookie. The
+ * cookie is visible to all subpaths on the server.
+ *
+ *
+ * @return a <code>String</code> specifying a path that contains
+ * a servlet name, for example, <i>/catalog</i>
+ *
+ * @see #setPath
+ *
+ */
+
+ public String getPath() {
+ return path;
+ }
+
+
+
+
+
+ /**
+ * Indicates to the browser whether the cookie should only be sent
+ * using a secure protocol, such as HTTPS or SSL.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @param flag if <code>true</code>, sends the cookie from the browser
+ * to the server using only when using a secure protocol;
+ * if <code>false</code>, sent on any protocol
+ *
+ * @see #getSecure
+ *
+ */
+
+ public void setSecure(boolean flag) {
+ secure = flag;
+ }
+
+
+
+
+ /**
+ * Returns <code>true</code> if the browser is sending cookies
+ * only over a secure protocol, or <code>false</code> if the
+ * browser can send cookies using any protocol.
+ *
+ * @return <code>true</code> if the browser can use
+ * any standard protocol; otherwise, <code>false</code>
+ *
+ * @see #setSecure
+ *
+ */
+
+ public boolean getSecure() {
+ return secure;
+ }
+
+
+
+
+
+ /**
+ * Returns the name of the cookie. The name cannot be changed after
+ * creation.
+ *
+ * @return a <code>String</code> specifying the cookie's name
+ *
+ */
+
+ public String getName() {
+ return name;
+ }
+
+
+
+
+
+ /**
+ *
+ * Assigns a new value to a cookie after the cookie is created.
+ * If you use a binary value, you may want to use BASE64 encoding.
+ *
+ * <p>With Version 0 cookies, values should not contain white
+ * space, brackets, parentheses, equals signs, commas,
+ * double quotes, slashes, question marks, at signs, colons,
+ * and semicolons. Empty values may not behave the same way
+ * on all browsers.
+ *
+ * @param newValue a <code>String</code> specifying the new value
+ *
+ *
+ * @see #getValue
+ *
+ */
+
+ public void setValue(String newValue) {
+ value = newValue;
+ }
+
+
+
+
+ /**
+ * Returns the value of the cookie.
+ *
+ * @return a <code>String</code> containing the cookie's
+ * present value
+ *
+ * @see #setValue
+ *
+ */
+
+ public String getValue() {
+ return value;
+ }
+
+
+
+
+ /**
+ * Returns the version of the protocol this cookie complies
+ * with. Version 1 complies with RFC 2965/2109,
+ * and version 0 complies with the original
+ * cookie specification drafted by Netscape. Cookies provided
+ * by a browser use and identify the browser's cookie version.
+ *
+ *
+ * @return 0 if the cookie complies with the
+ * original Netscape specification; 1
+ * if the cookie complies with RFC 2965/2109
+ *
+ * @see #setVersion
+ *
+ */
+
+ public int getVersion() {
+ return version;
+ }
+
+
+
+
+ /**
+ * Sets the version of the cookie protocol this cookie complies
+ * with. Version 0 complies with the original Netscape cookie
+ * specification. Version 1 complies with RFC 2965/2109.
+ *
+ *
+ * @param v 0 if the cookie should comply with
+ * the original Netscape specification;
+ * 1 if the cookie should comply with RFC 2965/2109
+ *
+ * @throws IllegalArgumentException if <tt>v</tt> is neither 0 nor 1
+ *
+ * @see #getVersion
+ *
+ */
+
+ public void setVersion(int v) {
+ if (v != 0 && v != 1) {
+ throw new IllegalArgumentException("cookie version should be 0 or 1");
+ }
+
+ version = v;
+ }
+
+
+ /**
+ * The utility method to check whether a host name is in a domain
+ * or not.
+ *
+ * <p>This concept is described in the cookie specification.
+ * To understand the concept, some terminologies need to be defined first:
+ * <blockquote>
+ * effective host name = hostname if host name contains dot<br>
+ * or = hostname.local if not
+ * </blockquote>
+ * <p>Host A's name domain-matches host B's if:
+ * <blockquote><ul>
+ * <li>their host name strings string-compare equal; or</li>
+ * <li>A is a HDN string and has the form NB, where N is a non-empty
+ * name string, B has the form .B', and B' is a HDN string. (So,
+ * x.y.com domain-matches .Y.com but not Y.com.)</li>
+ * </ul></blockquote>
+ *
+ * <p>A host isn't in a domain (RFC 2965 sec. 3.3.2) if:
+ * <blockquote><ul>
+ * <li>The value for the Domain attribute contains no embedded dots,
+ * and the value is not .local.</li>
+ * <li>The effective host name that derives from the request-host does
+ * not domain-match the Domain attribute.</li>
+ * <li>The request-host is a HDN (not IP address) and has the form HD,
+ * where D is the value of the Domain attribute, and H is a string
+ * that contains one or more dots.</li>
+ * </ul></blockquote>
+ *
+ * <p>Examples:
+ * <blockquote><ul>
+ * <li>A Set-Cookie2 from request-host y.x.foo.com for Domain=.foo.com
+ * would be rejected, because H is y.x and contains a dot.</li>
+ * <li>A Set-Cookie2 from request-host x.foo.com for Domain=.foo.com
+ * would be accepted.</li>
+ * <li>A Set-Cookie2 with Domain=.com or Domain=.com., will always be
+ * rejected, because there is no embedded dot.</li>
+ * <li>A Set-Cookie2 with Domain=ajax.com will be accepted, and the
+ * value for Domain will be taken to be .ajax.com, because a dot
+ * gets prepended to the value.</li>
+ * <li>A Set-Cookie2 from request-host example for Domain=.local will
+ * be accepted, because the effective host name for the request-
+ * host is example.local, and example.local domain-matches .local.</li>
+ * </ul></blockquote>
+ *
+ * @param domain the domain name to check host name with
+ * @param host the host name in question
+ * @return <tt>true</tt> if they domain-matches; <tt>false</tt> if not
+ */
+ public static boolean domainMatches(String domain, String host) {
+ if (domain == null || host == null)
+ return false;
+
+ // if there's no embedded dot in domain and domain is not .local
+ boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
+ int embeddedDotInDomain = domain.indexOf('.');
+ if (embeddedDotInDomain == 0)
+ embeddedDotInDomain = domain.indexOf('.', 1);
+ if (!isLocalDomain
+ && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1))
+ return false;
+
+ // if the host name contains no dot and the domain name is .local
+ int firstDotInHost = host.indexOf('.');
+ if (firstDotInHost == -1 && isLocalDomain)
+ return true;
+
+ int domainLength = domain.length();
+ int lengthDiff = host.length() - domainLength;
+ if (lengthDiff == 0) {
+ // if the host name and the domain name are just string-compare euqal
+ return host.equalsIgnoreCase(domain);
+ }
+ else if (lengthDiff > 0) {
+ // need to check H & D component
+ String H = host.substring(0, lengthDiff);
+ String D = host.substring(lengthDiff);
+
+ return (H.indexOf('.') == -1 && D.equalsIgnoreCase(domain));
+ }
+ else if (lengthDiff == -1) {
+ // if domain is actually .host
+ return (domain.charAt(0) == '.' &&
+ host.equalsIgnoreCase(domain.substring(1)));
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Constructs a cookie header string representation of this cookie,
+ * which is in the format defined by corresponding cookie specification,
+ * but without the leading "Cookie:" token.
+ *
+ * @return a string form of the cookie. The string has the defined format
+ */
+ public String toString() {
+ if (getVersion() > 0) {
+ return toRFC2965HeaderString();
+ } else {
+ return toNetscapeHeaderString();
+ }
+ }
+
+
+ /**
+ * Test the equality of two http cookies.
+ *
+ * <p> The result is <tt>true</tt> only if two cookies
+ * come from same domain (case-insensitive),
+ * have same name (case-insensitive),
+ * and have same path (case-sensitive).
+ *
+ * @return <tt>true</tt> if 2 http cookies equal to each other;
+ * otherwise, <tt>false</tt>
+ */
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof HttpCookie))
+ return false;
+ HttpCookie other = (HttpCookie)obj;
+
+ // One http cookie equals to another cookie (RFC 2965 sec. 3.3.3) if:
+ // 1. they come from same domain (case-insensitive),
+ // 2. have same name (case-insensitive),
+ // 3. and have same path (case-sensitive).
+ return equalsIgnoreCase(getName(), other.getName()) &&
+ equalsIgnoreCase(getDomain(), other.getDomain()) &&
+ equals(getPath(), other.getPath());
+ }
+
+
+ /**
+ * Return hash code of this http cookie. The result is the sum of
+ * hash code value of three significant components of this cookie:
+ * name, domain, and path.
+ * That is, the hash code is the value of the expression:
+ * <blockquote>
+ * getName().toLowerCase().hashCode()<br>
+ * + getDomain().toLowerCase().hashCode()<br>
+ * + getPath().hashCode()
+ * </blockquote>
+ *
+ * @return this http cookie's hash code
+ */
+ public int hashCode() {
+ int h1 = name.toLowerCase().hashCode();
+ int h2 = (domain!=null) ? domain.toLowerCase().hashCode() : 0;
+ int h3 = (path!=null) ? path.hashCode() : 0;
+
+ return h1 + h2 + h3;
+ }
+
+ /**
+ * Create and return a copy of this object.
+ *
+ * @return a clone of this http cookie
+ */
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupp...
[truncated message content] |