From b6cfc2412766c634941b6f1166f0929efdf703eb Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Fri, 13 Mar 2009 15:29:54 +0000 Subject: [PATCH] Handles client-side cookie much better now --- .../example/http/HttpRequestHandler.java | 5 +- .../handler/codec/http/CookieDecoder.java | 18 +++-- .../handler/codec/http/CookieDecoderTest.java | 78 ++++++++++++++----- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java b/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java index 197d7a7ac1..10a8caa1bc 100644 --- a/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java +++ b/src/main/java/org/jboss/netty/example/http/HttpRequestHandler.java @@ -23,6 +23,7 @@ package org.jboss.netty.example.http; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Map.Entry; import org.jboss.netty.buffer.ChannelBuffer; @@ -132,11 +133,11 @@ public class HttpRequestHandler extends SimpleChannelHandler { String cookieString = request.getHeader(HttpHeaders.Names.COOKIE); if (cookieString != null) { CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookies = cookieDecoder.decode(cookieString); + Set cookies = cookieDecoder.decode(cookieString); if(!cookies.isEmpty()) { // Reset the cookies if necessary. CookieEncoder cookieEncoder = new CookieEncoder(); - for (Cookie cookie : cookies.values()) { + for (Cookie cookie : cookies) { cookieEncoder.addCookie(cookie); } response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode()); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java index ac696a8233..05e80a7477 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java @@ -22,10 +22,8 @@ package org.jboss.netty.handler.codec.http; import java.text.ParseException; -import java.util.Map; -import java.util.TreeMap; - -import org.jboss.netty.util.CaseIgnoringComparator; +import java.util.Set; +import java.util.TreeSet; /** * @author The Netty Project (netty-dev@lists.jboss.org) @@ -54,10 +52,11 @@ public class CookieDecoder { this.charset = charset; } - public Map decode(String header) { - Map cookies = new TreeMap(CaseIgnoringComparator.INSTANCE); + public Set decode(String header) { + Set cookies = new TreeSet(); String[] split = header.split(SEMICOLON); int version = 0; + boolean versionAtTheBeginning = false; for (int i = 0; i < split.length; i++) { DefaultCookie theCookie; String s = split[i]; @@ -68,19 +67,21 @@ public class CookieDecoder { // $Version is the only attribute that can come before the // actual cookie name-value pair. - if (name.equalsIgnoreCase(CookieHeaderNames.VERSION)) { + if (!versionAtTheBeginning && + name.equalsIgnoreCase(CookieHeaderNames.VERSION)) { try { version = Integer.parseInt(trimValue(cookie[1])); } catch (NumberFormatException e) { // Ignore. } + versionAtTheBeginning = true; continue; } // If it's not a version attribute, it's the name-value pair. value = QueryStringDecoder.decodeComponent(trimValue(cookie[1]), charset); theCookie = new DefaultCookie(name, value); - cookies.put(name, theCookie); + cookies.add(theCookie); boolean discard = false; boolean secure = false; String comment = null; @@ -175,6 +176,7 @@ public class CookieDecoder { } private String trimName(String name) { + name = name.trim(); if (name.startsWith("$")) { return name.substring(1); } else { diff --git a/src/test/java/org/jboss/netty/handler/codec/http/CookieDecoderTest.java b/src/test/java/org/jboss/netty/handler/codec/http/CookieDecoderTest.java index a57afa9c23..d68afea54e 100644 --- a/src/test/java/org/jboss/netty/handler/codec/http/CookieDecoderTest.java +++ b/src/test/java/org/jboss/netty/handler/codec/http/CookieDecoderTest.java @@ -24,7 +24,8 @@ package org.jboss.netty.handler.codec.http; import static org.junit.Assert.*; import java.util.Date; -import java.util.Map; +import java.util.Iterator; +import java.util.Set; import org.junit.Test; @@ -41,9 +42,9 @@ public class CookieDecoderTest { cookieString = cookieString.replace("XXX", new CookieDateFormat().format(new Date(System.currentTimeMillis() + 50000))); CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookieMap = cookieDecoder.decode(cookieString); - assertEquals(1, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = cookieDecoder.decode(cookieString); + assertEquals(1, cookies.size()); + Cookie cookie = cookies.iterator().next(); assertNotNull(cookie); assertEquals("myValue", cookie.getValue()); assertNull(cookie.getComment()); @@ -61,9 +62,9 @@ public class CookieDecoderTest { public void testDecodingSingleCookieV0ExtraParamsIgnored() { String cookieString = "myCookie=myValue;max-age=50;path=/apathsomewhere;domain=.adomainsomewhere;secure;comment=this is a comment;version=0;commentURL=http://aurl.com;port=80,8080;discard;"; CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookieMap = cookieDecoder.decode(cookieString); - assertEquals(1, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = cookieDecoder.decode(cookieString); + assertEquals(1, cookies.size()); + Cookie cookie = cookies.iterator().next(); assertNotNull(cookie); assertEquals("myValue", cookie.getValue()); assertNull(cookie.getComment()); @@ -80,9 +81,9 @@ public class CookieDecoderTest { public void testDecodingSingleCookieV1() { String cookieString = "myCookie=myValue;max-age=50;path=/apathsomewhere;domain=.adomainsomewhere;secure;comment=this is a comment;version=1;"; CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookieMap = cookieDecoder.decode(cookieString); - assertEquals(1, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = cookieDecoder.decode(cookieString); + assertEquals(1, cookies.size()); + Cookie cookie = cookies.iterator().next(); assertEquals("myValue", cookie.getValue()); assertNotNull(cookie); assertEquals("this is a comment", cookie.getComment()); @@ -100,9 +101,9 @@ public class CookieDecoderTest { public void testDecodingSingleCookieV1ExtraParamsIgnored() { String cookieString = "myCookie=myValue;max-age=50;path=/apathsomewhere;domain=.adomainsomewhere;secure;comment=this is a comment;version=1;commentURL=http://aurl.com;port=80,8080;discard;"; CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookieMap = cookieDecoder.decode(cookieString); - assertEquals(1, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = cookieDecoder.decode(cookieString); + assertEquals(1, cookies.size()); + Cookie cookie = cookies.iterator().next(); assertNotNull(cookie); assertEquals("myValue", cookie.getValue()); assertEquals("this is a comment", cookie.getComment()); @@ -119,9 +120,9 @@ public class CookieDecoderTest { public void testDecodingSingleCookieV2() { String cookieString = "myCookie=myValue;max-age=50;path=/apathsomewhere;domain=.adomainsomewhere;secure;comment=this is a comment;version=2;commentURL=http://aurl.com;port=\"80,8080\";discard;"; CookieDecoder cookieDecoder = new CookieDecoder(); - Map cookieMap = cookieDecoder.decode(cookieString); - assertEquals(1, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = cookieDecoder.decode(cookieString); + assertEquals(1, cookies.size()); + Cookie cookie = cookies.iterator().next(); assertNotNull(cookie); assertEquals("myValue", cookie.getValue()); assertEquals("this is a comment", cookie.getComment()); @@ -145,9 +146,10 @@ public class CookieDecoderTest { String c3 = "myCookie3=myValue3;max-age=0;version=2;"; CookieDecoder decoder = new CookieDecoder(); - Map cookieMap = decoder.decode(c1 + c2 + c3); - assertEquals(3, cookieMap.size()); - Cookie cookie = cookieMap.get("MyCookie"); + Set cookies = decoder.decode(c1 + c2 + c3); + assertEquals(3, cookies.size()); + Iterator it = cookies.iterator(); + Cookie cookie = it.next(); assertNotNull(cookie); assertEquals("myValue", cookie.getValue()); assertEquals("this is a comment", cookie.getComment()); @@ -161,7 +163,7 @@ public class CookieDecoderTest { assertTrue(cookie.getPorts().contains(8080)); assertTrue(cookie.isSecure()); assertEquals(2, cookie.getVersion()); - cookie = cookieMap.get("MyCookie2"); + cookie = it.next(); assertNotNull(cookie); assertEquals("myValue2", cookie.getValue()); assertEquals("this is another comment", cookie.getComment()); @@ -173,7 +175,7 @@ public class CookieDecoderTest { assertTrue(cookie.getPorts().isEmpty()); assertFalse(cookie.isSecure()); assertEquals(2, cookie.getVersion()); - cookie = cookieMap.get("MyCookie3"); + cookie = it.next(); assertNotNull(cookie); assertEquals("myValue3", cookie.getValue()); assertNull( cookie.getComment()); @@ -186,4 +188,38 @@ public class CookieDecoderTest { assertFalse(cookie.isSecure()); assertEquals(2, cookie.getVersion()); } + + @Test + public void testDecodingClientSideCookies() { + String source = "$Version=\"1\"; " + + "Part_Number=\"Riding_Rocket_0023\"; $Path=\"/acme/ammo\"; " + + "Part_Number=\"Rocket_Launcher_0001\"; $Path=\"/acme\""; + + Set cookies = new CookieDecoder().decode(source); + Iterator it = cookies.iterator(); + Cookie c; + + c = it.next(); + assertEquals(1, c.getVersion()); + assertEquals("Part_Number", c.getName()); + assertEquals("Rocket_Launcher_0001", c.getValue()); + assertEquals("/acme", c.getPath()); + assertNull(c.getComment()); + assertNull(c.getCommentUrl()); + assertNull(c.getDomain()); + assertTrue(c.getPorts().isEmpty()); + assertEquals(-1, c.getMaxAge()); + + c = it.next(); + assertEquals(1, c.getVersion()); + assertEquals("Part_Number", c.getName()); + assertEquals("Riding_Rocket_0023", c.getValue()); + assertEquals("/acme/ammo", c.getPath()); + assertNull(c.getComment()); + assertNull(c.getCommentUrl()); + assertNull(c.getDomain()); + assertTrue(c.getPorts().isEmpty()); + assertEquals(-1, c.getMaxAge()); + + } }