diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java index f14e1f2189f..89a004f7107 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java @@ -934,6 +934,9 @@ public class HttpFields QuotedStringTokenizer.quoteIfNeeded(buf, name, delim); buf.append('='); String start=buf.toString(); + boolean hasDomain = false; + boolean hasPath = false; + if (value != null && value.length() > 0) QuotedStringTokenizer.quoteIfNeeded(buf, value, delim); @@ -945,6 +948,7 @@ public class HttpFields if (path != null && path.length() > 0) { + hasPath = true; buf.append(";Path="); if (path.trim().startsWith("\"")) buf.append(path); @@ -953,6 +957,7 @@ public class HttpFields } if (domain != null && domain.length() > 0) { + hasDomain = true; buf.append(";Domain="); QuotedStringTokenizer.quoteIfNeeded(buf,domain.toLowerCase(),delim); } @@ -985,14 +990,20 @@ public class HttpFields Field last=null; while (field!=null) { - if (field._value!=null && field._value.toString().startsWith(start)) + String val = (field._value == null ? null : field._value.toString()); + if (val!=null && val.startsWith(start)) { - _fields.remove(field); - if (last==null) - _names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next); - else - last._next=field._next; - break; + //existing cookie has same name, does it also match domain and path? + if (((!hasDomain && !val.contains("Domain")) || (hasDomain && val.contains("Domain="+domain))) && + ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path="+path)))) + { + _fields.remove(field); + if (last==null) + _names.put(HttpHeaders.SET_COOKIE_BUFFER,field._next); + else + last._next=field._next; + break; + } } last=field; field=field._next; diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java index 770ffb42de4..3e26687ec4a 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java @@ -364,7 +364,8 @@ public class HttpFieldsTest assertEquals("minimal=value",fields.getStringField("Set-Cookie")); fields.clear(); - fields.addSetCookie("everything","wrong","wrong","wrong",0,"to be replaced",true,true,0); + //test cookies with same name, domain and path, only 1 allowed + fields.addSetCookie("everything","wrong","domain","path",0,"to be replaced",true,true,0); fields.addSetCookie("everything","value","domain","path",0,"comment",true,true,0); assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",fields.getStringField("Set-Cookie")); Enumeration e =fields.getValues("Set-Cookie"); @@ -372,6 +373,61 @@ public class HttpFieldsTest assertEquals("everything=value;Comment=comment;Path=path;Domain=domain;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); assertFalse(e.hasMoreElements()); assertEquals("Thu, 01 Jan 1970 00:00:00 GMT",fields.getStringField("Expires")); + assertFalse(e.hasMoreElements()); + + //test cookies with same name, different domain + fields.clear(); + fields.addSetCookie("everything","other","domain1","path",0,"blah",true,true,0); + fields.addSetCookie("everything","value","domain2","path",0,"comment",true,true,0); + e =fields.getValues("Set-Cookie"); + assertTrue(e.hasMoreElements()); + assertEquals("everything=other;Comment=blah;Path=path;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertTrue(e.hasMoreElements()); + assertEquals("everything=value;Comment=comment;Path=path;Domain=domain2;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertFalse(e.hasMoreElements()); + + //test cookies with same name, same path, one with domain, one without + fields.clear(); + fields.addSetCookie("everything","other","domain1","path",0,"blah",true,true,0); + fields.addSetCookie("everything","value","","path",0,"comment",true,true,0); + e =fields.getValues("Set-Cookie"); + assertTrue(e.hasMoreElements()); + assertEquals("everything=other;Comment=blah;Path=path;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertTrue(e.hasMoreElements()); + assertEquals("everything=value;Comment=comment;Path=path;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertFalse(e.hasMoreElements()); + + + //test cookies with same name, different path + fields.clear(); + fields.addSetCookie("everything","other","domain1","path1",0,"blah",true,true,0); + fields.addSetCookie("everything","value","domain1","path2",0,"comment",true,true,0); + e =fields.getValues("Set-Cookie"); + assertTrue(e.hasMoreElements()); + assertEquals("everything=other;Comment=blah;Path=path1;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertTrue(e.hasMoreElements()); + assertEquals("everything=value;Comment=comment;Path=path2;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertFalse(e.hasMoreElements()); + + //test cookies with same name, same domain, one with path, one without + fields.clear(); + fields.addSetCookie("everything","other","domain1","path1",0,"blah",true,true,0); + fields.addSetCookie("everything","value","domain1","",0,"comment",true,true,0); + e =fields.getValues("Set-Cookie"); + assertTrue(e.hasMoreElements()); + assertEquals("everything=other;Comment=blah;Path=path1;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertTrue(e.hasMoreElements()); + assertEquals("everything=value;Comment=comment;Domain=domain1;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertFalse(e.hasMoreElements()); + + //test cookies same name only, no path, no domain + fields.clear(); + fields.addSetCookie("everything","other","","",0,"blah",true,true,0); + fields.addSetCookie("everything","value","","",0,"comment",true,true,0); + e =fields.getValues("Set-Cookie"); + assertTrue(e.hasMoreElements()); + assertEquals("everything=value;Comment=comment;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Secure;HttpOnly",e.nextElement()); + assertFalse(e.hasMoreElements()); fields.clear(); fields.addSetCookie("ev erything","va lue","do main","pa th",1,"co mment",true,true,2);