diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java index 0b5ca7eaaf8..c8bad52b04f 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockHttpServletResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -169,7 +169,7 @@ public class MockHttpServletResponseTests { response.addCookie(cookie); assertEquals("foo=bar; Path=/path; Domain=example.com; " + - "Max-Age=0; Expires=Thu, 1 Jan 1970 00:00:00 GMT; " + + "Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; " + "Secure; HttpOnly", response.getHeader(HttpHeaders.SET_COOKIE)); } diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 97638b75fcd..c959ebf7800 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -391,12 +391,18 @@ public class HttpHeaders implements MultiValueMap, Serializable private static final ZoneId GMT = ZoneId.of("GMT"); /** - * Date formats with time zone as specified in the HTTP RFC. + * Date formats with time zone as specified in the HTTP RFC to use for formatting. * @see Section 7.1.1.1 of RFC 7231 */ - private static final DateTimeFormatter[] DATE_FORMATTERS = new DateTimeFormatter[] { + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).withZone(GMT); + + /** + * Date formats with time zone as specified in the HTTP RFC to use for parsing. + * @see Section 7.1.1.1 of RFC 7231 + */ + private static final DateTimeFormatter[] DATE_PARSERS = new DateTimeFormatter[] { DateTimeFormatter.RFC_1123_DATE_TIME, - DateTimeFormatter.ofPattern("EEEE, dd-MMM-yy HH:mm:ss zz", Locale.US), + DateTimeFormatter.ofPattern("EEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy", Locale.US).withZone(GMT) }; @@ -1211,7 +1217,7 @@ public class HttpHeaders implements MultiValueMap, Serializable * @since 5.0 */ public void setZonedDateTime(String headerName, ZonedDateTime date) { - set(headerName, DATE_FORMATTERS[0].format(date)); + set(headerName, DATE_FORMATTER.format(date)); } /** @@ -1296,7 +1302,7 @@ public class HttpHeaders implements MultiValueMap, Serializable headerValue = headerValue.substring(0, parametersIndex); } - for (DateTimeFormatter dateFormatter : DATE_FORMATTERS) { + for (DateTimeFormatter dateFormatter : DATE_PARSERS) { try { return ZonedDateTime.parse(headerValue, dateFormatter); } @@ -1562,7 +1568,7 @@ public class HttpHeaders implements MultiValueMap, Serializable static String formatDate(long date) { Instant instant = Instant.ofEpochMilli(date); ZonedDateTime time = ZonedDateTime.ofInstant(instant, GMT); - return DATE_FORMATTERS[0].format(time); + return DATE_FORMATTER.format(time); } } diff --git a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java index 763967f24fd..1931265ddf5 100644 --- a/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java +++ b/spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.time.DateTimeException; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; @@ -37,7 +36,6 @@ import java.util.TimeZone; import org.hamcrest.Matchers; import org.junit.Test; -import static java.time.format.DateTimeFormatter.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; @@ -298,11 +296,6 @@ public class HttpHeadersTests { assertEquals("Invalid Expires header", "Thu, 18 Dec 2008 10:20:00 GMT", headers.getFirst("expires")); } - @Test(expected = DateTimeException.class) // SPR-16560 - public void expiresLargeDate() { - headers.setExpires(Long.MAX_VALUE); - } - @Test // SPR-10648 (example is from INT-3063) public void expiresInvalidDate() { headers.set("Expires", "-1"); @@ -495,37 +488,37 @@ public class HttpHeadersTests { @Test public void firstDate() { - headers.setDate(HttpHeaders.DATE, 1229595600000L); - assertThat(headers.getFirstDate(HttpHeaders.DATE), is(1229595600000L)); + headers.setDate(HttpHeaders.DATE, 1496370120000L); + assertThat(headers.getFirstDate(HttpHeaders.DATE), is(1496370120000L)); headers.clear(); - headers.add(HttpHeaders.DATE, "Thu, 18 Dec 2008 10:20:00 GMT"); + headers.add(HttpHeaders.DATE, "Fri, 02 Jun 2017 02:22:00 GMT"); headers.add(HttpHeaders.DATE, "Sat, 18 Dec 2010 10:20:00 GMT"); - assertThat(headers.getFirstDate(HttpHeaders.DATE), is(1229595600000L)); + assertThat(headers.getFirstDate(HttpHeaders.DATE), is(1496370120000L)); } @Test public void firstZonedDateTime() { - ZonedDateTime date = ZonedDateTime.of(2017, 6, 22, 22, 22, 0, 0, ZoneId.of("GMT")); + ZonedDateTime date = ZonedDateTime.of(2017, 6, 2, 2, 22, 0, 0, ZoneId.of("GMT")); headers.setZonedDateTime(HttpHeaders.DATE, date); - assertThat(headers.getFirst(HttpHeaders.DATE), is("Thu, 22 Jun 2017 22:22:00 GMT")); + assertThat(headers.getFirst(HttpHeaders.DATE), is("Fri, 02 Jun 2017 02:22:00 GMT")); assertTrue(headers.getFirstZonedDateTime(HttpHeaders.DATE).isEqual(date)); headers.clear(); ZonedDateTime otherDate = ZonedDateTime.of(2010, 12, 18, 10, 20, 0, 0, ZoneId.of("GMT")); - headers.add(HttpHeaders.DATE, RFC_1123_DATE_TIME.format(date)); - headers.add(HttpHeaders.DATE, RFC_1123_DATE_TIME.format(otherDate)); + headers.add(HttpHeaders.DATE, "Fri, 02 Jun 2017 02:22:00 GMT"); + headers.add(HttpHeaders.DATE, "Sat, 18 Dec 2010 10:20:00 GMT"); assertTrue(headers.getFirstZonedDateTime(HttpHeaders.DATE).isEqual(date)); // obsolete RFC 850 format headers.clear(); - headers.set(HttpHeaders.DATE, "Thursday, 22-Jun-17 22:22:00 GMT"); + headers.set(HttpHeaders.DATE, "Friday, 02-Jun-17 02:22:00 GMT"); assertTrue(headers.getFirstZonedDateTime(HttpHeaders.DATE).isEqual(date)); // ANSI C's asctime() format headers.clear(); - headers.set(HttpHeaders.DATE, "Thu Jun 22 22:22:00 2017"); + headers.set(HttpHeaders.DATE, "Fri Jun 02 02:22:00 2017"); assertTrue(headers.getFirstZonedDateTime(HttpHeaders.DATE).isEqual(date)); } diff --git a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java index 82bd43cdeda..87564ba752f 100644 --- a/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/RequestEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,7 +115,7 @@ public class RequestEntityTests { assertEquals("text/plain", responseHeaders.getFirst("Accept")); assertEquals("utf-8", responseHeaders.getFirst("Accept-Charset")); - assertEquals("Thu, 1 Jan 1970 00:00:12 GMT", responseHeaders.getFirst("If-Modified-Since")); + assertEquals("Thu, 01 Jan 1970 00:00:12 GMT", responseHeaders.getFirst("If-Modified-Since")); assertEquals(ifNoneMatch, responseHeaders.getFirst("If-None-Match")); assertEquals(String.valueOf(contentLength), responseHeaders.getFirst("Content-Length")); assertEquals(contentType.toString(), responseHeaders.getFirst("Content-Type")); diff --git a/spring-web/src/test/java/org/springframework/http/ResponseCookieTests.java b/spring-web/src/test/java/org/springframework/http/ResponseCookieTests.java index d088d96b1f7..6c1752ca333 100644 --- a/spring-web/src/test/java/org/springframework/http/ResponseCookieTests.java +++ b/spring-web/src/test/java/org/springframework/http/ResponseCookieTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,10 +62,10 @@ public class ResponseCookieTests { @Test public void maxAge0() { - assertEquals("id=1fWa; Max-Age=0; Expires=Thu, 1 Jan 1970 00:00:00 GMT", + assertEquals("id=1fWa; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT", ResponseCookie.from("id", "1fWa").maxAge(Duration.ofSeconds(0)).build().toString()); - assertEquals("id=1fWa; Max-Age=0; Expires=Thu, 1 Jan 1970 00:00:00 GMT", + assertEquals("id=1fWa; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT", ResponseCookie.from("id", "1fWa").maxAge(0).build().toString()); } diff --git a/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java b/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java index 07ef76f89ba..94fb64fbbc8 100644 --- a/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java +++ b/spring-web/src/test/java/org/springframework/http/ResponseEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -160,7 +160,7 @@ public class ResponseEntityTests { HttpHeaders responseHeaders = responseEntity.getHeaders(); assertEquals("GET", responseHeaders.getFirst("Allow")); - assertEquals("Thu, 1 Jan 1970 00:00:12 GMT", + assertEquals("Thu, 01 Jan 1970 00:00:12 GMT", responseHeaders.getFirst("Last-Modified")); assertEquals(location.toASCIIString(), responseHeaders.getFirst("Location"));