diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/cookie/ClientCookieEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/cookie/ClientCookieEncoder.java index 0287f4b3de..ac9bd03dbf 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/cookie/ClientCookieEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/cookie/ClientCookieEncoder.java @@ -91,7 +91,8 @@ public final class ClientCookieEncoder extends CookieEncoder { * Sort cookies into decreasing order of path length, breaking ties by sorting into increasing chronological * order of creation time, as recommended by RFC 6265. */ - private static final Comparator COOKIE_COMPARATOR = new Comparator() { + // package-private for testing only. + static final Comparator COOKIE_COMPARATOR = new Comparator() { @Override public int compare(Cookie c1, Cookie c2) { String path1 = c1.path(); @@ -103,13 +104,10 @@ public final class ClientCookieEncoder extends CookieEncoder { // limited use. int len1 = path1 == null ? Integer.MAX_VALUE : path1.length(); int len2 = path2 == null ? Integer.MAX_VALUE : path2.length(); - int diff = len2 - len1; - if (diff != 0) { - return diff; - } + // Rely on Arrays.sort's stability to retain creation order in cases where // cookies have same path length. - return 0; + return len2 - len1; } }; diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/cookie/ClientCookieEncoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/cookie/ClientCookieEncoderTest.java index af81059dd8..8fbe544630 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/cookie/ClientCookieEncoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/cookie/ClientCookieEncoderTest.java @@ -51,4 +51,16 @@ public class ClientCookieEncoderTest { public void testRejectCookieValueWithSemicolon() { ClientCookieEncoder.STRICT.encode(new DefaultCookie("myCookie", "foo;bar")); } + + @Test + public void testComparatorForSamePathLength() { + Cookie cookie = new DefaultCookie("test", "value"); + cookie.setPath("1"); + + Cookie cookie2 = new DefaultCookie("test", "value"); + cookie2.setPath("2"); + + assertEquals(0, ClientCookieEncoder.COOKIE_COMPARATOR.compare(cookie, cookie2)); + assertEquals(0, ClientCookieEncoder.COOKIE_COMPARATOR.compare(cookie2, cookie)); + } }