Fix HTTP module for proper RFC date formats

* Copy data format algorithm from the Spring Web `HttpHeaders` into the
`DefaultHttpHeaderMapper`
* Fix `HttpProxyScenarioTests` for proper zoned date formatting
This commit is contained in:
Artem Bilan
2017-11-01 12:44:47 -04:00
committed by Gary Russell
parent d9f7efe9c9
commit d76af8c2aa
2 changed files with 25 additions and 15 deletions

View File

@@ -257,11 +257,14 @@ public class DefaultHttpHeaderMapper implements HeaderMapper<HttpHeaders>, BeanF
public static final String HTTP_RESPONSE_HEADER_NAME_PATTERN = "HTTP_RESPONSE_HEADERS";
// Copy of 'org.springframework.http.HttpHeaders#GMT'
private static final ZoneId GMT = ZoneId.of("GMT");
// Copy of 'org.springframework.http.HttpHeaders#DATE_FORMATS'
protected static final DateTimeFormatter[] DATE_FORMATS = new DateTimeFormatter[] {
DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).withZone(ZoneId.of("GMT")),
DateTimeFormatter.ofPattern("EEE, dd-MMM-yy HH:mm:ss zzz", Locale.US).withZone(ZoneId.of("GMT")),
DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy", Locale.US).withZone(ZoneId.of("GMT"))
DateTimeFormatter.RFC_1123_DATE_TIME,
DateTimeFormatter.ofPattern("EEEE, dd-MMM-yy HH:mm:ss zz", Locale.US),
DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy", Locale.US).withZone(GMT)
};
static {
@@ -1069,22 +1072,25 @@ public class DefaultHttpHeaderMapper implements HeaderMapper<HttpHeaders>, BeanF
// Utility methods
protected long getFirstDate(String headerValue, String headerName) {
for (DateTimeFormatter dateFormat : DATE_FORMATS) {
for (DateTimeFormatter dateFormatter : DATE_FORMATS) {
try {
return dateFormat.parse(headerValue, ZonedDateTime::from)
return ZonedDateTime.parse(headerValue, dateFormatter)
.toInstant()
.toEpochMilli();
}
catch (DateTimeParseException e) {
catch (DateTimeParseException ex) {
// ignore
}
}
throw new IllegalArgumentException("Cannot parse date value '" + headerValue + "' for '" + headerName
+ "' header");
}
protected String formatDate(long date) {
return DATE_FORMATS[0].format(Instant.ofEpochMilli(date));
Instant instant = Instant.ofEpochMilli(date);
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, GMT);
return DATE_FORMATS[0].format(zonedDateTime);
}
/**

View File

@@ -23,11 +23,11 @@ import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.isNull;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -89,18 +89,22 @@ public class HttpProxyScenarioTests {
@Test
public void testHttpProxyScenario() throws Exception {
DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.RFC_1123_DATE_TIME;
ZoneId GMT = ZoneId.of("GMT");
Calendar c = Calendar.getInstance();
c.set(Calendar.MILLISECOND, 0);
final long ifModifiedSince = c.getTimeInMillis();
String ifModifiedSinceValue = dateFormat.format(ifModifiedSince);
Instant instant = Instant.ofEpochMilli(ifModifiedSince);
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, GMT);
String ifModifiedSinceValue = dateTimeFormatter.format(zonedDateTime);
c.add(Calendar.DATE, -1);
long ifUnmodifiedSince = c.getTimeInMillis();
final String ifUnmodifiedSinceValue = dateFormat.format(ifUnmodifiedSince);
instant = Instant.ofEpochMilli(ifUnmodifiedSince);
zonedDateTime = ZonedDateTime.ofInstant(instant, GMT);
final String ifUnmodifiedSinceValue = dateTimeFormatter.format(zonedDateTime);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test");
request.setQueryString("foo=bar&FOO=BAR");