Restore 2 digit days format in HttpHeaders
As recommended by RFC 7231, this commit restore using 2 digit days when formatting dates while still using DateTimeFormatter.RFC_1123_DATE_TIME for parsing. Closes gh-22478
This commit is contained in:
parent
35010149f8
commit
d4714847a0
|
|
@ -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.
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +349,7 @@ public class MockHttpServletResponseTests {
|
|||
response.addCookie(mockCookie);
|
||||
|
||||
assertEquals("SESSION=123; Path=/; Domain=example.com; Max-Age=0; " +
|
||||
"Expires=Thu, 1 Jan 1970 00:00:00 GMT; Secure; HttpOnly; SameSite=Lax",
|
||||
"Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure; HttpOnly; SameSite=Lax",
|
||||
response.getHeader(HttpHeaders.SET_COOKIE));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -394,12 +394,18 @@ public class HttpHeaders implements MultiValueMap<String, String>, 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 <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section 7.1.1.1 of RFC 7231</a>
|
||||
*/
|
||||
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 <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section 7.1.1.1 of RFC 7231</a>
|
||||
*/
|
||||
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)
|
||||
};
|
||||
|
||||
|
|
@ -1322,7 +1328,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
* @since 5.0
|
||||
*/
|
||||
public void setZonedDateTime(String headerName, ZonedDateTime date) {
|
||||
set(headerName, DATE_FORMATTERS[0].format(date));
|
||||
set(headerName, DATE_FORMATTER.format(date));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1417,7 +1423,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
|
|||
headerValue = headerValue.substring(0, parametersIndex);
|
||||
}
|
||||
|
||||
for (DateTimeFormatter dateFormatter : DATE_FORMATTERS) {
|
||||
for (DateTimeFormatter dateFormatter : DATE_PARSERS) {
|
||||
try {
|
||||
return ZonedDateTime.parse(headerValue, dateFormatter);
|
||||
}
|
||||
|
|
@ -1733,7 +1739,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -38,7 +37,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.*;
|
||||
|
||||
|
|
@ -299,11 +297,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");
|
||||
|
|
@ -503,37 +496,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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -59,10 +59,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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -180,7 +180,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"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue