Skip to content

Commit ca2297b

Browse files
committed
Addressing date header bug reported in #122 and added basic unit tests
1 parent 4ae1230 commit ca2297b

File tree

3 files changed

+35
-12
lines changed

3 files changed

+35
-12
lines changed

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
import java.net.URLDecoder;
3333
import java.net.URLEncoder;
3434
import java.nio.charset.StandardCharsets;
35-
import java.security.Security;
35+
import java.time.format.DateTimeFormatter;
3636
import java.util.AbstractMap;
3737
import java.util.ArrayList;
3838
import java.util.Collections;
@@ -58,7 +58,7 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {
5858
static final String HEADER_VALUE_SEPARATOR = ";";
5959
static final String FORM_DATA_SEPARATOR = "&";
6060
static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";
61-
static final String HEADER_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss z";
61+
static final DateTimeFormatter dateFormatter = DateTimeFormatter.RFC_1123_DATE_TIME;
6262
static final String ENCODING_VALUE_KEY = "charset";
6363

6464
// We need this to pickup the protocol from the CloudFront header since Lambda doesn't receive this

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequest.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@
5353
import java.net.URLDecoder;
5454
import java.nio.charset.StandardCharsets;
5555
import java.security.Principal;
56-
import java.text.ParseException;
57-
import java.text.SimpleDateFormat;
56+
import java.time.Instant;
57+
import java.time.ZonedDateTime;
58+
import java.time.format.DateTimeParseException;
5859
import java.util.ArrayList;
5960
import java.util.Arrays;
6061
import java.util.Base64;
6162
import java.util.Collection;
6263
import java.util.Collections;
63-
import java.util.Date;
6464
import java.util.Enumeration;
6565
import java.util.HashMap;
6666
import java.util.Iterator;
@@ -133,16 +133,15 @@ public Cookie[] getCookies() {
133133

134134
@Override
135135
public long getDateHeader(String s) {
136-
String dateString = getHeaderCaseInsensitive(HttpHeaders.DATE);
136+
String dateString = getHeaderCaseInsensitive(s);
137137
if (dateString == null) {
138-
return new Date().getTime();
138+
return -1L;
139139
}
140-
SimpleDateFormat dateFormatter = new SimpleDateFormat(HEADER_DATE_FORMAT);
141140
try {
142-
return dateFormatter.parse(dateString).getTime();
143-
} catch (ParseException e) {
144-
log.error("Could not parse date header", e);
145-
return new Date().getTime();
141+
return Instant.from(ZonedDateTime.parse(dateString, dateFormatter)).toEpochMilli();
142+
} catch (DateTimeParseException e) {
143+
log.warn("Invalid date header in request" + SecurityUtils.crlf(dateString));
144+
return -1L;
146145
}
147146
}
148147

aws-serverless-java-container-core/src/test/java/com/amazonaws/serverless/proxy/internal/servlet/AwsProxyHttpServletRequestTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import javax.ws.rs.core.HttpHeaders;
1010
import javax.ws.rs.core.MediaType;
1111

12+
import java.time.Instant;
13+
import java.time.ZonedDateTime;
1214
import java.util.Collections;
1315
import java.util.List;
1416
import java.util.Map;
@@ -25,6 +27,7 @@ public class AwsProxyHttpServletRequestTest {
2527
private static final String REQUEST_SCHEME_HTTP = "http";
2628
private static final String USER_AGENT = "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0";
2729
private static final String REFERER = "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox";
30+
private static ZonedDateTime REQUEST_DATE = ZonedDateTime.now();
2831

2932
private static final AwsProxyRequest REQUEST_WITH_HEADERS = new AwsProxyRequestBuilder("/hello", "GET")
3033
.header(CUSTOM_HEADER_KEY, CUSTOM_HEADER_VALUE)
@@ -52,6 +55,10 @@ public class AwsProxyHttpServletRequestTest {
5255
.userAgent(USER_AGENT)
5356
.referer(REFERER).build();
5457

58+
private static final AwsProxyRequest REQUEST_WITH_DATE = new AwsProxyRequestBuilder("/hello", "GET")
59+
.header(HttpHeaders.DATE, AwsHttpServletRequest.dateFormatter.format(REQUEST_DATE))
60+
.build();
61+
5562
private static final AwsProxyRequest REQUEST_NULL_QUERY_STRING;
5663
static {
5764
AwsProxyRequest awsProxyRequest = new AwsProxyRequestBuilder("/hello", "GET").build();
@@ -113,6 +120,23 @@ public void formParams_getParameter_queryStringPrecendence() {
113120
assertEquals(QUERY_STRING_NAME_VALUE, request.getParameter(FORM_PARAM_NAME));
114121
}
115122

123+
@Test
124+
public void dateHeader_noDate_returnNegativeOne() {
125+
HttpServletRequest request = new AwsProxyHttpServletRequest(REQUEST_FORM_URLENCODED_AND_QUERY, null, null);
126+
assertNotNull(request);
127+
assertEquals(-1L, request.getDateHeader(HttpHeaders.DATE));
128+
}
129+
130+
@Test
131+
public void dateHeader_correctDate_parseToCorrectLong() {
132+
HttpServletRequest request = new AwsProxyHttpServletRequest(REQUEST_WITH_DATE, null, null);
133+
assertNotNull(request);
134+
135+
String instantString = AwsHttpServletRequest.dateFormatter.format(REQUEST_DATE);
136+
assertEquals(Instant.from(AwsHttpServletRequest.dateFormatter.parse(instantString)).toEpochMilli(), request.getDateHeader(HttpHeaders.DATE));
137+
assertEquals(-1L, request.getDateHeader(HttpHeaders.IF_MODIFIED_SINCE));
138+
}
139+
116140
@Test
117141
public void scheme_getScheme_https() {
118142
HttpServletRequest request = new AwsProxyHttpServletRequest(REQUEST_FORM_URLENCODED, null, null);

0 commit comments

Comments
 (0)