diff --git a/src/main/java/org/jboss/netty/handler/codec/http/CookieDateFormat.java b/src/main/java/org/jboss/netty/handler/codec/http/CookieDateFormat.java index 26589560f7..f58618c460 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/CookieDateFormat.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/CookieDateFormat.java @@ -19,6 +19,10 @@ import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; +/** + * @deprecated use {@link HttpHeaderDateFormat} + */ +@Deprecated final class CookieDateFormat extends SimpleDateFormat { private static final long serialVersionUID = 1789486337887402640L; 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 e8e884773d..c4eebf681b 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 @@ -132,7 +132,7 @@ public class CookieDecoder { } else if (CookieHeaderNames.EXPIRES.equalsIgnoreCase(name)) { try { long maxAgeMillis = - new CookieDateFormat().parse(value).getTime() - + new HttpHeaderDateFormat().parse(value).getTime() - System.currentTimeMillis(); maxAge = (int) (maxAgeMillis / 1000) + 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 fa6fd5a8c2..cb5b5e6c8a 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 @@ -110,7 +110,7 @@ public class CookieEncoder { if (cookie.getMaxAge() != Integer.MIN_VALUE) { if (cookie.getVersion() == 0) { addUnquoted(sb, CookieHeaderNames.EXPIRES, - new CookieDateFormat().format( + new HttpHeaderDateFormat().format( new Date(System.currentTimeMillis() + cookie.getMaxAge() * 1000L))); } else { diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormat.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormat.java new file mode 100644 index 0000000000..326932bf54 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormat.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.codec.http; + +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +/** + * This DateFormat decodes 3 formats of {@link Date}, but only encodes the one, + * the first: + * + */ +final class HttpHeaderDateFormat extends SimpleDateFormat { + private static final long serialVersionUID = -925286159755905325L; + + private final SimpleDateFormat format1 = new HttpHeaderDateFormatObsolete1(); + private final SimpleDateFormat format2 = new HttpHeaderDateFormatObsolete2(); + + /** + * Standard date format

+ * Sun, 06 Nov 1994 08:49:37 GMT -> E, d MMM yyyy HH:mm:ss z + */ + HttpHeaderDateFormat() { + super("E, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH); + setTimeZone(TimeZone.getTimeZone("GMT")); + } + + @Override + public Date parse(String text, ParsePosition pos) { + Date date = super.parse(text, pos); + if (date == null) { + date = format1.parse(text, pos); + } + if (date == null) { + date = format2.parse(text, pos); + } + return date; + } + + /** + * First obsolete format

+ * Sunday, 06-Nov-94 08:49:37 GMT -> E, d-MMM-y HH:mm:ss z + */ + private static final class HttpHeaderDateFormatObsolete1 extends SimpleDateFormat { + private static final long serialVersionUID = -3178072504225114298L; + + HttpHeaderDateFormatObsolete1() { + super("E, dd-MMM-yy HH:mm:ss z", Locale.ENGLISH); + setTimeZone(TimeZone.getTimeZone("GMT")); + } + } + + /** + * Second obsolete format + *

+ * Sun Nov 6 08:49:37 1994 -> EEE, MMM d HH:mm:ss yyyy + */ + private static final class HttpHeaderDateFormatObsolete2 extends SimpleDateFormat { + private static final long serialVersionUID = 3010674519968303714L; + + HttpHeaderDateFormatObsolete2() { + super("E MMM d HH:mm:ss yyyy", Locale.ENGLISH); + setTimeZone(TimeZone.getTimeZone("GMT")); + } + } +} 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 9ca9b727be..2179254995 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 @@ -27,7 +27,7 @@ public class CookieDecoderTest { @Test public void testDecodingSingleCookieV0() { String cookieString = "myCookie=myValue;expires=XXX;path=/apathsomewhere;domain=.adomainsomewhere;secure;"; - cookieString = cookieString.replace("XXX", new CookieDateFormat().format(new Date(System.currentTimeMillis() + 50000))); + cookieString = cookieString.replace("XXX", new HttpHeaderDateFormat().format(new Date(System.currentTimeMillis() + 50000))); CookieDecoder cookieDecoder = new CookieDecoder(); Set cookies = cookieDecoder.decode(cookieString); 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 69dc99d296..f919e1f834 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 @@ -26,7 +26,7 @@ public class CookieEncoderTest { @Test public void testEncodingSingleCookieV0() { String result = "myCookie=myValue; Expires=XXX; Path=/apathsomewhere; Domain=.adomainsomewhere; Secure"; - DateFormat df = new CookieDateFormat(); + DateFormat df = new HttpHeaderDateFormat(); Cookie cookie = new DefaultCookie("myCookie", "myValue"); CookieEncoder encoder = new CookieEncoder(true); encoder.addCookie(cookie); diff --git a/src/test/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormatTest.java b/src/test/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormatTest.java new file mode 100644 index 0000000000..67c453a905 --- /dev/null +++ b/src/test/java/org/jboss/netty/handler/codec/http/HttpHeaderDateFormatTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.codec.http; + +import java.text.ParseException; +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; + +public class HttpHeaderDateFormatTest { + /** + * This date is set at "06 Nov 1994 08:49:37 GMT" (same used in example in + * RFC documentation) + *

+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html + */ + private static final Date DATE = new Date(784111777000L); + + @Test + public void testParse() throws ParseException { + HttpHeaderDateFormat format = new HttpHeaderDateFormat(); + + final Date parsedDateWithSingleDigitDay = format.parse("Sun, 6 Nov 1994 08:49:37 GMT"); + Assert.assertNotNull(parsedDateWithSingleDigitDay); + Assert.assertEquals(DATE, parsedDateWithSingleDigitDay); + + final Date parsedDateWithDoubleDigitDay = format.parse("Sun, 06 Nov 1994 08:49:37 GMT"); + Assert.assertNotNull(parsedDateWithDoubleDigitDay); + Assert.assertEquals(DATE, parsedDateWithDoubleDigitDay); + + final Date parsedDateWithDashSeparatorSingleDigitDay = format.parse("Sunday, 06-Nov-94 08:49:37 GMT"); + Assert.assertNotNull(parsedDateWithDashSeparatorSingleDigitDay); + Assert.assertEquals(DATE, parsedDateWithDashSeparatorSingleDigitDay); + + final Date parsedDateWithSingleDoubleDigitDay = format.parse("Sunday, 6-Nov-94 08:49:37 GMT"); + Assert.assertNotNull(parsedDateWithSingleDoubleDigitDay); + Assert.assertEquals(DATE, parsedDateWithSingleDoubleDigitDay); + + final Date parsedDateWithoutGMT = format.parse("Sun Nov 6 08:49:37 1994"); + Assert.assertNotNull(parsedDateWithoutGMT); + Assert.assertEquals(DATE, parsedDateWithoutGMT); + } + + private Date parseDate(HttpHeaderDateFormat dateFormat, String dateStr) throws ParseException { + return dateFormat.parse(dateStr); + } + + @Test + public void testFormat() { + HttpHeaderDateFormat format = new HttpHeaderDateFormat(); + + final String formatted = format.format(DATE); + Assert.assertNotNull(formatted); + Assert.assertEquals("Sun, 06 Nov 1994 08:49:37 GMT", formatted); + } +} +