diff --git a/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java b/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java index e0e07ba921..4fb14f3747 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/Cookie.java @@ -21,6 +21,8 @@ */ package org.jboss.netty.handler.codec.http; +import java.util.Set; + /** * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (tlee@redhat.com) @@ -46,6 +48,7 @@ public interface Cookie extends Comparable { void setCommentURL(String commentURL); boolean isDiscard(); void setDiscard(boolean discard); - int[] getPortList(); - void setPortList(int... portList); + Set getPorts(); + void setPorts(int... ports); + void setPorts(Iterable ports); } \ No newline at end of file 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 7eac19b6b9..ed838cef8b 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 @@ -21,11 +21,11 @@ */ package org.jboss.netty.handler.codec.http; -import org.jboss.netty.util.CaseIgnoringComparator; - import java.util.Map; import java.util.TreeMap; +import org.jboss.netty.util.CaseIgnoringComparator; + /** * @author The Netty Project (netty-dev@lists.jboss.org) * @author Andy Taylor (andy.taylor@jboss.org) @@ -73,17 +73,22 @@ public class CookieDecoder { int version = 0; int maxAge = 0; int[] ports = null; + loop: for (int j = i + 1; j < split.length; j++, i++) { String[] val = split[j].split(EQUALS, 2); - if (val != null && val.length == 1) { + if (val == null) { + continue; + } + switch (val.length) { + case 1: if (CookieHeaderNames.DISCARD.equalsIgnoreCase(val[0])) { discard = true; } else if (CookieHeaderNames.SECURE.equalsIgnoreCase(val[0])) { secure = true; } - } - else if (val != null && val.length == 2) { + break; + case 2: name = val[0].trim(); value = val[1].trim(); if (CookieHeaderNames.COMMENT.equalsIgnoreCase(name)) { @@ -107,17 +112,17 @@ public class CookieDecoder { else if (CookieHeaderNames.VERSION.equalsIgnoreCase(name)) { version = Integer.valueOf(value); } - else if (CookieHeaderNames.PORTLIST.equalsIgnoreCase(name)) { + else if (CookieHeaderNames.PORT.equalsIgnoreCase(name)) { String[] portList = value.split(COMMA); ports = new int[portList.length]; for (int i1 = 0; i1 < portList.length; i1++) { String s1 = portList[i1]; ports[i1] = Integer.valueOf(s1); } + } else { + break loop; } - else { - break; - } + break; } } theCookie.setVersion(version); @@ -130,11 +135,12 @@ public class CookieDecoder { } if (version > 1) { theCookie.setCommentURL(commentURL); - theCookie.setPortList(ports); + if (ports != null) { + theCookie.setPorts(ports); + } theCookie.setDiscard(discard); } } - } return cookies; } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/CookieEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/CookieEncoder.java index 7e3d3a5b8d..0443b7dd03 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/CookieEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/CookieEncoder.java @@ -21,12 +21,12 @@ */ package org.jboss.netty.handler.codec.http; -import org.jboss.netty.util.CaseIgnoringComparator; - import java.util.Collection; import java.util.Map; import java.util.TreeMap; +import org.jboss.netty.util.CaseIgnoringComparator; + /** * @author The Netty Project (netty-dev@lists.jboss.org) * @author Andy Taylor (andy.taylor@jboss.org) @@ -106,16 +106,14 @@ public class CookieEncoder { if (cookie.getCommentURL() != null) { add(sb, CookieHeaderNames.COMMENTURL, QueryStringEncoder.encodeComponent(cookie.getCommentURL(), charset)); } - if(cookie.getPortList() != null && cookie.getPortList().length > 0) { - sb.append(CookieHeaderNames.PORTLIST); + if(!cookie.getPorts().isEmpty()) { + sb.append(CookieHeaderNames.PORT); sb.append((char) HttpCodecUtil.EQUALS); - for (int i = 0; i < cookie.getPortList().length; i++) { - int port = cookie.getPortList()[i]; - if(i > 0) { - sb.append((char)HttpCodecUtil.COMMA); - } + for (int port: cookie.getPorts()) { sb.append(port); + sb.append((char) HttpCodecUtil.COMMA); } + sb.setLength(sb.length() - 1); // Remove the trailing comma. sb.append((char) HttpCodecUtil.SEMICOLON); } if (cookie.isDiscard()) { diff --git a/src/main/java/org/jboss/netty/handler/codec/http/CookieHeaderNames.java b/src/main/java/org/jboss/netty/handler/codec/http/CookieHeaderNames.java index 4c3aab8c50..e2d7689fc5 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/CookieHeaderNames.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/CookieHeaderNames.java @@ -41,7 +41,7 @@ public class CookieHeaderNames { public static final String DISCARD = "discard"; - public static final String PORTLIST = "port"; + public static final String PORT = "port"; public static final String VERSION = "version"; diff --git a/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java b/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java index fcd4302678..00df04a5bf 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/DefaultCookie.java @@ -21,6 +21,10 @@ */ package org.jboss.netty.handler.codec.http; +import java.util.Collections; +import java.util.Set; +import java.util.TreeSet; + /** * @author The Netty Project (netty-dev@lists.jboss.org) @@ -37,7 +41,8 @@ public class DefaultCookie implements Cookie { private String comment; private String commentURL; private boolean discard; - private int[] portList; + private Set ports = Collections.emptySet(); + private Set unmodifiablePorts = ports; private int maxAge; private int version; private boolean secure; @@ -127,21 +132,48 @@ public class DefaultCookie implements Cookie { this.discard = discard; } - public int[] getPortList() { - return portList.clone(); + public Set getPorts() { + if (unmodifiablePorts == null) { + unmodifiablePorts = Collections.unmodifiableSet(ports); + } + return unmodifiablePorts; } - public void setPortList(int... portList) { - if (portList == null) { - throw new NullPointerException("portList"); + public void setPorts(int... ports) { + if (ports == null) { + throw new NullPointerException("ports"); } - int[] portListCopy = portList.clone(); - for (int p: portListCopy) { + + int[] portsCopy = ports.clone(); + if (portsCopy.length == 0) { + unmodifiablePorts = this.ports = Collections.emptySet(); + } else { + Set newPorts = new TreeSet(); + for (int p: portsCopy) { + if (p <= 0 || p > 65535) { + throw new IllegalArgumentException("port out of range: " + p); + } + newPorts.add(Integer.valueOf(p)); + } + this.ports = newPorts; + unmodifiablePorts = null; + } + } + + public void setPorts(Iterable ports) { + Set newPorts = new TreeSet(); + for (int p: ports) { if (p <= 0 || p > 65535) { throw new IllegalArgumentException("port out of range: " + p); } + newPorts.add(Integer.valueOf(p)); + } + if (newPorts.isEmpty()) { + unmodifiablePorts = this.ports = Collections.emptySet(); + } else { + this.ports = newPorts; + unmodifiablePorts = null; } - this.portList = portListCopy; } public int getMaxAge() { 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 067b5e1f32..ae5478cc41 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 @@ -21,15 +21,12 @@ */ package org.jboss.netty.handler.codec.http; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import org.junit.Test; +import static org.junit.Assert.*; import java.util.Map; +import org.junit.Test; + /** * @author Andy Taylor */ @@ -49,7 +46,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertTrue(cookie.isSecure()); assertEquals(0, cookie.getVersion()); } @@ -69,7 +66,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertTrue(cookie.isSecure()); assertEquals(0, cookie.getVersion()); } @@ -88,7 +85,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertTrue(cookie.isSecure()); assertEquals(1, cookie.getVersion()); } @@ -108,7 +105,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertTrue(cookie.isSecure()); assertEquals(1, cookie.getVersion()); } @@ -127,10 +124,9 @@ public class CookieDecoderTest { assertTrue(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNotNull(cookie.getPortList()); - assertEquals(2, cookie.getPortList().length); - assertEquals(80, cookie.getPortList()[0]); - assertEquals(8080, cookie.getPortList()[1]); + assertEquals(2, cookie.getPorts().size()); + assertTrue(cookie.getPorts().contains(80)); + assertTrue(cookie.getPorts().contains(8080)); assertTrue(cookie.isSecure()); assertEquals(2, cookie.getVersion()); } @@ -154,10 +150,9 @@ public class CookieDecoderTest { assertTrue(cookie.isDiscard()); assertEquals(50, cookie.getMaxAge()); assertEquals("/apathsomewhere", cookie.getPath()); - assertNotNull(cookie.getPortList()); - assertEquals(2, cookie.getPortList().length); - assertEquals(80, cookie.getPortList()[0]); - assertEquals(8080, cookie.getPortList()[1]); + assertEquals(2, cookie.getPorts().size()); + assertTrue(cookie.getPorts().contains(80)); + assertTrue(cookie.getPorts().contains(8080)); assertTrue(cookie.isSecure()); assertEquals(2, cookie.getVersion()); cookie = cookieMap.get("MyCookie2"); @@ -169,7 +164,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(0, cookie.getMaxAge()); assertEquals("/anotherpathsomewhere", cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertFalse(cookie.isSecure()); assertEquals(2, cookie.getVersion()); cookie = cookieMap.get("MyCookie3"); @@ -181,7 +176,7 @@ public class CookieDecoderTest { assertFalse(cookie.isDiscard()); assertEquals(0, cookie.getMaxAge()); assertNull(cookie.getPath()); - assertNull(cookie.getPortList()); + assertTrue(cookie.getPorts().isEmpty()); assertFalse(cookie.isSecure()); assertEquals(2, cookie.getVersion()); } diff --git a/src/test/java/org/jboss/netty/handler/codec/http/CookieEncoderTest.java b/src/test/java/org/jboss/netty/handler/codec/http/CookieEncoderTest.java index 1005cf82d7..0637be9542 100644 --- a/src/test/java/org/jboss/netty/handler/codec/http/CookieEncoderTest.java +++ b/src/test/java/org/jboss/netty/handler/codec/http/CookieEncoderTest.java @@ -21,7 +21,8 @@ */ package org.jboss.netty.handler.codec.http; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; + import org.junit.Test; @@ -41,7 +42,7 @@ public class CookieEncoderTest { cookie.setDiscard(true); cookie.setMaxAge(50); cookie.setPath("/apathsomewhere"); - cookie.setPortList(new int[]{80, 8080}); + cookie.setPorts(80, 8080); cookie.setSecure(true); String encodedCookie = encoder.encode(); assertEquals(result, encodedCookie); @@ -58,7 +59,7 @@ public class CookieEncoderTest { cookie.setDiscard(true); cookie.setMaxAge(50); cookie.setPath("/apathsomewhere"); - cookie.setPortList(new int[]{80, 8080}); + cookie.setPorts(80, 8080); cookie.setSecure(true); String encodedCookie = encoder.encode(); assertEquals(result, encodedCookie); @@ -75,7 +76,7 @@ public class CookieEncoderTest { cookie.setDiscard(true); cookie.setMaxAge(50); cookie.setPath("/apathsomewhere"); - cookie.setPortList(new int[]{80, 8080}); + cookie.setPorts(80, 8080); cookie.setSecure(true); String encodedCookie = encoder.encode(); assertEquals(result, encodedCookie); @@ -94,7 +95,7 @@ public class CookieEncoderTest { cookie.setDiscard(true); cookie.setMaxAge(50); cookie.setPath("/apathsomewhere"); - cookie.setPortList(new int[]{80, 8080}); + cookie.setPorts(80, 8080); cookie.setSecure(true); encoder.addCookie(cookie); Cookie cookie2 = new DefaultCookie("myCookie2", "myValue2");