Skip to content

Commit e09fb83

Browse files
Fix CORS when working with multiheaders
1 parent fc376f9 commit e09fb83

File tree

9 files changed

+42
-7
lines changed

9 files changed

+42
-7
lines changed

aws_lambda_powertools/event_handler/api_gateway.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,30 @@ def to_dict(self, origin: Optional[str]) -> Dict[str, str]:
217217
headers["Access-Control-Allow-Credentials"] = "true"
218218
return headers
219219

220+
@staticmethod
221+
def extract_origin_header(resolver_headers: Dict):
222+
"""
223+
Extracts the 'origin' or 'Origin' header from the provided resolver headers.
224+
225+
The 'origin' or 'Origin' header can be either a single header or a multi-header.
226+
227+
Args:
228+
resolver_headers (Dict): A dictionary containing the headers.
229+
230+
Returns:
231+
Union[str, List[str], None]: The value(s) of the 'origin' or 'Origin' header.
232+
If the header is a single header, a string is returned.
233+
If the header is a multi-header, a list of strings is returned.
234+
If the header is not present, None is returned.
235+
"""
236+
resolved_header = resolver_headers.get("origin") or resolver_headers.get("Origin")
237+
if isinstance(resolved_header, str):
238+
return resolved_header
239+
if isinstance(resolved_header, list):
240+
return resolved_header[0]
241+
242+
return resolved_header
243+
220244

221245
class Response(Generic[ResponseT]):
222246
"""Response data class that provides greater control over what is returned from the proxy event"""
@@ -782,7 +806,8 @@ def __init__(
782806

783807
def _add_cors(self, event: ResponseEventT, cors: CORSConfig):
784808
"""Update headers to include the configured Access-Control headers"""
785-
self.response.headers.update(cors.to_dict(event.get_header_value("Origin")))
809+
extracted_origin_header = cors.extract_origin_header(event.resolved_headers_field)
810+
self.response.headers.update(cors.to_dict(extracted_origin_header))
786811

787812
def _add_cache_control(self, cache_control: str):
788813
"""Set the specified cache control headers for 200 http responses. For non-200 `no-cache` is used."""
@@ -2129,7 +2154,8 @@ def _not_found(self, method: str) -> ResponseBuilder:
21292154
headers = {}
21302155
if self._cors:
21312156
logger.debug("CORS is enabled, updating headers.")
2132-
headers.update(self._cors.to_dict(self.current_event.get_header_value("Origin")))
2157+
extracted_origin_header = self._cors.extract_origin_header(self.current_event.resolved_headers_field)
2158+
headers.update(self._cors.to_dict(extracted_origin_header))
21332159

21342160
if method == "OPTIONS":
21352161
logger.debug("Pre-flight request detected. Returning CORS with null response")

docs/index.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
8989
=== "CDK"
9090

9191
```python hl_lines="13 19"
92-
--8<-- "examples/homepage/install/x86_64/cdk.py"
92+
--8<-- "examples/homepage/install/x86_64/cdk_x86.py"
9393
```
9494

9595
=== "Terraform"
@@ -101,7 +101,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
101101
=== "Pulumi"
102102

103103
```python hl_lines="21-27"
104-
--8<-- "examples/homepage/install/x86_64/pulumi.py"
104+
--8<-- "examples/homepage/install/x86_64/pulumi_x86.py"
105105
```
106106

107107
=== "Amplify"
@@ -127,7 +127,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
127127
=== "CDK"
128128

129129
```python hl_lines="13 19"
130-
--8<-- "examples/homepage/install/arm64/cdk.py"
130+
--8<-- "examples/homepage/install/arm64/cdk_arm64.py"
131131
```
132132

133133
=== "Terraform"
@@ -139,7 +139,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc
139139
=== "Pulumi"
140140

141141
```python hl_lines="21-27"
142-
--8<-- "examples/homepage/install/arm64/pulumi.py"
142+
--8<-- "examples/homepage/install/arm64/pulumi_arm64.py"
143143
```
144144

145145
=== "Amplify"
@@ -275,7 +275,7 @@ Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to ch
275275
=== "CDK"
276276

277277
```python hl_lines="7 16-20 23-27"
278-
--8<-- "examples/homepage/install/sar/cdk.py"
278+
--8<-- "examples/homepage/install/sar/cdk_sar.py"
279279
```
280280

281281
=== "Terraform"

mypy.ini

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ disable_error_code = annotation-unchecked
1212
[mypy-jmespath]
1313
ignore_missing_imports=True
1414

15+
[mypy-pulumi.*]
16+
ignore_missing_imports=True
17+
18+
[mypy-pulumi_aws.*]
19+
ignore_missing_imports=True
20+
1521
[mypy-aws_encryption_sdk.*]
1622
ignore_missing_imports=True
1723

tests/events/apiGatewayProxyEvent.json

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
"Header1": [
1313
"value1"
1414
],
15+
"Origin": [
16+
"https://aws.amazon.com"
17+
],
1518
"Header2": [
1619
"value1",
1720
"value2"

0 commit comments

Comments
 (0)