Skip to content

Commit 269a327

Browse files
committed
Merge branch 'main' into 976-query-params-not-urldecoded
2 parents 1785eb5 + 24908a1 commit 269a327

File tree

62 files changed

+233
-2670
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+233
-2670
lines changed

.github/dependabot.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ updates:
1818
slf4j:
1919
patterns:
2020
- "org.slf4j:*"
21+
jackson:
22+
patterns:
23+
- "com.fasterxml.jackson.*:*"
2124
log4j:
2225
patterns:
2326
- "org.apache.logging.log4j:*"
@@ -36,7 +39,7 @@ updates:
3639
groups:
3740
jersey:
3841
patterns:
39-
- "org.glassfish.jersey:*"
42+
- "org.glassfish.jersey.*:*"
4043
spring:
4144
patterns:
4245
- "org.springframework:*"
@@ -46,5 +49,8 @@ updates:
4649
log4j:
4750
patterns:
4851
- "org.apache.logging.log4j:*"
52+
jackson:
53+
patterns:
54+
- "com.fasterxml.jackson.*:*"
4955
schedule:
5056
interval: "weekly"

.github/workflows/continuous-integration-workflow.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ jobs:
7979
run: ./gha_build.sh springboot3 false false -Dspringboot.version=3.1.12 -Dspring.version=6.0.21 -Dspringsecurity.version=6.1.9 -Ddependency-check.skip=true
8080
- name: Build with Spring Boot 3.2.x
8181
run: ./gha_build.sh springboot3 false false -Dspringboot.version=3.2.7 -Dspring.version=6.1.10 -Dspringsecurity.version=6.2.5 -Ddependency-check.skip=true
82+
- name: Build with Spring Boot 3.3.x
83+
run: ./gha_build.sh springboot3 false false -Dspringboot.version=3.3.6 -Dspring.version=6.1.15 -Dspringsecurity.version=6.3.5 -Ddependency-check.skip=true
8284

8385
# temporarily disabled as Struts is not released at the moment
8486
# build_struts2:

aws-serverless-java-container-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
<dependency>
6161
<groupId>org.springframework.security</groupId>
6262
<artifactId>spring-security-web</artifactId>
63-
<version>6.3.4</version>
63+
<version>6.4.1</version>
6464
<scope>test</scope>
6565
</dependency>
6666
</dependencies>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.amazonaws.serverless.proxy.internal;
2+
3+
import org.apache.commons.io.Charsets;
4+
5+
import java.nio.charset.Charset;
6+
import java.nio.charset.StandardCharsets;
7+
import java.nio.charset.UnsupportedCharsetException;
8+
9+
public final class HttpUtils {
10+
11+
static final String HEADER_KEY_VALUE_SEPARATOR = "=";
12+
static final String HEADER_VALUE_SEPARATOR = ";";
13+
static final String ENCODING_VALUE_KEY = "charset";
14+
15+
16+
static public Charset parseCharacterEncoding(String contentTypeHeader,Charset defaultCharset) {
17+
// we only look at content-type because content-encoding should only be used for
18+
// "binary" requests such as gzip/deflate.
19+
if (contentTypeHeader == null) {
20+
return defaultCharset;
21+
}
22+
23+
String[] contentTypeValues = contentTypeHeader.split(HEADER_VALUE_SEPARATOR);
24+
if (contentTypeValues.length <= 1) {
25+
return defaultCharset;
26+
}
27+
28+
for (String contentTypeValue : contentTypeValues) {
29+
if (contentTypeValue.trim().startsWith(ENCODING_VALUE_KEY)) {
30+
String[] encodingValues = contentTypeValue.split(HEADER_KEY_VALUE_SEPARATOR);
31+
if (encodingValues.length <= 1) {
32+
return defaultCharset;
33+
}
34+
try {
35+
return Charsets.toCharset(encodingValues[1]);
36+
} catch (UnsupportedCharsetException ex) {
37+
return defaultCharset;
38+
}
39+
}
40+
}
41+
return defaultCharset;
42+
}
43+
44+
45+
static public String appendCharacterEncoding(String currentContentType, String newEncoding) {
46+
if (currentContentType == null || currentContentType.trim().isEmpty()) {
47+
return null;
48+
}
49+
50+
if (currentContentType.contains(HEADER_VALUE_SEPARATOR)) {
51+
String[] contentTypeValues = currentContentType.split(HEADER_VALUE_SEPARATOR);
52+
StringBuilder contentType = new StringBuilder(contentTypeValues[0]);
53+
54+
for (int i = 1; i < contentTypeValues.length; i++) {
55+
String contentTypeValue = contentTypeValues[i];
56+
String contentTypeString = HEADER_VALUE_SEPARATOR + " " + contentTypeValue;
57+
if (contentTypeValue.trim().startsWith(ENCODING_VALUE_KEY)) {
58+
contentTypeString = HEADER_VALUE_SEPARATOR + " " + ENCODING_VALUE_KEY + HEADER_KEY_VALUE_SEPARATOR + newEncoding;
59+
}
60+
contentType.append(contentTypeString);
61+
}
62+
63+
return contentType.toString();
64+
} else {
65+
return currentContentType + HEADER_VALUE_SEPARATOR + " " + ENCODING_VALUE_KEY + HEADER_KEY_VALUE_SEPARATOR + newEncoding;
66+
}
67+
}
68+
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313
package com.amazonaws.serverless.proxy.internal.servlet;
1414

15+
import com.amazonaws.serverless.proxy.internal.HttpUtils;
1516
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
1617
import com.amazonaws.serverless.proxy.internal.SecurityUtils;
1718
import com.amazonaws.serverless.proxy.model.ContainerConfig;
@@ -32,6 +33,7 @@
3233
import java.io.StringReader;
3334
import java.io.UnsupportedEncodingException;
3435
import java.net.URLDecoder;
36+
import java.nio.charset.Charset;
3537
import java.security.Principal;
3638
import java.time.Instant;
3739
import java.time.ZonedDateTime;
@@ -232,7 +234,8 @@ public String getCharacterEncoding() {
232234
if (headers == null) {
233235
return config.getDefaultContentCharset();
234236
}
235-
return parseCharacterEncoding(headers.getFirst(HttpHeaders.CONTENT_TYPE));
237+
Charset charset = HttpUtils.parseCharacterEncoding(headers.getFirst(HttpHeaders.CONTENT_TYPE),null);
238+
return charset != null ? charset.name() : null;
236239
}
237240

238241
@Override
@@ -242,7 +245,7 @@ public void setCharacterEncoding(String s) throws UnsupportedEncodingException {
242245
return;
243246
}
244247
String currentContentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
245-
headers.putSingle(HttpHeaders.CONTENT_TYPE, appendCharacterEncoding(currentContentType, s));
248+
headers.putSingle(HttpHeaders.CONTENT_TYPE, HttpUtils.appendCharacterEncoding(currentContentType, s));
246249
}
247250

248251
@Override

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

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -369,53 +369,9 @@ protected StringBuffer generateRequestURL(String requestPath) {
369369
return new StringBuffer(getScheme() + "://" + url);
370370
}
371371

372-
protected String parseCharacterEncoding(String contentTypeHeader) {
373-
// we only look at content-type because content-encoding should only be used for
374-
// "binary" requests such as gzip/deflate.
375-
if (contentTypeHeader == null) {
376-
return null;
377-
}
378372

379-
String[] contentTypeValues = contentTypeHeader.split(HEADER_VALUE_SEPARATOR);
380-
if (contentTypeValues.length <= 1) {
381-
return null;
382-
}
383373

384-
for (String contentTypeValue : contentTypeValues) {
385-
if (contentTypeValue.trim().startsWith(ENCODING_VALUE_KEY)) {
386-
String[] encodingValues = contentTypeValue.split(HEADER_KEY_VALUE_SEPARATOR);
387-
if (encodingValues.length <= 1) {
388-
return null;
389-
}
390-
return encodingValues[1];
391-
}
392-
}
393-
return null;
394-
}
395374

396-
protected String appendCharacterEncoding(String currentContentType, String newEncoding) {
397-
if (currentContentType == null || currentContentType.trim().isEmpty()) {
398-
return null;
399-
}
400-
401-
if (currentContentType.contains(HEADER_VALUE_SEPARATOR)) {
402-
String[] contentTypeValues = currentContentType.split(HEADER_VALUE_SEPARATOR);
403-
StringBuilder contentType = new StringBuilder(contentTypeValues[0]);
404-
405-
for (int i = 1; i < contentTypeValues.length; i++) {
406-
String contentTypeValue = contentTypeValues[i];
407-
String contentTypeString = HEADER_VALUE_SEPARATOR + " " + contentTypeValue;
408-
if (contentTypeValue.trim().startsWith(ENCODING_VALUE_KEY)) {
409-
contentTypeString = HEADER_VALUE_SEPARATOR + " " + ENCODING_VALUE_KEY + HEADER_KEY_VALUE_SEPARATOR + newEncoding;
410-
}
411-
contentType.append(contentTypeString);
412-
}
413-
414-
return contentType.toString();
415-
} else {
416-
return currentContentType + HEADER_VALUE_SEPARATOR + " " + ENCODING_VALUE_KEY + HEADER_KEY_VALUE_SEPARATOR + newEncoding;
417-
}
418-
}
419375

420376
protected ServletInputStream bodyStringToInputStream(String body, boolean isBase64Encoded) throws IOException {
421377
if (body == null) {

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package com.amazonaws.serverless.proxy.internal.servlet;
1414

1515

16+
import com.amazonaws.serverless.proxy.internal.HttpUtils;
1617
import com.amazonaws.serverless.proxy.internal.LambdaContainerHandler;
1718
import com.amazonaws.serverless.proxy.internal.SecurityUtils;
1819
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
@@ -35,6 +36,7 @@
3536
import java.io.IOException;
3637
import java.io.StringReader;
3738
import java.io.UnsupportedEncodingException;
39+
import java.nio.charset.Charset;
3840
import java.security.Principal;
3941
import java.time.Instant;
4042
import java.time.ZonedDateTime;
@@ -273,7 +275,8 @@ public String getCharacterEncoding() {
273275
if (request.getMultiValueHeaders() == null) {
274276
return config.getDefaultContentCharset();
275277
}
276-
return parseCharacterEncoding(request.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE));
278+
Charset charset = HttpUtils.parseCharacterEncoding(request.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE),null);
279+
return charset != null ? charset.name() : null;
277280
}
278281

279282

@@ -284,12 +287,12 @@ public void setCharacterEncoding(String s)
284287
request.setMultiValueHeaders(new Headers());
285288
}
286289
String currentContentType = request.getMultiValueHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
287-
if (currentContentType == null || "".equals(currentContentType)) {
290+
if (currentContentType == null || currentContentType.isEmpty()) {
288291
log.debug("Called set character encoding to " + SecurityUtils.crlf(s) + " on a request without a content type. Character encoding will not be set");
289292
return;
290293
}
291294

292-
request.getMultiValueHeaders().putSingle(HttpHeaders.CONTENT_TYPE, appendCharacterEncoding(currentContentType, s));
295+
request.getMultiValueHeaders().putSingle(HttpHeaders.CONTENT_TYPE, HttpUtils.appendCharacterEncoding(currentContentType, s));
293296
}
294297

295298

aws-serverless-java-container-jersey/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
</parent>
1717

1818
<properties>
19-
<jersey.version>3.1.8</jersey.version>
19+
<jersey.version>3.1.9</jersey.version>
2020
</properties>
2121

2222
<dependencies>

aws-serverless-java-container-spring/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
</parent>
1717

1818
<properties>
19-
<spring.version>6.1.14</spring.version>
20-
<spring-security.version>6.3.4</spring-security.version>
19+
<spring.version>6.2.0</spring.version>
20+
<spring-security.version>6.4.1</spring-security.version>
2121
</properties>
2222

2323
<dependencies>

aws-serverless-java-container-springboot3/pom.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
<version>2.1.0-SNAPSHOT</version>
1616

1717
<properties>
18-
<spring.version>6.1.14</spring.version>
19-
<springboot.version>3.3.5</springboot.version>
20-
<springsecurity.version>6.3.4</springsecurity.version>
18+
<spring.version>6.2.0</spring.version>
19+
<springboot.version>3.4.0</springboot.version>
20+
<springsecurity.version>6.4.1</springsecurity.version>
2121
</properties>
2222

2323
<dependencies>
2424
<!-- Core interfaces for the aws-serverless-java-container project -->
2525
<dependency>
2626
<groupId>org.springframework.cloud</groupId>
2727
<artifactId>spring-cloud-function-serverless-web</artifactId>
28-
<version>4.1.3</version>
28+
<version>4.1.4</version>
2929
</dependency>
3030
<dependency>
3131
<groupId>com.amazonaws.serverless</groupId>

aws-serverless-java-container-springboot3/src/main/java/com/amazonaws/serverless/proxy/spring/AwsSpringHttpProcessingUtils.java

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
package com.amazonaws.serverless.proxy.spring;
22

33
import java.io.InputStream;
4+
import java.nio.charset.Charset;
45
import java.nio.charset.StandardCharsets;
5-
import java.util.Iterator;
6+
import java.nio.charset.UnsupportedCharsetException;
7+
import java.util.Base64;
68
import java.util.Map;
79
import java.util.Map.Entry;
8-
import java.util.Set;
910
import java.util.concurrent.CountDownLatch;
1011
import java.util.concurrent.TimeUnit;
1112

13+
import com.amazonaws.serverless.proxy.internal.HttpUtils;
14+
import org.apache.commons.io.Charsets;
1215
import org.apache.commons.logging.Log;
1316
import org.apache.commons.logging.LogFactory;
1417
import org.springframework.cloud.function.serverless.web.ServerlessHttpServletRequest;
1518
import org.springframework.cloud.function.serverless.web.ServerlessMVC;
19+
import org.springframework.http.HttpHeaders;
20+
import org.springframework.http.MediaType;
1621
import org.springframework.util.CollectionUtils;
1722
import org.springframework.util.FileCopyUtils;
1823
import org.springframework.util.MultiValueMapAdapter;
1924
import org.springframework.util.StringUtils;
2025

21-
import com.amazonaws.serverless.proxy.AsyncInitializationWrapper;
2226
import com.amazonaws.serverless.proxy.AwsHttpApiV2SecurityContextWriter;
2327
import com.amazonaws.serverless.proxy.AwsProxySecurityContextWriter;
2428
import com.amazonaws.serverless.proxy.RequestReader;
@@ -120,10 +124,12 @@ private static HttpServletRequest generateRequest1(String request, Context lambd
120124
MultiValueMapAdapter headers = new MultiValueMapAdapter(v1Request.getMultiValueHeaders());
121125
httpRequest.setHeaders(headers);
122126
}
123-
if (StringUtils.hasText(v1Request.getBody())) {
124-
httpRequest.setContentType("application/json");
125-
httpRequest.setContent(v1Request.getBody().getBytes(StandardCharsets.UTF_8));
126-
}
127+
populateContentAndContentType(
128+
v1Request.getBody(),
129+
v1Request.getHeaders().get(HttpHeaders.CONTENT_TYPE),
130+
v1Request.isBase64Encoded(),
131+
httpRequest
132+
);
127133
if (v1Request.getRequestContext() != null) {
128134
httpRequest.setAttribute(RequestReader.API_GATEWAY_CONTEXT_PROPERTY, v1Request.getRequestContext());
129135
httpRequest.setAttribute(RequestReader.ALB_CONTEXT_PROPERTY, v1Request.getRequestContext().getElb());
@@ -149,11 +155,14 @@ private static HttpServletRequest generateRequest2(String request, Context lambd
149155
populateQueryStringparameters(v2Request.getQueryStringParameters(), httpRequest);
150156

151157
v2Request.getHeaders().forEach(httpRequest::setHeader);
152-
153-
if (StringUtils.hasText(v2Request.getBody())) {
154-
httpRequest.setContentType("application/json");
155-
httpRequest.setContent(v2Request.getBody().getBytes(StandardCharsets.UTF_8));
156-
}
158+
159+
populateContentAndContentType(
160+
v2Request.getBody(),
161+
v2Request.getHeaders().get(HttpHeaders.CONTENT_TYPE),
162+
v2Request.isBase64Encoded(),
163+
httpRequest
164+
);
165+
157166
httpRequest.setAttribute(RequestReader.HTTP_API_CONTEXT_PROPERTY, v2Request.getRequestContext());
158167
httpRequest.setAttribute(RequestReader.HTTP_API_STAGE_VARS_PROPERTY, v2Request.getStageVariables());
159168
httpRequest.setAttribute(RequestReader.HTTP_API_EVENT_PROPERTY, v2Request);
@@ -180,4 +189,22 @@ private static <T> T readValue(String json, Class<T> clazz, ObjectMapper mapper)
180189
}
181190
}
182191

192+
private static void populateContentAndContentType(
193+
String body,
194+
String contentType,
195+
boolean base64Encoded,
196+
ServerlessHttpServletRequest httpRequest) {
197+
if (StringUtils.hasText(body)) {
198+
httpRequest.setContentType(contentType == null ? MediaType.APPLICATION_JSON_VALUE : contentType);
199+
if (base64Encoded) {
200+
httpRequest.setContent(Base64.getMimeDecoder().decode(body));
201+
} else {
202+
Charset charseEncoding = HttpUtils.parseCharacterEncoding(contentType,StandardCharsets.UTF_8);
203+
httpRequest.setContent(body.getBytes(charseEncoding));
204+
}
205+
}
206+
}
207+
208+
209+
183210
}

0 commit comments

Comments
 (0)