marcsaeg 02/02/22 11:13:51
Modified: httpclient/src/java/org/apache/commons/httpclient
Cookie.java
Log:
1) Added better support for Netscape cookies.
2) Fixed cookie sorting problem. The previous implementation used a
set and the compare() method made cookies with identical paths compre
as equals which prevented them from being added.
Revision Changes Path
1.14 +97 -26
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.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Cookie.java 19 Feb 2002 00:15:18 -0000 1.13
+++ Cookie.java 22 Feb 2002 19:13:51 -0000 1.14
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java,v
1.13 2002/02/19 00:15:18 dion Exp $
- * $Revision: 1.13 $
- * $Date: 2002/02/19 00:15:18 $
+ * $Header:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/Cookie.java,v
1.14 2002/02/22 19:13:51 marcsaeg Exp $
+ * $Revision: 1.14 $
+ * $Date: 2002/02/22 19:13:51 $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -68,8 +68,9 @@
import java.util.Enumeration;
import java.util.Vector;
import java.util.Locale;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.StringTokenizer;
+import java.util.List;
+import java.util.LinkedList;
import java.util.Comparator;
import java.util.Iterator;
import java.text.RuleBasedCollator;
@@ -87,7 +88,7 @@
* @author Rod Waldhoff
* @author dIon Gillard
* @author <a href="mailto:[EMAIL PROTECTED]">John Evans</a>
- * @version $Revision: 1.13 $ $Date: 2002/02/19 00:15:18 $
+ * @version $Revision: 1.14 $ $Date: 2002/02/22 19:13:51 $
*/
public class Cookie extends NameValuePair implements Serializable, Comparator {
@@ -350,11 +351,11 @@
StringBuffer buf = new StringBuffer();
buf.append(getName()).append("=").append(getValue());
if (_path != null) {
- buf.append(";$Path=");
+ buf.append("; $Path=");
buf.append(_path);
}
if (_domain != null) {
- buf.append(";$Domain=");
+ buf.append("; $Domain=");
buf.append(_domain);
}
return buf.toString();
@@ -473,20 +474,18 @@
if (cookies.length <= 0) {
return null;
}
- Set addedCookies = new TreeSet(cookies[0]);
+ List addedCookies = new LinkedList();
for(int i=0;i<cookies.length;i++) {
if(cookies[i].matches(domain,port,path,secure,now)) {
- addedCookies.add(cookies[i]);
+ addInPathOrder(addedCookies, cookies[i]);
added = true;
}
}
if (added) {
for (Iterator itr = addedCookies.iterator(); itr.hasNext(); ) {
Cookie cookie = (Cookie)itr.next();
- if (cookie.matches(domain,port,path,secure,now)) {
- value.append(";");
- value.append(cookie.toExternalForm());
- }
+ value.append("; ");
+ value.append(cookie.toExternalForm());
}
return new Header("Cookie", value.toString());
@@ -728,7 +727,7 @@
}
// check version
- if (cookie.getVersion() != 1) {
+ if (cookie.getVersion() < 0 || cookie.getVersion() > 1) {
if(log.isInfoEnabled()) {
log.info("Cookie.parse(): Rejecting set cookie header \"" +
setCookie.getValue() + "\" because it has an unrecognized version attribute (" +
cookie.getVersion() + ").");
}
@@ -756,16 +755,41 @@
" Illegal domain attribute" + cookie.getDomain());
}
- // host minus domain may not contain any dots
- if (domain.substring(0,
- domain.length() -
- cookie.getDomain().length()).indexOf('.') != -1) {
- if(log.isInfoEnabled()) {
- log.info("Cookie.parse(): Rejecting set cookie header \"" +
setCookie.getValue() + "\" because \"" + cookie.getName() + "\" has an illegal domain
attribute (\"" + cookie.getDomain() + "\") for the given domain \"" + domain + "\".");
+ if(cookie.getVersion() == 0){
+ // Validate domain using Netscape cookie specification
+ int domainParts = new StringTokenizer(domain,
".").countTokens();
+ if(isSpecialDomain(domain)){
+ if(domainParts < 2){
+ if(log.isInfoEnabled()) {
+ log.info("Cookie.parse(): Rejecting set cookie
header \"" + setCookie.getValue() + "\" because \"" + cookie.getName() + "\" has an
illegal domain attribute (\"" + cookie.getDomain() + "\") for the given domain \"" +
domain + "\". It violoates the Netscape cookie specification for special TLDs.");
+ }
+ throw new HttpException(
+ "Bad Set-Cookie header: " + setCookie.getValue() +
+ " Illegal domain attribute " + cookie.getDomain());
+ }
+ }else{
+ if(domainParts < 3){
+ if(log.isInfoEnabled()) {
+ log.info("Cookie.parse(): Rejecting set cookie
header \"" + setCookie.getValue() + "\" because \"" + cookie.getName() + "\" has an
illegal domain attribute (\"" + cookie.getDomain() + "\") for the given domain \"" +
domain + "\". It violoates the Netscape cookie specification for non-special TLDs.");
+ }
+ throw new HttpException(
+ "Bad Set-Cookie header: " + setCookie.getValue() +
+ " Illegal domain attribute " + cookie.getDomain());
+ }
+
+ }
+ }else{
+ // host minus domain may not contain any dots
+ if (domain.substring(0,
+ domain.length() -
+ cookie.getDomain().length()).indexOf('.') != -1) {
+ if(log.isInfoEnabled()) {
+ log.info("Cookie.parse(): Rejecting set cookie header
\"" + setCookie.getValue() + "\" because \"" + cookie.getName() + "\" has an illegal
domain attribute (\"" + cookie.getDomain() + "\") for the given domain \"" + domain +
"\".");
+ }
+ throw new HttpException(
+ "Bad Set-Cookie header: " + setCookie.getValue() +
+ " Illegal domain attribute " + cookie.getDomain());
}
- throw new HttpException(
- "Bad Set-Cookie header: " + setCookie.getValue() +
- " Illegal domain attribute " + cookie.getDomain());
}
}
@@ -815,6 +839,49 @@
return cookies;
}
+ /**
+ * Checks if the given domain is in one of the seven special
+ * top level domains defined by the Netscape cookie specification.
+ */
+ private static boolean isSpecialDomain(String domain)
+ {
+ String ucDomain = domain.toUpperCase();
+ if(ucDomain.endsWith(".COM") ||
+ ucDomain.endsWith(".EDU") ||
+ ucDomain.endsWith(".NET") ||
+ ucDomain.endsWith(".GOV") ||
+ ucDomain.endsWith(".MIL") ||
+ ucDomain.endsWith(".ORG") ||
+ ucDomain.endsWith(".INT")){
+ return true;
+ }
+
+ return false;
+
+ }
+
+ /**
+ * Adds the given cookie into the given in descending path order. That is,
+ * more specific path to least specific paths. This may not be the fastest
+ * algorythm, but it'll work OK for the small number of cookies we're
+ * generally dealing with.
+ *
+ * @param list - the list to add the cookie to
+ * @param addCookie - the Cookie to add to list
+ */
+ private static void addInPathOrder(List list, Cookie addCookie)
+ {
+ int i = 0;
+
+ for(i=0;i<list.size();i++){
+ Cookie c = (Cookie)list.get(i);
+ if(addCookie.compare(addCookie, c) > 0){
+ break;
+ }
+ }
+ list.add(i, addCookie);
+ }
+
// ----------------------------------------------------- Instance Variables
/** My comment. */
@@ -833,12 +900,12 @@
private boolean _secure;
/** The version of the cookie specification I was created from. */
- private int _version = 1;
+ private int _version = 0;
// -------------------------------------------------------------- Constants
/** List of valid date formats for the "expires" cookie attribute. */
- private static final DateFormat[] expiryFormats = new DateFormat[4];
+ private static final DateFormat[] expiryFormats = new DateFormat[6];
/** Collator for Cookie comparisons. Could be replaced with references to
specific Locales. */
private static final RuleBasedCollator stringCollator =
@@ -855,6 +922,10 @@
expiryFormats[2] = new SimpleDateFormat("EEE dd-MMM-yy HH:mm:ss z",
Locale.US);
expiryFormats[3] = new SimpleDateFormat("EEE dd-MMM-yyyy HH:mm:ss z",
+ Locale.US);
+ expiryFormats[4] = new SimpleDateFormat("EEE dd MMM yy HH:mm:ss z",
+ Locale.US);
+ expiryFormats[5] = new SimpleDateFormat("EEE dd MMM yyyy HH:mm:ss z",
Locale.US);
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>