Skip to content

Commit 2ccfe8e

Browse files
committed
\aws#220 Fix header case sensitivity (updated aws#234)
This solution builds upon @jeromevdl 's solution of PR aws#234 to fix the issue of headers being case sensitive. Fixes @carlzogh 's comment regarding breaking changes in setHeaders.
1 parent 4fe08f4 commit 2ccfe8e

20 files changed

+529
-40
lines changed

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayCustomAuthorizerEvent.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
34
import lombok.AllArgsConstructor;
45
import lombok.Builder;
56
import lombok.Data;
@@ -26,7 +27,7 @@ public class APIGatewayCustomAuthorizerEvent {
2627
private String resource;
2728
private String path;
2829
private String httpMethod;
29-
private Map<String, String> headers;
30+
private HttpHeaders<String> headers;
3031
private Map<String, String> queryStringParameters;
3132
private Map<String, String> pathParameters;
3233
private Map<String, String> stageVariables;

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayProxyRequestEvent.java

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
4+
35
import java.io.Serializable;
4-
import java.util.List;
5-
import java.util.Map;
6+
import java.util.*;
67

78
/**
89
* Class that represents an APIGatewayProxyRequestEvent
@@ -19,9 +20,9 @@ public class APIGatewayProxyRequestEvent implements Serializable, Cloneable {
1920

2021
private String httpMethod;
2122

22-
private Map<String, String> headers;
23+
private HttpHeaders<String> headers;
2324

24-
private Map<String, List<String>> multiValueHeaders;
25+
private HttpHeaders<List<String>> multiValueHeaders;
2526

2627
private Map<String, String> queryStringParameters;
2728

@@ -69,7 +70,8 @@ public static class ProxyRequestContext implements Serializable, Cloneable {
6970
/**
7071
* default constructor
7172
*/
72-
public ProxyRequestContext() {}
73+
public ProxyRequestContext() {
74+
}
7375

7476
/**
7577
* @return account id that owns Lambda function
@@ -103,7 +105,7 @@ public void setAuthorizer(final Map<String, Object> authorizer) {
103105
}
104106

105107
/**
106-
* @return API Gateway stage name
108+
* @return API Gateway stage name
107109
*/
108110
public String getStage() {
109111
return stage;
@@ -288,14 +290,14 @@ public ProxyRequestContext withPath(String path) {
288290

289291
/**
290292
* @return The name of the operation being performed
291-
* */
293+
*/
292294
public String getOperationName() {
293295
return operationName;
294296
}
295297

296298
/**
297299
* @param operationName The name of the operation being performed
298-
* */
300+
*/
299301
public void setOperationName(String operationName) {
300302
this.operationName = operationName;
301303
}
@@ -309,7 +311,6 @@ public ProxyRequestContext withOperationName(String operationName) {
309311
* Returns a string representation of this object; useful for testing and debugging.
310312
*
311313
* @return A string representation of this object.
312-
*
313314
* @see Object#toString()
314315
*/
315316
@Override
@@ -414,7 +415,7 @@ public int hashCode() {
414415
hashCode = prime * hashCode + ((getApiId() == null) ? 0 : getApiId().hashCode());
415416
hashCode = prime * hashCode + ((getPath() == null) ? 0 : getPath().hashCode());
416417
hashCode = prime * hashCode + ((getAuthorizer() == null) ? 0 : getAuthorizer().hashCode());
417-
hashCode = prime * hashCode + ((getOperationName() == null) ? 0: getOperationName().hashCode());
418+
hashCode = prime * hashCode + ((getOperationName() == null) ? 0 : getOperationName().hashCode());
418419
return hashCode;
419420
}
420421

@@ -461,7 +462,8 @@ public static class RequestIdentity implements Serializable, Cloneable {
461462
/**
462463
* default constructor
463464
*/
464-
public RequestIdentity() {}
465+
public RequestIdentity() {
466+
}
465467

466468
/**
467469
* @return The Cognito identity pool id.
@@ -766,7 +768,6 @@ public RequestIdentity withAccessKey(String accessKey) {
766768
* Returns a string representation of this object; useful for testing and debugging.
767769
*
768770
* @return A string representation of this object.
769-
*
770771
* @see Object#toString()
771772
*/
772773
@Override
@@ -903,7 +904,8 @@ public RequestIdentity clone() {
903904
/**
904905
* default constructor
905906
*/
906-
public APIGatewayProxyRequestEvent() {}
907+
public APIGatewayProxyRequestEvent() {
908+
}
907909

908910
/**
909911
* @return The payload format version
@@ -1008,7 +1010,7 @@ public Map<String, String> getHeaders() {
10081010
* @param headers The headers sent with the request
10091011
*/
10101012
public void setHeaders(Map<String, String> headers) {
1011-
this.headers = headers;
1013+
this.headers = HttpHeadersUtil.mergeOrReplace(headers);
10121014
}
10131015

10141016
/**
@@ -1031,7 +1033,7 @@ public Map<String, List<String>> getMultiValueHeaders() {
10311033
* @param multiValueHeaders The multi value headers sent with the request
10321034
*/
10331035
public void setMultiValueHeaders(Map<String, List<String>> multiValueHeaders) {
1034-
this.multiValueHeaders = multiValueHeaders;
1036+
this.multiValueHeaders = HttpHeadersUtil.mergeOrReplace(multiValueHeaders);
10351037
}
10361038

10371039
/**
@@ -1224,7 +1226,6 @@ public APIGatewayProxyRequestEvent withIsBase64Encoded(Boolean isBase64Encoded)
12241226
* Returns a string representation of this object; useful for testing and debugging.
12251227
*
12261228
* @return A string representation of this object.
1227-
*
12281229
* @see Object#toString()
12291230
*/
12301231
@Override

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayProxyResponseEvent.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
4+
35
import java.io.Serializable;
46
import java.util.List;
57
import java.util.Map;
@@ -13,9 +15,9 @@ public class APIGatewayProxyResponseEvent implements Serializable, Cloneable {
1315

1416
private Integer statusCode;
1517

16-
private Map<String, String> headers;
18+
private HttpHeaders<String> headers;
1719

18-
private Map<String, List<String>> multiValueHeaders;
20+
private HttpHeaders<List<String>> multiValueHeaders;
1921

2022
private String body;
2123

@@ -60,7 +62,7 @@ public Map<String, String> getHeaders() {
6062
* @param headers The Http headers return in the response
6163
*/
6264
public void setHeaders(Map<String, String> headers) {
63-
this.headers = headers;
65+
this.headers = HttpHeadersUtil.mergeOrReplace(headers);
6466
}
6567

6668
/**
@@ -83,7 +85,7 @@ public Map<String, List<String>> getMultiValueHeaders() {
8385
* @param multiValueHeaders the Http multi value headers to return in the response
8486
*/
8587
public void setMultiValueHeaders(Map<String, List<String>> multiValueHeaders) {
86-
this.multiValueHeaders = multiValueHeaders;
88+
this.multiValueHeaders = HttpHeadersUtil.mergeOrReplace(multiValueHeaders);
8789
}
8890

8991
/**

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2CustomAuthorizerEvent.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
34
import lombok.AllArgsConstructor;
45
import lombok.Builder;
56
import lombok.Data;
@@ -31,7 +32,7 @@ public class APIGatewayV2CustomAuthorizerEvent {
3132
private String rawPath;
3233
private String rawQueryString;
3334
private List<String> cookies;
34-
private Map<String, String> headers;
35+
private HttpHeaders<String> headers;
3536
private Map<String, String> queryStringParameters;
3637
private RequestContext requestContext;
3738
private Map<String, String> pathParameters;

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2HTTPEvent.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package com.amazonaws.services.lambda.runtime.events;
1515

16+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
1617
import lombok.AllArgsConstructor;
1718
import lombok.Builder;
1819
import lombok.Data;
@@ -34,14 +35,18 @@ public class APIGatewayV2HTTPEvent {
3435
private String rawPath;
3536
private String rawQueryString;
3637
private List<String> cookies;
37-
private Map<String, String> headers;
38+
private HttpHeaders<String> headers;
3839
private Map<String, String> queryStringParameters;
3940
private Map<String, String> pathParameters;
4041
private Map<String, String> stageVariables;
4142
private String body;
4243
private boolean isBase64Encoded;
4344
private RequestContext requestContext;
4445

46+
public void setHeaders(Map<String, String> headers) {
47+
this.headers = HttpHeadersUtil.mergeOrReplace(headers);
48+
}
49+
4550
@AllArgsConstructor
4651
@Builder(setterPrefix = "with")
4752
@Data

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2HTTPResponse.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
package com.amazonaws.services.lambda.runtime.events;
1515

16+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
1617
import lombok.AllArgsConstructor;
1718
import lombok.Builder;
1819
import lombok.Data;
@@ -27,9 +28,28 @@
2728
@NoArgsConstructor
2829
public class APIGatewayV2HTTPResponse {
2930
private int statusCode;
30-
private Map<String, String> headers;
31-
private Map<String, List<String>> multiValueHeaders;
31+
private HttpHeaders<String> headers;
32+
private HttpHeaders<List<String>> multiValueHeaders;
3233
private List<String> cookies;
3334
private String body;
3435
private boolean isBase64Encoded;
36+
37+
public static APIGatewayV2HTTPResponseBuilder builder() {
38+
return new APIGatewayV2HTTPResponseBuilder();
39+
}
40+
41+
public static class APIGatewayV2HTTPResponseBuilder {
42+
private HttpHeaders<String> headers;
43+
private HttpHeaders<List<String>> multiValueHeaders;
44+
45+
public APIGatewayV2HTTPResponseBuilder withHeaders(Map<String, String> headers) {
46+
this.headers = HttpHeadersUtil.mergeOrReplace(headers);
47+
return this;
48+
}
49+
50+
public APIGatewayV2HTTPResponseBuilder withMultiValueHeaders(Map<String, List<String>> multiValueHeaders) {
51+
this.multiValueHeaders = HttpHeadersUtil.mergeOrReplace(multiValueHeaders);
52+
return this;
53+
}
54+
}
3555
}

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2WebSocketResponse.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
4+
35
import java.io.Serializable;
46
import java.util.Map;
57

@@ -12,8 +14,8 @@ public class APIGatewayV2WebSocketResponse implements Serializable, Cloneable {
1214

1315
private boolean isBase64Encoded = false;
1416
private int statusCode;
15-
private Map<String, String> headers;
16-
private Map<String, String[]> multiValueHeaders;
17+
private HttpHeaders<String> headers;
18+
private HttpHeaders<String[]> multiValueHeaders;
1719
private String body;
1820

1921
public boolean isIsBase64Encoded() {
@@ -37,15 +39,15 @@ public Map<String, String> getHeaders() {
3739
}
3840

3941
public void setHeaders(Map<String, String> headers) {
40-
this.headers = headers;
42+
this.headers = HttpHeadersUtil.mergeOrReplace(headers);
4143
}
4244

4345
public Map<String, String[]> getMultiValueHeaders() {
4446
return multiValueHeaders;
4547
}
4648

4749
public void setMultiValueHeaders(Map<String, String[]> multiValueHeaders) {
48-
this.multiValueHeaders = multiValueHeaders;
50+
this.multiValueHeaders = HttpHeadersUtil.mergeOrReplace(multiValueHeaders);
4951
}
5052

5153
public String getBody() {

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerRequestEvent.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
34
import lombok.Data;
45
import lombok.NoArgsConstructor;
56

@@ -40,8 +41,8 @@ public static class RequestContext implements Serializable, Cloneable {
4041
private String path;
4142
private Map<String, String> queryStringParameters;
4243
private Map<String, List<String>> multiValueQueryStringParameters;
43-
private Map<String, String> headers;
44-
private Map<String, List<String>> multiValueHeaders;
44+
private HttpHeaders<String> headers;
45+
private HttpHeaders<List<String>> multiValueHeaders;
4546
private String body;
4647
private boolean isBase64Encoded;
4748

aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerResponseEvent.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.amazonaws.services.lambda.runtime.events;
22

3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
34
import lombok.Data;
45
import lombok.NoArgsConstructor;
56

@@ -22,8 +23,8 @@ public class ApplicationLoadBalancerResponseEvent implements Serializable, Clone
2223
private int statusCode;
2324
private String statusDescription;
2425
private boolean isBase64Encoded;
25-
private Map<String, String> headers;
26-
private Map<String, List<String>> multiValueHeaders;
26+
private HttpHeaders<String> headers;
27+
private HttpHeaders<List<String>> multiValueHeaders;
2728
private String body;
2829

2930
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.amazonaws.services.lambda.runtime.events;
2+
3+
import com.amazonaws.services.lambda.runtime.events.models.HttpHeaders;
4+
5+
import java.util.Map;
6+
7+
final class HttpHeadersUtil {
8+
private HttpHeadersUtil() {}
9+
10+
public static <T> HttpHeaders<T> mergeOrReplace(Map<String, T> from) {
11+
if (from == null) return null;
12+
if (from instanceof HttpHeaders) return (HttpHeaders<T>) from;
13+
14+
HttpHeaders<T> out = new HttpHeaders<>();
15+
if (from.isEmpty()) return out;
16+
17+
out.putAll(from);
18+
return out;
19+
}
20+
}

0 commit comments

Comments
 (0)