You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ol...@apache.org on 2004/06/05 18:49:21 UTC
cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie TestCookieCompatibilitySpec.java TestCookieRFC2109Spec.java
olegk 2004/06/05 09:49:21
Modified: httpclient/src/java/org/apache/commons/httpclient
Cookie.java
httpclient/src/java/org/apache/commons/httpclient/cookie
RFC2109Spec.java
httpclient/src/test/org/apache/commons/httpclient/cookie
TestCookieCompatibilitySpec.java
TestCookieRFC2109Spec.java
Log:
PR #29377 (Cookies with names containing blanks or starting with $ should be rejected by RFC2109 spec only)
Contributed by Oleg Kalnichevski
Reviewed by Michael Becke
Revision Changes Path
1.44 +549 -555 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java
Index: Cookie.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- Cookie.java 18 Apr 2004 23:51:34 -0000 1.43
+++ Cookie.java 5 Jun 2004 16:49:20 -0000 1.44
@@ -1,555 +1,549 @@
-/*
- * $Header$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- *
- * Copyright 1999-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.commons.httpclient;
-
-import java.io.Serializable;
-import java.text.RuleBasedCollator;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Locale;
-
-import org.apache.commons.httpclient.cookie.CookiePolicy;
-import org.apache.commons.httpclient.cookie.CookieSpec;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * <p>
- * HTTP "magic-cookie" represents a piece of state information
- * that the HTTP agent and the target server can exchange to maintain
- * a session.
- * </p>
- *
- * @author B.C. Holmes
- * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
- * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
- * @author Rod Waldhoff
- * @author dIon Gillard
- * @author Sean C. Sullivan
- * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
- * @author Marc A. Saegesser
- * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
- * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
- *
- * @version $Revision$ $Date$
- */
-public class Cookie extends NameValuePair implements Serializable, Comparator {
-
- // ----------------------------------------------------------- Constructors
-
- /**
- * Default constructor. Creates a blank cookie
- */
-
- public Cookie() {
- this(null, "noname", null, null, null, false);
- }
-
- /**
- * Creates a cookie with the given name, value and domain attribute.
- *
- * @param name the cookie name
- * @param value the cookie value
- * @param domain the domain this cookie can be sent to
- */
- public Cookie(String domain, String name, String value) {
- this(domain, name, value, null, null, false);
- }
-
- /**
- * Creates a cookie with the given name, value, domain attribute,
- * path attribute, expiration attribute, and secure attribute
- *
- * @param name the cookie name
- * @param value the cookie value
- * @param domain the domain this cookie can be sent to
- * @param path the path prefix for which this cookie can be sent
- * @param expires the {@link Date} at which this cookie expires,
- * or <tt>null</tt> if the cookie expires at the end
- * of the session
- * @param secure if true this cookie can only be sent over secure
- * connections
- * @throws IllegalArgumentException If cookie name is null or blank,
- * cookie name contains a blank, or cookie name starts with character $
- *
- */
- public Cookie(String domain, String name, String value,
- String path, Date expires, boolean secure) {
-
- super(name, value);
- LOG.trace("enter Cookie(String, String, String, String, Date, boolean)");
- if (name == null) {
- throw new IllegalArgumentException("Cookie name may not be null");
- }
- if (name.equals("")) {
- throw new IllegalArgumentException("Cookie name may not be blank");
- }
- if (name.indexOf(' ') != -1) {
- throw new IllegalArgumentException("Cookie name may not contain blanks");
- }
- if (name.startsWith("$")) {
- throw new IllegalArgumentException("Cookie name may not start with $");
- }
- this.setPath(path);
- this.setDomain(domain);
- this.setExpiryDate(expires);
- this.setSecure(secure);
- }
-
- /**
- * Creates a cookie with the given name, value, domain attribute,
- * path attribute, maximum age attribute, and secure attribute
- *
- * @param name the cookie name
- * @param value the cookie value
- * @param domain the domain this cookie can be sent to
- * @param path the path prefix for which this cookie can be sent
- * @param maxAge the number of seconds for which this cookie is valid.
- * maxAge is expected to be a non-negative number.
- * <tt>-1</tt> signifies that the cookie should never expire.
- * @param secure if <tt>true</tt> this cookie can only be sent over secure
- * connections
- */
- public Cookie(String domain, String name, String value, String path,
- int maxAge, boolean secure) {
-
- this(domain, name, value, path, null, secure);
- if (maxAge < -1) {
- throw new IllegalArgumentException("Invalid max age: " + Integer.toString(maxAge));
- }
- if (maxAge >= 0) {
- setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L));
- }
- }
-
- /**
- * Returns the comment describing the purpose of this cookie, or
- * <tt>null</tt> if no such comment has been defined.
- *
- * @return comment
- *
- * @see #setComment(String)
- */
- public String getComment() {
- return cookieComment;
- }
-
- /**
- * If a user agent (web browser) presents this cookie to a user, the
- * cookie's purpose will be described using this comment.
- *
- * @param comment
- *
- * @see #getComment()
- */
- public void setComment(String comment) {
- cookieComment = comment;
- }
-
- /**
- * Returns the expiration {@link Date} of the cookie, or <tt>null</tt>
- * if none exists.
- * <p><strong>Note:</strong> the object returned by this method is
- * considered immutable. Changing it (e.g. using setTime()) could result
- * in undefined behaviour. Do so at your peril. </p>
- * @return Expiration {@link Date}, or <tt>null</tt>.
- *
- * @see #setExpiryDate(java.util.Date)
- *
- */
- public Date getExpiryDate() {
- return cookieExpiryDate;
- }
-
- /**
- * Sets expiration date.
- * <p><strong>Note:</strong> the object returned by this method is considered
- * immutable. Changing it (e.g. using setTime()) could result in undefined
- * behaviour. Do so at your peril.</p>
- *
- * @param expiryDate the {@link Date} after which this cookie is no longer valid.
- *
- * @see #getExpiryDate
- *
- */
- public void setExpiryDate (Date expiryDate) {
- cookieExpiryDate = expiryDate;
- }
-
-
- /**
- * Returns <tt>false</tt> if the cookie should be discarded at the end
- * of the "session"; <tt>true</tt> otherwise.
- *
- * @return <tt>false</tt> if the cookie should be discarded at the end
- * of the "session"; <tt>true</tt> otherwise
- */
- public boolean isPersistent() {
- return (null != cookieExpiryDate);
- }
-
-
- /**
- * Returns domain attribute of the cookie.
- *
- * @return the value of the domain attribute
- *
- * @see #setDomain(java.lang.String)
- */
- public String getDomain() {
- return cookieDomain;
- }
-
- /**
- * Sets the domain attribute.
- *
- * @param domain The value of the domain attribute
- *
- * @see #getDomain
- */
- public void setDomain(String domain) {
- if (domain != null) {
- int ndx = domain.indexOf(":");
- if (ndx != -1) {
- domain = domain.substring(0, ndx);
- }
- cookieDomain = domain.toLowerCase();
- }
- }
-
-
- /**
- * Returns the path attribute of the cookie
- *
- * @return The value of the path attribute.
- *
- * @see #setPath(java.lang.String)
- */
- public String getPath() {
- return cookiePath;
- }
-
- /**
- * Sets the path attribute.
- *
- * @param path The value of the path attribute
- *
- * @see #getPath
- *
- */
- public void setPath(String path) {
- cookiePath = path;
- }
-
- /**
- * @return <code>true</code> if this cookie should only be sent over secure connections.
- * @see #setSecure(boolean)
- */
- public boolean getSecure() {
- return isSecure;
- }
-
- /**
- * Sets the secure attribute of the cookie.
- * <p>
- * When <tt>true</tt> the cookie should only be sent
- * using a secure protocol (https). This should only be set when
- * the cookie's originating server used a secure protocol to set the
- * cookie's value.
- *
- * @param secure The value of the secure attribute
- *
- * @see #getSecure()
- */
- public void setSecure (boolean secure) {
- isSecure = secure;
- }
-
- /**
- * Returns the version of the cookie specification to which this
- * cookie conforms.
- *
- * @return the version of the cookie.
- *
- * @see #setVersion(int)
- *
- */
- public int getVersion() {
- return cookieVersion;
- }
-
- /**
- * Sets the version of the cookie specification to which this
- * cookie conforms.
- *
- * @param version the version of the cookie.
- *
- * @see #getVersion
- */
- public void setVersion(int version) {
- cookieVersion = version;
- }
-
- /**
- * Returns true if this cookie has expired.
- *
- * @return <tt>true</tt> if the cookie has expired.
- */
- public boolean isExpired() {
- return (cookieExpiryDate != null
- && cookieExpiryDate.getTime() <= System.currentTimeMillis());
- }
-
- /**
- * Returns true if this cookie has expired according to the time passed in.
- *
- * @param now The current time.
- *
- * @return <tt>true</tt> if the cookie expired.
- */
- public boolean isExpired(Date now) {
- return (cookieExpiryDate != null
- && cookieExpiryDate.getTime() <= now.getTime());
- }
-
-
- /**
- * Indicates whether the cookie had a path specified in a
- * path attribute of the <tt>Set-Cookie</tt> header. This value
- * is important for generating the <tt>Cookie</tt> header because
- * some cookie specifications require that the <tt>Cookie</tt> header
- * should only include a path attribute if the cookie's path
- * was specified in the <tt>Set-Cookie</tt> header.
- *
- * @param value <tt>true</tt> if the cookie's path was explicitly
- * set, <tt>false</tt> otherwise.
- *
- * @see #isPathAttributeSpecified
- */
- public void setPathAttributeSpecified(boolean value) {
- hasPathAttribute = value;
- }
-
- /**
- * Returns <tt>true</tt> if cookie's path was set via a path attribute
- * in the <tt>Set-Cookie</tt> header.
- *
- * @return value <tt>true</tt> if the cookie's path was explicitly
- * set, <tt>false</tt> otherwise.
- *
- * @see #setPathAttributeSpecified
- */
- public boolean isPathAttributeSpecified() {
- return hasPathAttribute;
- }
-
- /**
- * Indicates whether the cookie had a domain specified in a
- * domain attribute of the <tt>Set-Cookie</tt> header. This value
- * is important for generating the <tt>Cookie</tt> header because
- * some cookie specifications require that the <tt>Cookie</tt> header
- * should only include a domain attribute if the cookie's domain
- * was specified in the <tt>Set-Cookie</tt> header.
- *
- * @param value <tt>true</tt> if the cookie's domain was explicitly
- * set, <tt>false</tt> otherwise.
- *
- * @see #isDomainAttributeSpecified
- */
- public void setDomainAttributeSpecified(boolean value) {
- hasDomainAttribute = value;
- }
-
- /**
- * Returns <tt>true</tt> if cookie's domain was set via a domain
- * attribute in the <tt>Set-Cookie</tt> header.
- *
- * @return value <tt>true</tt> if the cookie's domain was explicitly
- * set, <tt>false</tt> otherwise.
- *
- * @see #setDomainAttributeSpecified
- */
- public boolean isDomainAttributeSpecified() {
- return hasDomainAttribute;
- }
-
- /**
- * Returns a hash code in keeping with the
- * {@link Object#hashCode} general hashCode contract.
- * @return A hash code
- */
- public int hashCode() {
- return super.hashCode()
- ^ (null == cookiePath ? 0 : cookiePath.hashCode())
- ^ (null == cookieDomain ? 0 : cookieDomain.hashCode());
- }
-
-
- /**
- * Two cookies are equal if the name, path and domain match.
- * @param obj The object to compare against.
- * @return true if the two objects are equal.
- */
- public boolean equals(Object obj) {
- LOG.trace("enter Cookie.equals(Object)");
-
- if ((obj != null) && (obj instanceof Cookie)) {
- Cookie that = (Cookie) obj;
- return
- (null == this.getName()
- ? null == that.getName()
- : this.getName().equals(that.getName()))
- && (null == this.getPath()
- ? null == that.getPath()
- : this.getPath().equals(that.getPath()))
- && (null == this.getDomain()
- ? null == that.getDomain()
- : this.getDomain().equals(that.getDomain()));
- } else {
- return false;
- }
- }
-
-
- /**
- * Return a textual representation of the cookie.
- *
- * @return string.
- */
- public String toExternalForm() {
- CookieSpec spec = null;
- if (getVersion() > 0) {
- spec = CookiePolicy.getDefaultSpec();
- } else {
- spec = CookiePolicy.getCookieSpec(CookiePolicy.NETSCAPE);
- }
- return spec.formatCookie(this);
- }
-
- /**
- * <p>Compares two cookies to determine order for cookie header.</p>
- * <p>Most specific should be first. </p>
- * <p>This method is implemented so a cookie can be used as a comparator for
- * a SortedSet of cookies. Specifically it's used above in the
- * createCookieHeader method.</p>
- * @param o1 The first object to be compared
- * @param o2 The second object to be compared
- * @return See {@link java.util.Comparator#compare(Object,Object)}
- */
- public int compare(Object o1, Object o2) {
- LOG.trace("enter Cookie.compare(Object, Object)");
-
- if (!(o1 instanceof Cookie)) {
- throw new ClassCastException(o1.getClass().getName());
- }
- if (!(o2 instanceof Cookie)) {
- throw new ClassCastException(o2.getClass().getName());
- }
- Cookie c1 = (Cookie) o1;
- Cookie c2 = (Cookie) o2;
- if (c1.getPath() == null && c2.getPath() == null) {
- return 0;
- } else if (c1.getPath() == null) {
- // null is assumed to be "/"
- if (c2.getPath().equals(CookieSpec.PATH_DELIM)) {
- return 0;
- } else {
- return -1;
- }
- } else if (c2.getPath() == null) {
- // null is assumed to be "/"
- if (c1.getPath().equals(CookieSpec.PATH_DELIM)) {
- return 0;
- } else {
- return 1;
- }
- } else {
- return STRING_COLLATOR.compare(c1.getPath(), c2.getPath());
- }
- }
-
- /**
- * Return a textual representation of the cookie.
- *
- * @return string.
- *
- * @see #toExternalForm
- */
- public String toString() {
- return toExternalForm();
- }
-
- // ----------------------------------------------------- Instance Variables
-
- /** Comment attribute. */
- private String cookieComment;
-
- /** Domain attribute. */
- private String cookieDomain;
-
- /** Expiration {@link Date}. */
- private Date cookieExpiryDate;
-
- /** Path attribute. */
- private String cookiePath;
-
- /** My secure flag. */
- private boolean isSecure;
-
- /**
- * Specifies if the set-cookie header included a Path attribute for this
- * cookie
- */
- private boolean hasPathAttribute = false;
-
- /**
- * Specifies if the set-cookie header included a Domain attribute for this
- * cookie
- */
- private boolean hasDomainAttribute = false;
-
- /** The version of the cookie specification I was created from. */
- private int cookieVersion = 0;
-
- // -------------------------------------------------------------- Constants
-
- /**
- * Collator for Cookie comparisons. Could be replaced with references to
- * specific Locales.
- */
- private static final RuleBasedCollator STRING_COLLATOR =
- (RuleBasedCollator) RuleBasedCollator.getInstance(
- new Locale("en", "US", ""));
-
- /** Log object for this class */
- private static final Log LOG = LogFactory.getLog(Cookie.class);
-
-}
-
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.httpclient;
+
+import java.io.Serializable;
+import java.text.RuleBasedCollator;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.cookie.CookieSpec;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>
+ * HTTP "magic-cookie" represents a piece of state information
+ * that the HTTP agent and the target server can exchange to maintain
+ * a session.
+ * </p>
+ *
+ * @author B.C. Holmes
+ * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
+ * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
+ * @author Rod Waldhoff
+ * @author dIon Gillard
+ * @author Sean C. Sullivan
+ * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
+ * @author Marc A. Saegesser
+ * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
+ * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
+ *
+ * @version $Revision$ $Date$
+ */
+public class Cookie extends NameValuePair implements Serializable, Comparator {
+
+ // ----------------------------------------------------------- Constructors
+
+ /**
+ * Default constructor. Creates a blank cookie
+ */
+
+ public Cookie() {
+ this(null, "noname", null, null, null, false);
+ }
+
+ /**
+ * Creates a cookie with the given name, value and domain attribute.
+ *
+ * @param name the cookie name
+ * @param value the cookie value
+ * @param domain the domain this cookie can be sent to
+ */
+ public Cookie(String domain, String name, String value) {
+ this(domain, name, value, null, null, false);
+ }
+
+ /**
+ * Creates a cookie with the given name, value, domain attribute,
+ * path attribute, expiration attribute, and secure attribute
+ *
+ * @param name the cookie name
+ * @param value the cookie value
+ * @param domain the domain this cookie can be sent to
+ * @param path the path prefix for which this cookie can be sent
+ * @param expires the {@link Date} at which this cookie expires,
+ * or <tt>null</tt> if the cookie expires at the end
+ * of the session
+ * @param secure if true this cookie can only be sent over secure
+ * connections
+ * @throws IllegalArgumentException If cookie name is null or blank,
+ * cookie name contains a blank, or cookie name starts with character $
+ *
+ */
+ public Cookie(String domain, String name, String value,
+ String path, Date expires, boolean secure) {
+
+ super(name, value);
+ LOG.trace("enter Cookie(String, String, String, String, Date, boolean)");
+ if (name == null) {
+ throw new IllegalArgumentException("Cookie name may not be null");
+ }
+ if (name.trim().equals("")) {
+ throw new IllegalArgumentException("Cookie name may not be blank");
+ }
+ this.setPath(path);
+ this.setDomain(domain);
+ this.setExpiryDate(expires);
+ this.setSecure(secure);
+ }
+
+ /**
+ * Creates a cookie with the given name, value, domain attribute,
+ * path attribute, maximum age attribute, and secure attribute
+ *
+ * @param name the cookie name
+ * @param value the cookie value
+ * @param domain the domain this cookie can be sent to
+ * @param path the path prefix for which this cookie can be sent
+ * @param maxAge the number of seconds for which this cookie is valid.
+ * maxAge is expected to be a non-negative number.
+ * <tt>-1</tt> signifies that the cookie should never expire.
+ * @param secure if <tt>true</tt> this cookie can only be sent over secure
+ * connections
+ */
+ public Cookie(String domain, String name, String value, String path,
+ int maxAge, boolean secure) {
+
+ this(domain, name, value, path, null, secure);
+ if (maxAge < -1) {
+ throw new IllegalArgumentException("Invalid max age: " + Integer.toString(maxAge));
+ }
+ if (maxAge >= 0) {
+ setExpiryDate(new Date(System.currentTimeMillis() + maxAge * 1000L));
+ }
+ }
+
+ /**
+ * Returns the comment describing the purpose of this cookie, or
+ * <tt>null</tt> if no such comment has been defined.
+ *
+ * @return comment
+ *
+ * @see #setComment(String)
+ */
+ public String getComment() {
+ return cookieComment;
+ }
+
+ /**
+ * If a user agent (web browser) presents this cookie to a user, the
+ * cookie's purpose will be described using this comment.
+ *
+ * @param comment
+ *
+ * @see #getComment()
+ */
+ public void setComment(String comment) {
+ cookieComment = comment;
+ }
+
+ /**
+ * Returns the expiration {@link Date} of the cookie, or <tt>null</tt>
+ * if none exists.
+ * <p><strong>Note:</strong> the object returned by this method is
+ * considered immutable. Changing it (e.g. using setTime()) could result
+ * in undefined behaviour. Do so at your peril. </p>
+ * @return Expiration {@link Date}, or <tt>null</tt>.
+ *
+ * @see #setExpiryDate(java.util.Date)
+ *
+ */
+ public Date getExpiryDate() {
+ return cookieExpiryDate;
+ }
+
+ /**
+ * Sets expiration date.
+ * <p><strong>Note:</strong> the object returned by this method is considered
+ * immutable. Changing it (e.g. using setTime()) could result in undefined
+ * behaviour. Do so at your peril.</p>
+ *
+ * @param expiryDate the {@link Date} after which this cookie is no longer valid.
+ *
+ * @see #getExpiryDate
+ *
+ */
+ public void setExpiryDate (Date expiryDate) {
+ cookieExpiryDate = expiryDate;
+ }
+
+
+ /**
+ * Returns <tt>false</tt> if the cookie should be discarded at the end
+ * of the "session"; <tt>true</tt> otherwise.
+ *
+ * @return <tt>false</tt> if the cookie should be discarded at the end
+ * of the "session"; <tt>true</tt> otherwise
+ */
+ public boolean isPersistent() {
+ return (null != cookieExpiryDate);
+ }
+
+
+ /**
+ * Returns domain attribute of the cookie.
+ *
+ * @return the value of the domain attribute
+ *
+ * @see #setDomain(java.lang.String)
+ */
+ public String getDomain() {
+ return cookieDomain;
+ }
+
+ /**
+ * Sets the domain attribute.
+ *
+ * @param domain The value of the domain attribute
+ *
+ * @see #getDomain
+ */
+ public void setDomain(String domain) {
+ if (domain != null) {
+ int ndx = domain.indexOf(":");
+ if (ndx != -1) {
+ domain = domain.substring(0, ndx);
+ }
+ cookieDomain = domain.toLowerCase();
+ }
+ }
+
+
+ /**
+ * Returns the path attribute of the cookie
+ *
+ * @return The value of the path attribute.
+ *
+ * @see #setPath(java.lang.String)
+ */
+ public String getPath() {
+ return cookiePath;
+ }
+
+ /**
+ * Sets the path attribute.
+ *
+ * @param path The value of the path attribute
+ *
+ * @see #getPath
+ *
+ */
+ public void setPath(String path) {
+ cookiePath = path;
+ }
+
+ /**
+ * @return <code>true</code> if this cookie should only be sent over secure connections.
+ * @see #setSecure(boolean)
+ */
+ public boolean getSecure() {
+ return isSecure;
+ }
+
+ /**
+ * Sets the secure attribute of the cookie.
+ * <p>
+ * When <tt>true</tt> the cookie should only be sent
+ * using a secure protocol (https). This should only be set when
+ * the cookie's originating server used a secure protocol to set the
+ * cookie's value.
+ *
+ * @param secure The value of the secure attribute
+ *
+ * @see #getSecure()
+ */
+ public void setSecure (boolean secure) {
+ isSecure = secure;
+ }
+
+ /**
+ * Returns the version of the cookie specification to which this
+ * cookie conforms.
+ *
+ * @return the version of the cookie.
+ *
+ * @see #setVersion(int)
+ *
+ */
+ public int getVersion() {
+ return cookieVersion;
+ }
+
+ /**
+ * Sets the version of the cookie specification to which this
+ * cookie conforms.
+ *
+ * @param version the version of the cookie.
+ *
+ * @see #getVersion
+ */
+ public void setVersion(int version) {
+ cookieVersion = version;
+ }
+
+ /**
+ * Returns true if this cookie has expired.
+ *
+ * @return <tt>true</tt> if the cookie has expired.
+ */
+ public boolean isExpired() {
+ return (cookieExpiryDate != null
+ && cookieExpiryDate.getTime() <= System.currentTimeMillis());
+ }
+
+ /**
+ * Returns true if this cookie has expired according to the time passed in.
+ *
+ * @param now The current time.
+ *
+ * @return <tt>true</tt> if the cookie expired.
+ */
+ public boolean isExpired(Date now) {
+ return (cookieExpiryDate != null
+ && cookieExpiryDate.getTime() <= now.getTime());
+ }
+
+
+ /**
+ * Indicates whether the cookie had a path specified in a
+ * path attribute of the <tt>Set-Cookie</tt> header. This value
+ * is important for generating the <tt>Cookie</tt> header because
+ * some cookie specifications require that the <tt>Cookie</tt> header
+ * should only include a path attribute if the cookie's path
+ * was specified in the <tt>Set-Cookie</tt> header.
+ *
+ * @param value <tt>true</tt> if the cookie's path was explicitly
+ * set, <tt>false</tt> otherwise.
+ *
+ * @see #isPathAttributeSpecified
+ */
+ public void setPathAttributeSpecified(boolean value) {
+ hasPathAttribute = value;
+ }
+
+ /**
+ * Returns <tt>true</tt> if cookie's path was set via a path attribute
+ * in the <tt>Set-Cookie</tt> header.
+ *
+ * @return value <tt>true</tt> if the cookie's path was explicitly
+ * set, <tt>false</tt> otherwise.
+ *
+ * @see #setPathAttributeSpecified
+ */
+ public boolean isPathAttributeSpecified() {
+ return hasPathAttribute;
+ }
+
+ /**
+ * Indicates whether the cookie had a domain specified in a
+ * domain attribute of the <tt>Set-Cookie</tt> header. This value
+ * is important for generating the <tt>Cookie</tt> header because
+ * some cookie specifications require that the <tt>Cookie</tt> header
+ * should only include a domain attribute if the cookie's domain
+ * was specified in the <tt>Set-Cookie</tt> header.
+ *
+ * @param value <tt>true</tt> if the cookie's domain was explicitly
+ * set, <tt>false</tt> otherwise.
+ *
+ * @see #isDomainAttributeSpecified
+ */
+ public void setDomainAttributeSpecified(boolean value) {
+ hasDomainAttribute = value;
+ }
+
+ /**
+ * Returns <tt>true</tt> if cookie's domain was set via a domain
+ * attribute in the <tt>Set-Cookie</tt> header.
+ *
+ * @return value <tt>true</tt> if the cookie's domain was explicitly
+ * set, <tt>false</tt> otherwise.
+ *
+ * @see #setDomainAttributeSpecified
+ */
+ public boolean isDomainAttributeSpecified() {
+ return hasDomainAttribute;
+ }
+
+ /**
+ * Returns a hash code in keeping with the
+ * {@link Object#hashCode} general hashCode contract.
+ * @return A hash code
+ */
+ public int hashCode() {
+ return super.hashCode()
+ ^ (null == cookiePath ? 0 : cookiePath.hashCode())
+ ^ (null == cookieDomain ? 0 : cookieDomain.hashCode());
+ }
+
+
+ /**
+ * Two cookies are equal if the name, path and domain match.
+ * @param obj The object to compare against.
+ * @return true if the two objects are equal.
+ */
+ public boolean equals(Object obj) {
+ LOG.trace("enter Cookie.equals(Object)");
+
+ if ((obj != null) && (obj instanceof Cookie)) {
+ Cookie that = (Cookie) obj;
+ return
+ (null == this.getName()
+ ? null == that.getName()
+ : this.getName().equals(that.getName()))
+ && (null == this.getPath()
+ ? null == that.getPath()
+ : this.getPath().equals(that.getPath()))
+ && (null == this.getDomain()
+ ? null == that.getDomain()
+ : this.getDomain().equals(that.getDomain()));
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Return a textual representation of the cookie.
+ *
+ * @return string.
+ */
+ public String toExternalForm() {
+ CookieSpec spec = null;
+ if (getVersion() > 0) {
+ spec = CookiePolicy.getDefaultSpec();
+ } else {
+ spec = CookiePolicy.getCookieSpec(CookiePolicy.NETSCAPE);
+ }
+ return spec.formatCookie(this);
+ }
+
+ /**
+ * <p>Compares two cookies to determine order for cookie header.</p>
+ * <p>Most specific should be first. </p>
+ * <p>This method is implemented so a cookie can be used as a comparator for
+ * a SortedSet of cookies. Specifically it's used above in the
+ * createCookieHeader method.</p>
+ * @param o1 The first object to be compared
+ * @param o2 The second object to be compared
+ * @return See {@link java.util.Comparator#compare(Object,Object)}
+ */
+ public int compare(Object o1, Object o2) {
+ LOG.trace("enter Cookie.compare(Object, Object)");
+
+ if (!(o1 instanceof Cookie)) {
+ throw new ClassCastException(o1.getClass().getName());
+ }
+ if (!(o2 instanceof Cookie)) {
+ throw new ClassCastException(o2.getClass().getName());
+ }
+ Cookie c1 = (Cookie) o1;
+ Cookie c2 = (Cookie) o2;
+ if (c1.getPath() == null && c2.getPath() == null) {
+ return 0;
+ } else if (c1.getPath() == null) {
+ // null is assumed to be "/"
+ if (c2.getPath().equals(CookieSpec.PATH_DELIM)) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else if (c2.getPath() == null) {
+ // null is assumed to be "/"
+ if (c1.getPath().equals(CookieSpec.PATH_DELIM)) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return STRING_COLLATOR.compare(c1.getPath(), c2.getPath());
+ }
+ }
+
+ /**
+ * Return a textual representation of the cookie.
+ *
+ * @return string.
+ *
+ * @see #toExternalForm
+ */
+ public String toString() {
+ return toExternalForm();
+ }
+
+ // ----------------------------------------------------- Instance Variables
+
+ /** Comment attribute. */
+ private String cookieComment;
+
+ /** Domain attribute. */
+ private String cookieDomain;
+
+ /** Expiration {@link Date}. */
+ private Date cookieExpiryDate;
+
+ /** Path attribute. */
+ private String cookiePath;
+
+ /** My secure flag. */
+ private boolean isSecure;
+
+ /**
+ * Specifies if the set-cookie header included a Path attribute for this
+ * cookie
+ */
+ private boolean hasPathAttribute = false;
+
+ /**
+ * Specifies if the set-cookie header included a Domain attribute for this
+ * cookie
+ */
+ private boolean hasDomainAttribute = false;
+
+ /** The version of the cookie specification I was created from. */
+ private int cookieVersion = 0;
+
+ // -------------------------------------------------------------- Constants
+
+ /**
+ * Collator for Cookie comparisons. Could be replaced with references to
+ * specific Locales.
+ */
+ private static final RuleBasedCollator STRING_COLLATOR =
+ (RuleBasedCollator) RuleBasedCollator.getInstance(
+ new Locale("en", "US", ""));
+
+ /** Log object for this class */
+ private static final Log LOG = LogFactory.getLog(Cookie.class);
+
+}
+
1.21 +293 -285 jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java
Index: RFC2109Spec.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/cookie/RFC2109Spec.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- RFC2109Spec.java 13 May 2004 04:02:00 -0000 1.20
+++ RFC2109Spec.java 5 Jun 2004 16:49:20 -0000 1.21
@@ -1,285 +1,293 @@
-/*
- * $Header$
- * $Revision$
- * $Date$
- *
- * ====================================================================
- *
- * Copyright 2002-2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package org.apache.commons.httpclient.cookie;
-
-import org.apache.commons.httpclient.NameValuePair;
-import org.apache.commons.httpclient.Cookie;
-
-/**
- * <p>RFC 2109 specific cookie management functions
- *
- * @author B.C. Holmes
- * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
- * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
- * @author Rod Waldhoff
- * @author dIon Gillard
- * @author Sean C. Sullivan
- * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
- * @author Marc A. Saegesser
- * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
- * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
- *
- * @since 2.0
- */
-
-public class RFC2109Spec extends CookieSpecBase {
-
- /** Default constructor */
- public RFC2109Spec() {
- super();
- }
-
-
- /**
- * Parse RFC 2109 specific cookie attribute and update the corresponsing
- * {@link Cookie} properties.
- *
- * @param attribute {@link NameValuePair} cookie attribute from the
- * <tt>Set- Cookie</tt>
- * @param cookie {@link Cookie} to be updated
- * @throws MalformedCookieException if an exception occurs during parsing
- */
- public void parseAttribute(
- final NameValuePair attribute, final Cookie cookie)
- throws MalformedCookieException {
-
- if (attribute == null) {
- throw new IllegalArgumentException("Attribute may not be null.");
- }
- if (cookie == null) {
- throw new IllegalArgumentException("Cookie may not be null.");
- }
- final String paramName = attribute.getName().toLowerCase();
- final String paramValue = attribute.getValue();
-
- if (paramName.equals("path")) {
- if (paramValue == null) {
- throw new MalformedCookieException(
- "Missing value for path attribute");
- }
- if (paramValue.trim().equals("")) {
- throw new MalformedCookieException(
- "Blank value for path attribute");
- }
- cookie.setPath(paramValue);
- cookie.setPathAttributeSpecified(true);
- } else if (paramName.equals("version")) {
-
- if (paramValue == null) {
- throw new MalformedCookieException(
- "Missing value for version attribute");
- }
- try {
- cookie.setVersion(Integer.parseInt(paramValue));
- } catch (NumberFormatException e) {
- throw new MalformedCookieException("Invalid version: "
- + e.getMessage());
- }
-
- } else {
- super.parseAttribute(attribute, cookie);
- }
- }
-
- /**
- * Performs RFC 2109 compliant {@link Cookie} validation
- *
- * @param host the host from which the {@link Cookie} was received
- * @param port the port from which the {@link Cookie} was received
- * @param path the path from which the {@link Cookie} was received
- * @param secure <tt>true</tt> when the {@link Cookie} was received using a
- * secure connection
- * @param cookie The cookie to validate
- * @throws MalformedCookieException if an exception occurs during
- * validation
- */
- public void validate(String host, int port, String path,
- boolean secure, final Cookie cookie) throws MalformedCookieException {
-
- LOG.trace("enter RFC2109Spec.validate(String, int, String, "
- + "boolean, Cookie)");
-
- // Perform generic validation
- super.validate(host, port, path, secure, cookie);
- // Perform RFC 2109 specific validation
- if (cookie.isDomainAttributeSpecified()
- && (!cookie.getDomain().equals(host))) {
-
- // domain must start with dot
- if (!cookie.getDomain().startsWith(".")) {
- throw new MalformedCookieException("Domain attribute \""
- + cookie.getDomain()
- + "\" violates RFC 2109: domain must start with a dot");
- }
- // domain must have at least one embedded dot
- int dotIndex = cookie.getDomain().indexOf('.', 1);
- if (dotIndex < 0 || dotIndex == cookie.getDomain().length() - 1) {
- throw new MalformedCookieException("Domain attribute \""
- + cookie.getDomain()
- + "\" violates RFC 2109: domain must contain an embedded dot");
- }
- host = host.toLowerCase();
- if (!host.endsWith(cookie.getDomain())) {
- throw new MalformedCookieException(
- "Illegal domain attribute \"" + cookie.getDomain()
- + "\". Domain of origin: \"" + host + "\"");
- }
- // host minus domain may not contain any dots
- String hostWithoutDomain = host.substring(0, host.length()
- - cookie.getDomain().length());
- if (hostWithoutDomain.indexOf('.') != -1) {
- throw new MalformedCookieException("Domain attribute \""
- + cookie.getDomain()
- + "\" violates RFC 2109: host minus domain may not contain any dots");
- }
- }
- }
-
- /**
- * Performs domain-match as defined by the RFC2109.
- * @param host The target host.
- * @param domain The cookie domain attribute.
- * @return true if the specified host matches the given domain.
- *
- * @since 3.0
- */
- public boolean domainMatch(String host, String domain) {
- boolean match = host.equals(domain)
- || (domain.startsWith(".") && host.endsWith(domain));
-
- return match;
- }
-
- /**
- * Return a name/value string suitable for sending in a <tt>"Cookie"</tt>
- * header as defined in RFC 2109 for backward compatibility with cookie
- * version 0
- * @param name The name.
- * @param value The value
- * @param version The cookie version
- * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
- */
-
- private String formatNameValuePair(
- final String name, final String value, int version) {
-
- final StringBuffer buffer = new StringBuffer();
- if (version < 1) {
- buffer.append(name);
- buffer.append("=");
- if (value != null) {
- buffer.append(value);
- }
- } else {
- buffer.append(name);
- buffer.append("=\"");
- if (value != null) {
- buffer.append(value);
- }
- buffer.append("\"");
- }
- return buffer.toString();
- }
-
- /**
- * Return a string suitable for sending in a <tt>"Cookie"</tt> header
- * as defined in RFC 2109 for backward compatibility with cookie version 0
- * @param cookie a {@link Cookie} to be formatted as string
- * @param version The version to use.
- * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
- */
- private String formatCookieAsVer(Cookie cookie, int version) {
- LOG.trace("enter RFC2109Spec.formatCookieAsVer(Cookie)");
- StringBuffer buf = new StringBuffer();
- buf.append(formatNameValuePair(cookie.getName(),
- cookie.getValue(), version));
- if (cookie.getDomain() != null
- && cookie.isDomainAttributeSpecified()) {
-
- buf.append("; ");
- buf.append(formatNameValuePair("$Domain",
- cookie.getDomain(), version));
- }
- if (cookie.getPath() != null && cookie.isPathAttributeSpecified()) {
- buf.append("; ");
- buf.append(formatNameValuePair("$Path", cookie.getPath(), version));
- }
- return buf.toString();
- }
-
-
- /**
- * Return a string suitable for sending in a <tt>"Cookie"</tt> header as
- * defined in RFC 2109
- * @param cookie a {@link Cookie} to be formatted as string
- * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
- */
- public String formatCookie(Cookie cookie) {
- LOG.trace("enter RFC2109Spec.formatCookie(Cookie)");
- if (cookie == null) {
- throw new IllegalArgumentException("Cookie may not be null");
- }
- int ver = cookie.getVersion();
- StringBuffer buffer = new StringBuffer();
- buffer.append(formatNameValuePair("$Version",
- Integer.toString(ver), ver));
- buffer.append("; ");
- buffer.append(formatCookieAsVer(cookie, ver));
- return buffer.toString();
- }
-
- /**
- * Create a RFC 2109 compliant <tt>"Cookie"</tt> header value containing all
- * {@link Cookie}s in <i>cookies</i> suitable for sending in a <tt>"Cookie"
- * </tt> header
- * @param cookies an array of {@link Cookie}s to be formatted
- * @return a string suitable for sending in a Cookie header.
- */
- public String formatCookies(Cookie[] cookies) {
- LOG.trace("enter RFC2109Spec.formatCookieHeader(Cookie[])");
- int version = Integer.MAX_VALUE;
- // Pick the lowerest common denominator
- for (int i = 0; i < cookies.length; i++) {
- Cookie cookie = cookies[i];
- if (cookie.getVersion() < version) {
- version = cookie.getVersion();
- }
- }
- final StringBuffer buffer = new StringBuffer();
- buffer.append(formatNameValuePair("$Version",
- Integer.toString(version), version));
- for (int i = 0; i < cookies.length; i++) {
- buffer.append("; ");
- buffer.append(formatCookieAsVer(cookies[i], version));
- }
- return buffer.toString();
- }
-
-}
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.httpclient.cookie;
+
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.Cookie;
+
+/**
+ * <p>RFC 2109 specific cookie management functions
+ *
+ * @author B.C. Holmes
+ * @author <a href="mailto:jericho@thinkfree.com">Park, Sung-Gu</a>
+ * @author <a href="mailto:dsale@us.britannica.com">Doug Sale</a>
+ * @author Rod Waldhoff
+ * @author dIon Gillard
+ * @author Sean C. Sullivan
+ * @author <a href="mailto:JEvans@Cyveillance.com">John Evans</a>
+ * @author Marc A. Saegesser
+ * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
+ * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
+ *
+ * @since 2.0
+ */
+
+public class RFC2109Spec extends CookieSpecBase {
+
+ /** Default constructor */
+ public RFC2109Spec() {
+ super();
+ }
+
+
+ /**
+ * Parse RFC 2109 specific cookie attribute and update the corresponsing
+ * {@link Cookie} properties.
+ *
+ * @param attribute {@link NameValuePair} cookie attribute from the
+ * <tt>Set- Cookie</tt>
+ * @param cookie {@link Cookie} to be updated
+ * @throws MalformedCookieException if an exception occurs during parsing
+ */
+ public void parseAttribute(
+ final NameValuePair attribute, final Cookie cookie)
+ throws MalformedCookieException {
+
+ if (attribute == null) {
+ throw new IllegalArgumentException("Attribute may not be null.");
+ }
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null.");
+ }
+ final String paramName = attribute.getName().toLowerCase();
+ final String paramValue = attribute.getValue();
+
+ if (paramName.equals("path")) {
+ if (paramValue == null) {
+ throw new MalformedCookieException(
+ "Missing value for path attribute");
+ }
+ if (paramValue.trim().equals("")) {
+ throw new MalformedCookieException(
+ "Blank value for path attribute");
+ }
+ cookie.setPath(paramValue);
+ cookie.setPathAttributeSpecified(true);
+ } else if (paramName.equals("version")) {
+
+ if (paramValue == null) {
+ throw new MalformedCookieException(
+ "Missing value for version attribute");
+ }
+ try {
+ cookie.setVersion(Integer.parseInt(paramValue));
+ } catch (NumberFormatException e) {
+ throw new MalformedCookieException("Invalid version: "
+ + e.getMessage());
+ }
+
+ } else {
+ super.parseAttribute(attribute, cookie);
+ }
+ }
+
+ /**
+ * Performs RFC 2109 compliant {@link Cookie} validation
+ *
+ * @param host the host from which the {@link Cookie} was received
+ * @param port the port from which the {@link Cookie} was received
+ * @param path the path from which the {@link Cookie} was received
+ * @param secure <tt>true</tt> when the {@link Cookie} was received using a
+ * secure connection
+ * @param cookie The cookie to validate
+ * @throws MalformedCookieException if an exception occurs during
+ * validation
+ */
+ public void validate(String host, int port, String path,
+ boolean secure, final Cookie cookie) throws MalformedCookieException {
+
+ LOG.trace("enter RFC2109Spec.validate(String, int, String, "
+ + "boolean, Cookie)");
+
+ // Perform generic validation
+ super.validate(host, port, path, secure, cookie);
+ // Perform RFC 2109 specific validation
+
+ if (cookie.getName().indexOf(' ') != -1) {
+ throw new MalformedCookieException("Cookie name may not contain blanks");
+ }
+ if (cookie.getName().startsWith("$")) {
+ throw new MalformedCookieException("Cookie name may not start with $");
+ }
+
+ if (cookie.isDomainAttributeSpecified()
+ && (!cookie.getDomain().equals(host))) {
+
+ // domain must start with dot
+ if (!cookie.getDomain().startsWith(".")) {
+ throw new MalformedCookieException("Domain attribute \""
+ + cookie.getDomain()
+ + "\" violates RFC 2109: domain must start with a dot");
+ }
+ // domain must have at least one embedded dot
+ int dotIndex = cookie.getDomain().indexOf('.', 1);
+ if (dotIndex < 0 || dotIndex == cookie.getDomain().length() - 1) {
+ throw new MalformedCookieException("Domain attribute \""
+ + cookie.getDomain()
+ + "\" violates RFC 2109: domain must contain an embedded dot");
+ }
+ host = host.toLowerCase();
+ if (!host.endsWith(cookie.getDomain())) {
+ throw new MalformedCookieException(
+ "Illegal domain attribute \"" + cookie.getDomain()
+ + "\". Domain of origin: \"" + host + "\"");
+ }
+ // host minus domain may not contain any dots
+ String hostWithoutDomain = host.substring(0, host.length()
+ - cookie.getDomain().length());
+ if (hostWithoutDomain.indexOf('.') != -1) {
+ throw new MalformedCookieException("Domain attribute \""
+ + cookie.getDomain()
+ + "\" violates RFC 2109: host minus domain may not contain any dots");
+ }
+ }
+ }
+
+ /**
+ * Performs domain-match as defined by the RFC2109.
+ * @param host The target host.
+ * @param domain The cookie domain attribute.
+ * @return true if the specified host matches the given domain.
+ *
+ * @since 3.0
+ */
+ public boolean domainMatch(String host, String domain) {
+ boolean match = host.equals(domain)
+ || (domain.startsWith(".") && host.endsWith(domain));
+
+ return match;
+ }
+
+ /**
+ * Return a name/value string suitable for sending in a <tt>"Cookie"</tt>
+ * header as defined in RFC 2109 for backward compatibility with cookie
+ * version 0
+ * @param name The name.
+ * @param value The value
+ * @param version The cookie version
+ * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
+ */
+
+ private String formatNameValuePair(
+ final String name, final String value, int version) {
+
+ final StringBuffer buffer = new StringBuffer();
+ if (version < 1) {
+ buffer.append(name);
+ buffer.append("=");
+ if (value != null) {
+ buffer.append(value);
+ }
+ } else {
+ buffer.append(name);
+ buffer.append("=\"");
+ if (value != null) {
+ buffer.append(value);
+ }
+ buffer.append("\"");
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Return a string suitable for sending in a <tt>"Cookie"</tt> header
+ * as defined in RFC 2109 for backward compatibility with cookie version 0
+ * @param cookie a {@link Cookie} to be formatted as string
+ * @param version The version to use.
+ * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
+ */
+ private String formatCookieAsVer(Cookie cookie, int version) {
+ LOG.trace("enter RFC2109Spec.formatCookieAsVer(Cookie)");
+ StringBuffer buf = new StringBuffer();
+ buf.append(formatNameValuePair(cookie.getName(),
+ cookie.getValue(), version));
+ if (cookie.getDomain() != null
+ && cookie.isDomainAttributeSpecified()) {
+
+ buf.append("; ");
+ buf.append(formatNameValuePair("$Domain",
+ cookie.getDomain(), version));
+ }
+ if (cookie.getPath() != null && cookie.isPathAttributeSpecified()) {
+ buf.append("; ");
+ buf.append(formatNameValuePair("$Path", cookie.getPath(), version));
+ }
+ return buf.toString();
+ }
+
+
+ /**
+ * Return a string suitable for sending in a <tt>"Cookie"</tt> header as
+ * defined in RFC 2109
+ * @param cookie a {@link Cookie} to be formatted as string
+ * @return a string suitable for sending in a <tt>"Cookie"</tt> header.
+ */
+ public String formatCookie(Cookie cookie) {
+ LOG.trace("enter RFC2109Spec.formatCookie(Cookie)");
+ if (cookie == null) {
+ throw new IllegalArgumentException("Cookie may not be null");
+ }
+ int ver = cookie.getVersion();
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(formatNameValuePair("$Version",
+ Integer.toString(ver), ver));
+ buffer.append("; ");
+ buffer.append(formatCookieAsVer(cookie, ver));
+ return buffer.toString();
+ }
+
+ /**
+ * Create a RFC 2109 compliant <tt>"Cookie"</tt> header value containing all
+ * {@link Cookie}s in <i>cookies</i> suitable for sending in a <tt>"Cookie"
+ * </tt> header
+ * @param cookies an array of {@link Cookie}s to be formatted
+ * @return a string suitable for sending in a Cookie header.
+ */
+ public String formatCookies(Cookie[] cookies) {
+ LOG.trace("enter RFC2109Spec.formatCookieHeader(Cookie[])");
+ int version = Integer.MAX_VALUE;
+ // Pick the lowerest common denominator
+ for (int i = 0; i < cookies.length; i++) {
+ Cookie cookie = cookies[i];
+ if (cookie.getVersion() < version) {
+ version = cookie.getVersion();
+ }
+ }
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append(formatNameValuePair("$Version",
+ Integer.toString(version), version));
+ for (int i = 0; i < cookies.length; i++) {
+ buffer.append("; ");
+ buffer.append(formatCookieAsVer(cookies[i], version));
+ }
+ return buffer.toString();
+ }
+
+}
1.6 +17 -22 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie/TestCookieCompatibilitySpec.java
Index: TestCookieCompatibilitySpec.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie/TestCookieCompatibilitySpec.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TestCookieCompatibilitySpec.java 27 Apr 2004 22:35:21 -0000 1.5
+++ TestCookieCompatibilitySpec.java 5 Jun 2004 16:49:20 -0000 1.6
@@ -702,31 +702,26 @@
/**
* Tests if cookie constructor rejects cookie name containing blanks.
*/
- public void testInvalidCookieName() {
- try {
- CookieSpec cookiespec = new CookieSpecBase();
- cookiespec.parse("localhost", 80, "/", false, "invalid name=");
- fail("MalformedCookieException must have been thrown");
- }
- catch(MalformedCookieException e) {
- // Expected
- }
+ public void testCookieNameWithBlanks() throws Exception {
+ Header setcookie = new Header("Set-Cookie", "invalid name=");
+ CookieSpec cookiespec = new CookieSpecBase();
+ Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
+ assertNotNull(parsed);
+ assertEquals(1, parsed.length);
}
/**
* Tests if cookie constructor rejects cookie name starting with $.
*/
- public void testInvalidCookieName2() {
- try {
- CookieSpec cookiespec = new CookieSpecBase();
- cookiespec.parse("localhost", 80, "/", false, "$invalid_name=");
- fail("MalformedCookieException must have been thrown");
- }
- catch(MalformedCookieException e) {
- // Expected
- }
+ public void testCookieNameStartingWithDollarSign() throws Exception {
+ Header setcookie = new Header("Set-Cookie", "$invalid_name=");
+ CookieSpec cookiespec = new CookieSpecBase();
+ Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
+ assertNotNull(parsed);
+ assertEquals(1, parsed.length);
}
+
/**
* Tests if malformatted expires attribute is parsed correctly.
1.3 +33 -4 jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie/TestCookieRFC2109Spec.java
Index: TestCookieRFC2109Spec.java
===================================================================
RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie/TestCookieRFC2109Spec.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestCookieRFC2109Spec.java 25 Apr 2004 11:57:39 -0000 1.2
+++ TestCookieRFC2109Spec.java 5 Jun 2004 16:49:20 -0000 1.3
@@ -236,6 +236,35 @@
}
/**
+ * Tests if cookie constructor rejects cookie name containing blanks.
+ */
+ public void testCookieNameWithBlanks() throws Exception {
+ Header setcookie = new Header("Set-Cookie", "invalid name=");
+ CookieSpec cookiespec = new RFC2109Spec();
+ try {
+ Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
+ fail("MalformedCookieException exception should have been thrown");
+ } catch (MalformedCookieException e) {
+ // expected
+ }
+ }
+
+
+ /**
+ * Tests if cookie constructor rejects cookie name starting with $.
+ */
+ public void testCookieNameStartingWithDollarSign() throws Exception {
+ Header setcookie = new Header("Set-Cookie", "$invalid_name=");
+ CookieSpec cookiespec = new RFC2109Spec();
+ try {
+ Cookie[] parsed = cookieParse(cookiespec, "127.0.0.1", 80, "/", false, setcookie);
+ fail("MalformedCookieException exception should have been thrown");
+ } catch (MalformedCookieException e) {
+ // expected
+ }
+ }
+
+ /**
* Tests if default cookie validator rejects cookies originating from a host without domain
* where domain attribute does not match the host of origin
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: cvs commit:
jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie
TestCookieCompatibilitySpec.java TestCookieRFC2109Spec.java
Posted by Oleg Kalnichevski <ol...@bluewin.ch>.
Odi,
I have no idea why the commit diff got trashed so badly. CVS content
appears correct.
Oleg
On Mon, 2004-06-07 at 09:42, Ortwin Glück wrote:
> What's the problem with this diff? Why is it so bad?
>
> olegk@apache.org wrote:
>
> > olegk 2004/06/05 09:49:21
> >
> > Modified: httpclient/src/java/org/apache/commons/httpclient
> > Cookie.java
> > httpclient/src/java/org/apache/commons/httpclient/cookie
> > RFC2109Spec.java
> > httpclient/src/test/org/apache/commons/httpclient/cookie
> > TestCookieCompatibilitySpec.java
> > TestCookieRFC2109Spec.java
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/cookie
TestCookieCompatibilitySpec.java TestCookieRFC2109Spec.java
Posted by Ortwin Glück <or...@nose.ch>.
What's the problem with this diff? Why is it so bad?
olegk@apache.org wrote:
> olegk 2004/06/05 09:49:21
>
> Modified: httpclient/src/java/org/apache/commons/httpclient
> Cookie.java
> httpclient/src/java/org/apache/commons/httpclient/cookie
> RFC2109Spec.java
> httpclient/src/test/org/apache/commons/httpclient/cookie
> TestCookieCompatibilitySpec.java
> TestCookieRFC2109Spec.java
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org