-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Apigw ng implement header remapping #11237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
LocalStack Community integration with Pro 2 files ± 0 2 suites ±0 1h 36m 9s ⏱️ -3s Results for commit 29f4f64. ± Comparison against base commit 4928fe8. This pull request removes 54 and adds 142 tests. Note that renamed tests count towards both.
This pull request removes 2 skipped tests and adds 5 skipped tests. Note that renamed tests count towards both.
♻️ This comment has been updated with latest results. |
90ca21d
to
254c093
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that is a lot of work! Impressive tests, they really cover a lot of ground here.
I'm a bit torn about the headers helper file, as some of those methods are very tied to their handler and integration, and I'm wondering if it would maybe make more sense to have them in the handler directly, as they most probably won't be able to be re-used as is. We could keep the base header manipulation utils there, and move the "handler" specific methods directly there? What do you think? It feels like having helpers at first made sense, but now that there is a lot of integration specific (that we didn't expect), maybe it could be simpler and more contained.
Also, the fact that one is used for both exceptions and invocations makes me want to create a response handler for those, maybe it could simplify it a bit. It's not a big deal if the header doesn't do a lot, I think it might even be a good thing! 😄
We could also attach the integration type to the context in the request routing, I think that could be worth it as we access it quite often now.
All in all, this is really great work, you really went above and beyond here 🚀
localstack-core/localstack/testing/snapshots/transformer_utility.py
Outdated
Show resolved
Hide resolved
...ack-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_request.py
Outdated
Show resolved
Hide resolved
localstack-core/localstack/services/apigateway/next_gen/execute_api/header_utils.py
Outdated
Show resolved
Hide resolved
localstack-core/localstack/services/apigateway/next_gen/execute_api/integrations/aws.py
Show resolved
Hide resolved
localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/method_response.py
Outdated
Show resolved
Hide resolved
localstack-core/localstack/services/apigateway/next_gen/execute_api/handlers/method_response.py
Outdated
Show resolved
Hide resolved
...ck-core/localstack/services/apigateway/next_gen/execute_api/handlers/integration_response.py
Outdated
Show resolved
Hide resolved
localstack-core/localstack/services/apigateway/next_gen/execute_api/header_utils.py
Outdated
Show resolved
Hide resolved
Thanks for the review @bentsku. I agree that the headers helper is doing a bit more than it should really. You are right that in the and, most of the methods are tightly coupled with their integrations. I will move those methods in their respective handlers and keep only the shared methods in there |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, nice changes! Thanks a lot for addressing my concerns, this looks really good! The PR felt very easy to parse and understand, that was a lot of work! Congrats!
I just have minor comments, but nothing too major. After the questions are answered, this can be merged 😄 LGTM!
error = self.create_exception_response(exception, context) | ||
if error: | ||
response.update_from(error) | ||
|
||
@staticmethod | ||
def set_error_context(exception: BaseGatewayException, context: RestApiInvocationContext): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so neat 👌
# TODO apply responseParameters to the headers and get content-type from the gateway_response | ||
return {"content-type": APPLICATION_JSON, "x-amzn-ErrorType": exception.code} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: any particular reason we're deleting the Content-Type
here? We could avoid the workaround to remove the default content-type of the response if we'd let this for now, as right above we call json.dumps
, maybe setting the content type explicitly makes sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that makes more sense. Then when we implement the response mappings, we will have the content-type available from the template! 👍
# Some headers can't be modified by parameter mappings or mapping templates. | ||
# Aws will raise in those were present. Even for AWS_PROXY, where it is not applying them. | ||
if header_mappings := request_data_mapping["header"]: | ||
self._validate_headers_mapping(header_mappings, integration_type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super neat!
localstack-core/localstack/services/apigateway/next_gen/execute_api/header_utils.py
Outdated
Show resolved
Hide resolved
if not (connection := request.headers.get("Connection")) or connection != "close": | ||
# We only set the connection if it isn't close. | ||
# There appears to be in issue in Localstack, where setting "close" will result in "close, close" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, good catch!
assert default_context.integration_request["body"] == b"" | ||
assert default_context.integration_request["headers"]["Accept"] == "application/json" | ||
assert default_context.integration_request["http_method"] == "POST" | ||
assert default_context.integration_request["query_string_parameters"] == {} | ||
assert default_context.integration_request["uri"] == "https://example.com" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good change! might be easier to parse what's wrong in the test 👍
return ApiGatewayEndpoint.create_response(Request()) | ||
|
||
|
||
class TestResponseContextHandler: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
q: should we add a test for the keep-alive behavior? e.g. not setting the close
if it's there, and setting keep-alive
if anything else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure this is the right place for this test, but I can create a new test file to test this behavior
from localstack.utils.strings import short_uid | ||
|
||
|
||
class ResponseContextHandler(RestApiGatewayHandler): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: what do you think about the name InvocationResponseEnricher
? I'm not sure the name convey what it really does here.
Motivation
This PR aims at bringing a higher level of parity with apigateway headers. Some headers when not passed through appropriately will fail the invocation.
As noted on the Important Notes of the Api Gateway documention, some headers are either, dropped, passthrough or remapped from the users requests and following data transformations.
Changes
A series of header manipulation in the handlers was added.
Invocation
(parsing handler)
InvocationRequest
when first parsing the incoming request (This change was introduces by Apigw ng refactor headers to werkzeug headers #11227 )Request
( integration request handler)
InternalServerError
if modified by request parameters of mapping templates. Even forAWS_PROXY
where they are not applied, go figure 😄Response
( method response handler)
x-amzn-Remapped-
Connection
, seems to be taking from the original requestsConnection