Skip to content

Commit 47cfaa4

Browse files
committed
fix: Populate AWSProxyResponse headers with multi
Fixes: #1330
1 parent 79bc380 commit 47cfaa4

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/MicronautResponseWriter.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.amazonaws.serverless.proxy.internal.testutils.Timer;
2121
import com.amazonaws.serverless.proxy.model.AwsProxyRequest;
2222
import com.amazonaws.serverless.proxy.model.AwsProxyResponse;
23+
import com.amazonaws.serverless.proxy.model.Headers;
2324
import com.amazonaws.services.lambda.runtime.Context;
2425
import io.micronaut.core.annotation.Internal;
2526
import io.micronaut.core.io.Writable;
@@ -38,6 +39,7 @@
3839
import java.io.IOException;
3940
import java.nio.charset.Charset;
4041
import java.util.Base64;
42+
import java.util.HashMap;
4143
import java.util.List;
4244
import java.util.Map;
4345

@@ -68,6 +70,7 @@ public AwsProxyResponse writeResponse(
6870
Context lambdaContext) throws InvalidResponseObjectException {
6971
Timer.start(TIMER_NAME);
7072
AwsProxyResponse awsProxyResponse = containerResponse.getAwsResponse();
73+
7174
final Map<String, Cookie> cookies = containerResponse.getAllCookies();
7275
if (CollectionUtils.isNotEmpty(cookies)) {
7376
final io.netty.handler.codec.http.cookie.Cookie[] nettyCookies = cookies.values().stream().filter(c -> c instanceof NettyCookie).map(c -> ((NettyCookie) c).getNettyCookie()).toArray(io.netty.handler.codec.http.cookie.Cookie[]::new);
@@ -112,8 +115,20 @@ public AwsProxyResponse writeResponse(
112115
status + " " +
113116
Response.Status.fromStatusCode(status.getCode()).getReasonPhrase());
114117
}
115-
118+
awsProxyResponse.setHeaders(getHeaders(awsProxyResponse));
116119
Timer.stop(TIMER_NAME);
117120
return awsProxyResponse;
118121
}
122+
123+
private static Map<String, String> getHeaders(AwsProxyResponse awsProxyResponse) {
124+
Headers multiValueHeaders = awsProxyResponse.getMultiValueHeaders();
125+
Map<String, String> headers = new HashMap<>();
126+
for (String k : multiValueHeaders.keySet()) {
127+
List<String> headerValues = multiValueHeaders.get(k);
128+
if (headerValues != null && headerValues.size() == 1) {
129+
headers.put(k, headerValues.get(0));
130+
}
131+
}
132+
return headers;
133+
}
119134
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package io.micronaut.function.aws.proxy
2+
3+
import com.amazonaws.serverless.proxy.internal.testutils.AwsProxyRequestBuilder
4+
import com.amazonaws.serverless.proxy.internal.testutils.MockLambdaContext
5+
import com.amazonaws.serverless.proxy.model.AwsProxyResponse
6+
import com.amazonaws.services.lambda.runtime.Context
7+
import io.micronaut.context.ApplicationContext
8+
import io.micronaut.context.annotation.Requires
9+
import io.micronaut.http.HttpHeaders
10+
import io.micronaut.http.HttpMethod
11+
import io.micronaut.http.HttpStatus
12+
import io.micronaut.http.MediaType
13+
import io.micronaut.http.annotation.Body
14+
import io.micronaut.http.annotation.Controller
15+
import io.micronaut.http.annotation.Get
16+
import io.micronaut.http.annotation.Post
17+
import io.micronaut.http.annotation.Status
18+
import spock.lang.AutoCleanup
19+
import spock.lang.Issue
20+
import spock.lang.PendingFeature
21+
import spock.lang.Shared
22+
import spock.lang.Specification
23+
24+
class ContentTypeSpec extends Specification {
25+
@Shared
26+
@AutoCleanup
27+
MicronautLambdaContainerHandler handler = new MicronautLambdaContainerHandler(
28+
ApplicationContext.builder().properties([
29+
'spec.name' : 'ContentTypeSpec',
30+
'micronaut.security.enabled': false,
31+
])
32+
)
33+
@Shared
34+
Context lambdaContext = new MockLambdaContext()
35+
36+
void "verify controllers return json by default and mulitvalue headers are populated"() {
37+
given:
38+
AwsProxyRequestBuilder builder = new AwsProxyRequestBuilder('/json/bydefault', HttpMethod.GET.toString())
39+
builder.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
40+
41+
when:
42+
AwsProxyResponse response = handler.proxy(builder.build(), lambdaContext)
43+
44+
then:
45+
response.statusCode == 200
46+
response.body == '{"msg":"Hello world"}'
47+
48+
and: 'works with multivalue headers'
49+
response.multiValueHeaders
50+
["application/json"] == response.getMultiValueHeaders().get("Content-Type")
51+
}
52+
53+
@Issue("https://github.com/micronaut-projects/micronaut-aws/issues/1330")
54+
void "verify controllers return json by default and headers are populated"() {
55+
given:
56+
AwsProxyRequestBuilder builder = new AwsProxyRequestBuilder('/json/bydefault', HttpMethod.GET.toString())
57+
builder.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON)
58+
59+
when:
60+
AwsProxyResponse response = handler.proxy(builder.build(), lambdaContext)
61+
62+
then:
63+
response.statusCode == 200
64+
response.body == '{"msg":"Hello world"}'
65+
66+
response.headers
67+
"application/json" == response.getHeaders().get("Content-Type")
68+
}
69+
70+
@Controller('/json')
71+
@Requires(property = 'spec.name', value = 'ContentTypeSpec')
72+
static class BodyController {
73+
74+
@Get("/bydefault")
75+
@Status(HttpStatus.OK)
76+
Map<String, Object> index() {
77+
[msg: "Hello world"]
78+
}
79+
}
80+
}

0 commit comments

Comments
 (0)