diff --git a/aws-lambda-java-events/pom.xml b/aws-lambda-java-events/pom.xml
index 79b5d2fc..c1b2a95f 100644
--- a/aws-lambda-java-events/pom.xml
+++ b/aws-lambda-java-events/pom.xml
@@ -83,6 +83,13 @@
${lombok.version}
provided
+
+
+ org.assertj
+ assertj-core
+ 3.18.1
+ test
+
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerRequestEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerRequestEvent.java
index fca77846..c6be1b92 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerRequestEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerRequestEvent.java
@@ -59,8 +59,8 @@ public static class RequestContext implements Serializable {
private String path;
private Map queryStringParameters;
private Map> multiValueQueryStringParameters;
- private Map headers;
- private Map> multiValueHeaders;
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
private String body;
private boolean isBase64Encoded;
}
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerResponseEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerResponseEvent.java
index 7a8f6856..92349702 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerResponseEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/ApplicationLoadBalancerResponseEvent.java
@@ -39,7 +39,7 @@ public class ApplicationLoadBalancerResponseEvent implements Serializable {
private int statusCode;
private String statusDescription;
private boolean isBase64Encoded;
- private Map headers;
- private Map> multiValueHeaders;
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
private String body;
}
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/HttpHeaders.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/HttpHeaders.java
new file mode 100644
index 00000000..fa209930
--- /dev/null
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/HttpHeaders.java
@@ -0,0 +1,89 @@
+package com.amazonaws.services.lambda.runtime.events;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Class that represents Http Headers.
+ *
+ * Http Headers are case-insensitive.
+ * Thus, requesting a header "host" will yield the same result as "Host" or "HOST"
+ */
+public class HttpHeaders implements Map {
+
+ // Headers are case insensitive (https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2)
+ private final Map map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ @Override
+ public int size() {
+ return map.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return map.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return map.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return map.containsValue(value);
+ }
+
+ @Override
+ public T get(Object key) {
+ return map.get(key);
+ }
+
+ @Override
+ public T put(String key, T value) {
+ return map.put(key, value);
+ }
+
+ @Override
+ public T remove(Object key) {
+ return map.remove(key);
+ }
+
+ @Override
+ public void putAll(Map extends String, ? extends T> m) {
+ map.putAll(m);
+ }
+
+ @Override
+ public void clear() {
+ map.clear();
+ }
+
+ @Override
+ public Set keySet() {
+ return map.keySet();
+ }
+
+ @Override
+ public Collection values() {
+ return map.values();
+ }
+
+ @Override
+ public Set> entrySet() {
+ return map.entrySet();
+ }
+
+ public static HttpHeaders mergeOrReplace(Map from) {
+ if (from == null) return null;
+ if (from instanceof HttpHeaders) return (HttpHeaders) from;
+
+ HttpHeaders out = new HttpHeaders<>();
+ if (from.isEmpty()) return out;
+
+ out.putAll(from);
+ return out;
+ }
+}
\ No newline at end of file
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayCustomAuthorizerEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayCustomAuthorizerEvent.java
index 981bfdca..6ae03a19 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayCustomAuthorizerEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayCustomAuthorizerEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -39,7 +40,7 @@ public class APIGatewayCustomAuthorizerEvent {
private String resource;
private String path;
private String httpMethod;
- private Map headers;
+ private HttpHeaders headers;
private Map queryStringParameters;
private Map pathParameters;
private Map stageVariables;
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyRequestEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyRequestEvent.java
index 0d8f3378..75cbb077 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyRequestEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyRequestEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -37,8 +38,8 @@ public class APIGatewayProxyRequestEvent implements Serializable {
private String resource;
private String path;
private String httpMethod;
- private Map headers;
- private Map> multiValueHeaders;
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
private Map queryStringParameters;
private Map> multiValueQueryStringParameters;
private Map pathParameters;
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyResponseEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyResponseEvent.java
index 20cd305e..637ea2e6 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyResponseEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayProxyResponseEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -34,7 +35,7 @@ public class APIGatewayProxyResponseEvent implements Serializable {
private static final long serialVersionUID = 2263167344670024172L;
private Integer statusCode;
- private Map headers;
+ private HttpHeaders headers;
private String body;
private Boolean isBase64Encoded;
}
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2CustomAuthorizerEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2CustomAuthorizerEvent.java
index 9634d5c9..98a94271 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2CustomAuthorizerEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2CustomAuthorizerEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -43,7 +44,7 @@ public class APIGatewayV2CustomAuthorizerEvent {
private String rawPath;
private String rawQueryString;
private List cookies;
- private Map headers;
+ private HttpHeaders headers;
private Map queryStringParameters;
private RequestContext requestContext;
private Map pathParameters;
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPEvent.java
index d2f713ad..95721fc9 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -37,7 +38,7 @@ public class APIGatewayV2HTTPEvent {
private String rawPath;
private String rawQueryString;
private List cookies;
- private Map headers;
+ private HttpHeaders headers;
private Map queryStringParameters;
private Map pathParameters;
private Map stageVariables;
@@ -45,6 +46,10 @@ public class APIGatewayV2HTTPEvent {
private boolean isBase64Encoded;
private RequestContext requestContext;
+ public void setHeaders(Map headers) {
+ this.headers = HttpHeaders.mergeOrReplace(headers);
+ }
+
@AllArgsConstructor
@Builder(setterPrefix = "with")
@Data
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPResponse.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPResponse.java
index 0513f7bc..1ff44d5f 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPResponse.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2HTTPResponse.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@@ -28,9 +29,28 @@
public class APIGatewayV2HTTPResponse {
private int statusCode;
- private Map headers;
- private Map> multiValueHeaders;
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
private List cookies;
private String body;
private boolean isBase64Encoded;
+
+ public static APIGatewayV2HTTPResponseBuilder builder() {
+ return new APIGatewayV2HTTPResponseBuilder();
+ }
+
+ public static class APIGatewayV2HTTPResponseBuilder {
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
+
+ public APIGatewayV2HTTPResponseBuilder withHeaders(Map headers) {
+ this.headers = HttpHeaders.mergeOrReplace(headers);
+ return this;
+ }
+
+ public APIGatewayV2HTTPResponseBuilder withMultiValueHeaders(Map> multiValueHeaders) {
+ this.multiValueHeaders = HttpHeaders.mergeOrReplace(multiValueHeaders);
+ return this;
+ }
+ }
}
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2WebSocketEvent.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2WebSocketEvent.java
index 6bcc50df..9d514b91 100644
--- a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2WebSocketEvent.java
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/apigateway/APIGatewayV2WebSocketEvent.java
@@ -13,6 +13,7 @@
package com.amazonaws.services.lambda.runtime.events.apigateway;
+import com.amazonaws.services.lambda.runtime.events.HttpHeaders;
import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
@@ -91,8 +92,8 @@ public static class RequestContext implements Serializable {
private String resource;
private String path;
private String httpMethod;
- private Map headers;
- private Map> multiValueHeaders;
+ private HttpHeaders headers;
+ private HttpHeaders> multiValueHeaders;
private Map queryStringParameters;
private Map> multiValueQueryStringParameters;
private Map pathParameters;
diff --git a/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersTest.java b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersTest.java
new file mode 100644
index 00000000..f8436b8b
--- /dev/null
+++ b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersTest.java
@@ -0,0 +1,148 @@
+package com.amazonaws.services.lambda.runtime.events;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class HttpHeadersTest {
+
+ @Test
+ public void testHttpHeadersCanBeInit() {
+ HttpHeaders obj = new HttpHeaders<>();
+ }
+
+ @Test
+ public void testValueCanBeAddedToHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ assertThat(obj).hasSize(1);
+ assertThat(obj).containsEntry("key", "value");
+ }
+
+ @Test
+ public void testValuesCanBeAddedToHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+ obj.put("key3", "value3");
+
+ assertThat(obj).hasSize(3);
+ assertThat(obj).containsEntry("key", "value");
+ assertThat(obj).containsEntry("key2", "value2");
+ assertThat(obj).containsEntry("key3", "value3");
+ }
+
+ @Test
+ public void testOverridingHttpHeadersKeysIsCaseInsensitive() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("KEY", "value2");
+ obj.put("kEy", "value3");
+
+ assertThat(obj).hasSize(1);
+ assertThat(obj).containsEntry("key", "value3");
+ }
+
+ @Test
+ public void testValuesCanBeRemovedFromHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+
+ assertThat(obj).hasSize(1);
+ obj.remove("key");
+ assertThat(obj).isEmpty();
+ }
+
+ @Test
+ public void testContainedKeysAreContainedInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+
+ assertTrue(obj.containsKey("key"));
+ }
+
+ @Test
+ public void testContainedValuesAreContainedInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+
+ assertTrue(obj.containsValue("value"));
+ }
+
+ @Test
+ public void testPutAllWorksInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+
+ Map otherMap = new HashMap<>();
+ otherMap.put("otherKey1", "otherVal1");
+ otherMap.put("otherKey2", "otherVal2");
+ otherMap.put("otherKey3", "otherVal3");
+
+ obj.putAll(otherMap);
+
+ assertThat(obj).hasSize(5);
+ assertThat(obj).containsEntry("key", "value");
+ assertThat(obj).containsEntry("key2", "value2");
+ assertThat(obj).containsEntry("otherKey1", "otherVal1");
+ assertThat(obj).containsEntry("otherKey2", "otherVal2");
+ assertThat(obj).containsEntry("otherKey3", "otherVal3");
+ }
+
+ @Test
+ public void testClearWorksInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+
+ assertThat(obj).hasSize(2);
+
+ obj.clear();
+
+ assertThat(obj).hasSize(0);
+ }
+
+ @Test
+ public void testKeySetWorksInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+
+ Set keySet = obj.keySet();
+
+ assertNotNull(keySet);
+ assertThat(keySet).hasSize(2);
+ assertThat(keySet).contains("key", "key2");
+ }
+
+ @Test
+ public void testValuesWorksInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+
+ Collection values = obj.values();
+
+ assertNotNull(values);
+ assertThat(values).hasSize(2);
+ assertThat(values).contains("value", "value2");
+ }
+
+ @Test
+ public void testEntrySetWorksInHttpHeaders() {
+ HttpHeaders obj = new HttpHeaders<>();
+ obj.put("key", "value");
+ obj.put("key2", "value2");
+
+ Set> entrySet = obj.entrySet();
+
+ assertNotNull(entrySet);
+ assertThat(entrySet).hasSize(2);
+ assertThat(entrySet).contains(new AbstractMap.SimpleEntry<>("key", "value"));
+ assertThat(entrySet).contains(new AbstractMap.SimpleEntry<>("key2", "value2"));
+ }
+}
diff --git a/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersUtilTest.java b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersUtilTest.java
new file mode 100644
index 00000000..022a0f37
--- /dev/null
+++ b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/HttpHeadersUtilTest.java
@@ -0,0 +1,146 @@
+package com.amazonaws.services.lambda.runtime.events;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class HttpHeadersUtilTest {
+
+ @Test
+ public void testWhenFromObjNullThenNullReturned() {
+ Map result = HttpHeaders.mergeOrReplace(null);
+ assertNull(result);
+ }
+
+ @Test
+ public void testWhenFromObjEmptyThenEmptyHttpHeadersReturned() {
+ Map from = new HashMap<>();
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(Collections.emptyMap(), result);
+ }
+
+ @Test
+ public void testWhenFromObjIsHashmapThenNewHttpHeadersReturned() {
+ HashMap from = createHashMap("key", "value");
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(from, result);
+ }
+
+ @Test
+ public void testWhenFromObjIsHashmapMultiValueThenNewHttpHeadersReturned() {
+ HashMap from = createHashMap(
+ "key", "value",
+ "key2", "value2",
+ "key3", "value3"
+ );
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(from, result);
+ }
+
+ @Test
+ public void testWhenFromObjIsTreemapMultiValueThenNewHttpHeadersReturned() {
+ TreeMap from = createTreeMap(
+ "key", "value",
+ "key2", "value2",
+ "key3", "value3"
+ );
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(from, result);
+ }
+
+ @Test
+ public void testWhenFromObjIsDuplicatedKeyMultiValueTreeMapThenReturnedHttpHeadersContainOnlyFinalValue() {
+ TreeMap from = createTreeMap(
+ "key", "value",
+ "KEY", "value2",
+ "kEy", "value3",
+ Collections.reverseOrder()
+ );
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(1, result.size());
+ Map.Entry lastEntry = from.lastEntry();
+ assertEquals(result.getOrDefault(lastEntry.getKey(), null), lastEntry.getValue());
+ }
+
+ @Test
+ public void testWhenFromObjIsDuplicatedKeyMultiValueHashMapThenReturnedHttpHeadersContainOnlyOneValue() {
+ HashMap from = createHashMap(
+ "key", "value",
+ "KEY", "value2",
+ "kEy", "value3"
+ );
+ Map result = HttpHeaders.mergeOrReplace(from);
+
+ assertNotNull(result);
+ assertInstanceOf(HttpHeaders.class, result);
+ assertEquals(1, result.size());
+
+ Map.Entry entry = from.entrySet().iterator().next();
+ assertTrue(from.entrySet().stream()
+ .anyMatch(e -> entry.getKey().equals(e.getKey()) && entry.getValue().equals(e.getValue())));
+ }
+
+ @Test
+ public void testWhenFromObjAlreadyHttpHeadersThenSameInstanceReturned() {
+ Map from = new HttpHeaders<>();
+ from.put("key", "value");
+
+ Map result = HttpHeaders.mergeOrReplace(from);
+ assertSame(from, result);
+ }
+
+ @Test
+ public void testWhenFromObjAlreadyEmptyHttpHeadersThenSameInstanceReturned() {
+ Map from = new HttpHeaders<>();
+
+ Map result = HttpHeaders.mergeOrReplace(from);
+ assertSame(from, result);
+ }
+
+ private static HashMap createHashMap(String key1, T val1) {
+ HashMap map = new HashMap<>();
+ map.put(key1, val1);
+ return map;
+ }
+
+ private static HashMap createHashMap(String key1, T val1, String key2, T val2, String key3, T val3) {
+ HashMap map = new HashMap<>();
+ map.put(key1, val1);
+ map.put(key2, val2);
+ map.put(key3, val3);
+ return map;
+ }
+
+ private static TreeMap createTreeMap(String key1, T val1, String key2, T val2, String key3, T val3) {
+ TreeMap map = new TreeMap<>();
+ map.put(key1, val1);
+ map.put(key2, val2);
+ map.put(key3, val3);
+ return map;
+ }
+
+ private static TreeMap createTreeMap(String key1, T val1, String key2, T val2, String key3, T val3, java.util.Comparator ordering) {
+ TreeMap map = new TreeMap<>();
+ map.put(key1, val1);
+ map.put(key2, val2);
+ map.put(key3, val3);
+ return map;
+ }
+}
\ No newline at end of file
diff --git a/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HeadersTest.java b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HeadersTest.java
new file mode 100644
index 00000000..938d1613
--- /dev/null
+++ b/aws-lambda-java-tests/src/test/java/com/amazonaws/services/lambda/runtime/tests/HeadersTest.java
@@ -0,0 +1,56 @@
+package com.amazonaws.services.lambda.runtime.tests;
+
+import com.amazonaws.services.lambda.runtime.events.ApplicationLoadBalancerRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.apigateway.APIGatewayCustomAuthorizerEvent;
+import com.amazonaws.services.lambda.runtime.events.apigateway.APIGatewayProxyRequestEvent;
+import com.amazonaws.services.lambda.runtime.events.apigateway.APIGatewayV2CustomAuthorizerEvent;
+import com.amazonaws.services.lambda.runtime.events.apigateway.APIGatewayV2HTTPEvent;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class HeadersTest {
+
+ @Test
+ public void testHeadersApiGatewayRestEvent() {
+ APIGatewayProxyRequestEvent event = EventLoader.loadApiGatewayRestEvent("apigw_rest_event.json");
+
+ assertThat(event.getHeaders().get("Header1")).isEqualTo("value1");
+ assertThat(event.getHeaders().get("header1")).isEqualTo("value1");
+ assertThat(event.getMultiValueHeaders().get("header1")).contains("value1", "value11");
+ assertThat(event.getMultiValueHeaders().get("Header1")).contains("value1", "value11");
+ assertThat(event.getHeaders()).hasSize(2);
+ }
+
+ @Test
+ public void testHeadersApiGatewayHttpEvent() {
+ APIGatewayV2HTTPEvent event = EventLoader.loadApiGatewayHttpEvent("apigw_http_event.json");
+
+ assertThat(event.getHeaders().get("Header1")).isEqualTo("value1");
+ assertThat(event.getHeaders().get("header1")).isEqualTo("value1");
+ }
+
+ @Test
+ public void testHeadersAPIGatewayCustomAuthorizerEvent() {
+ APIGatewayCustomAuthorizerEvent event = EventLoader.loadAPIGatewayCustomAuthorizerEvent("apigw_auth.json");
+
+ assertThat(event.getHeaders().get("Accept")).isEqualTo("*/*");
+ assertThat(event.getHeaders().get("accept")).isEqualTo("*/*");
+ }
+
+ @Test
+ public void testHeadersAPIGatewayV2CustomAuthorizerEvent() {
+ APIGatewayV2CustomAuthorizerEvent event = EventLoader.loadAPIGatewayV2CustomAuthorizerEvent("apigw_auth_v2.json");
+
+ assertThat(event.getHeaders().get("Header1")).isEqualTo("Value1");
+ assertThat(event.getHeaders().get("header1")).isEqualTo("Value1");
+ }
+
+ @Test
+ public void testHeadersApplicationLoadBalancerRequestEvent() {
+ ApplicationLoadBalancerRequestEvent event = EventLoader.loadApplicationLoadBalancerRequestEvent("elb_event.json");
+
+ assertThat(event.getHeaders().get("Accept")).isEqualTo("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ assertThat(event.getHeaders().get("accept")).isEqualTo("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ }
+}
\ No newline at end of file
diff --git a/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json b/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json
index a603763e..70024f22 100644
--- a/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json
+++ b/aws-lambda-java-tests/src/test/resources/apigw_auth_v2.json
@@ -8,8 +8,9 @@
"rawQueryString": "parameter1=value1¶meter1=value2¶meter2=value",
"cookies": [ "cookie1", "cookie2" ],
"headers": {
- "Header1": "value1",
- "Header2": "value2"
+ "header1": "value1",
+ "Header2": "value2",
+ "Header1": "Value1"
},
"queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" },
"requestContext": {
diff --git a/aws-lambda-java-tests/src/test/resources/apigw_http_event.json b/aws-lambda-java-tests/src/test/resources/apigw_http_event.json
index 88f4e5b4..43c7e4b3 100644
--- a/aws-lambda-java-tests/src/test/resources/apigw_http_event.json
+++ b/aws-lambda-java-tests/src/test/resources/apigw_http_event.json
@@ -8,8 +8,9 @@
"cookie2"
],
"headers": {
- "Header1": "value1",
- "Header2": "value1,value2"
+ "Header1": "Value1",
+ "Header2": "value1,value2",
+ "header1": "value1"
},
"queryStringParameters": {
"parameter1": "value1,value2",
diff --git a/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json b/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json
index 28f10c22..e7907d58 100644
--- a/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json
+++ b/aws-lambda-java-tests/src/test/resources/apigw_rest_event.json
@@ -4,8 +4,9 @@
"path": "/my/path",
"httpMethod": "GET",
"headers": {
- "Header1": "value1",
- "Header2": "value2"
+ "Header1": "Value1",
+ "Header2": "value2",
+ "header1": "value1"
},
"multiValueHeaders": {
"Header1": [
@@ -14,6 +15,10 @@
"Header2": [
"value1",
"value2"
+ ],
+ "header1": [
+ "value1",
+ "value11"
]
},
"queryStringParameters": {