Skip to content

Commit fb7cde9

Browse files
authored
APIGW NG: add LocalStack-only CORS handling for REST API (#11764)
1 parent e675014 commit fb7cde9

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

localstack-core/localstack/services/apigateway/next_gen/execute_api/gateway.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ def __init__(self):
3232
handlers.method_response_handler,
3333
]
3434
)
35-
self.response_handlers.extend(
35+
self.exception_handlers.extend(
3636
[
37-
handlers.response_enricher
38-
# add composite response handlers?
37+
handlers.gateway_exception_handler,
3938
]
4039
)
41-
self.exception_handlers.extend(
40+
self.response_handlers.extend(
4241
[
43-
handlers.gateway_exception_handler,
42+
handlers.response_enricher,
43+
handlers.cors_response_enricher,
44+
# add composite response handlers?
4445
]
4546
)
4647

localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from rolo.gateway import CompositeHandler
22

33
from .api_key_validation import ApiKeyValidationHandler
4+
from .cors import CorsResponseEnricher
45
from .gateway_exception import GatewayExceptionHandler
56
from .integration import IntegrationHandler
67
from .integration_request import IntegrationRequestHandler
@@ -23,3 +24,4 @@
2324
gateway_exception_handler = GatewayExceptionHandler()
2425
api_key_validation_handler = ApiKeyValidationHandler()
2526
response_enricher = InvocationResponseEnricher()
27+
cors_response_enricher = CorsResponseEnricher()
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import logging
2+
from http import HTTPMethod
3+
4+
from localstack import config
5+
from localstack.aws.handlers.cors import CorsEnforcer
6+
from localstack.aws.handlers.cors import CorsResponseEnricher as GlobalCorsResponseEnricher
7+
from localstack.http import Response
8+
9+
from ..api import RestApiGatewayHandler, RestApiGatewayHandlerChain
10+
from ..context import RestApiInvocationContext
11+
from ..gateway_response import MissingAuthTokenError
12+
13+
LOG = logging.getLogger(__name__)
14+
15+
16+
class CorsResponseEnricher(RestApiGatewayHandler):
17+
def __call__(
18+
self,
19+
chain: RestApiGatewayHandlerChain,
20+
context: RestApiInvocationContext,
21+
response: Response,
22+
):
23+
"""
24+
This is a LocalStack only handler, to allow users to override API Gateway CORS configuration and just use the
25+
default LocalStack configuration instead, to ease the usage and reduce production code changes.
26+
"""
27+
if not config.DISABLE_CUSTOM_CORS_APIGATEWAY:
28+
return
29+
30+
if not context.invocation_request:
31+
return
32+
33+
headers = context.invocation_request["headers"]
34+
35+
if "Origin" not in headers:
36+
return
37+
38+
if context.request.method == HTTPMethod.OPTIONS:
39+
# If the user did not configure an OPTIONS route, we still want LocalStack to properly respond to CORS
40+
# requests
41+
if context.invocation_exception:
42+
if isinstance(context.invocation_exception, MissingAuthTokenError):
43+
response.data = b""
44+
response.status_code = 204
45+
else:
46+
return
47+
48+
if CorsEnforcer.is_cors_origin_allowed(headers):
49+
GlobalCorsResponseEnricher.add_cors_headers(headers, response.headers)

0 commit comments

Comments
 (0)