Skip to content
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

Query parameter values not URL decoded when using HTTP API V2 Gateway with a RequestStreamHandler implementation #976

Open
jfennelly-ext opened this issue Aug 15, 2024 · 6 comments
Assignees

Comments

@jfennelly-ext
Copy link

Serverless Java Container version: 2.0.3
Implementations: Spring Boot 3
Framework version: Spring Boot 3.2.4
Frontend service: HTTP API
Deployment method: Console via Zip File

Scenario

Follow the guidance in https://github.com/aws/serverless-java-container/wiki/Quick-start---Spring-Boot3 for creating an implementation of RequestStreamHandler which obtains a SpringBootLambdaContainerHandler by calling SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(...).

A request is made to a lambda using this handler implementation with a query parameter that holds a timezone string such as America/Los_Angeles, which has been URL encoded by the caller to America%2FLos_Angeles. The rawQueryString in the event arriving at the lambda looks like: date=2024-07-16&timezone=America%2FLos_Angeles. The Spring Boot controller maps the timezone parameter to a controller method argument. The value seen in the controller method is America%2FLos_Angeles. When Spring Boot is run standalone (no lambda/serverless container) the value seen in the controller method is America/Los_Angeles.

It appears that parsing of the lambda event to an HttpRequest occurs differently when using SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(...) for a custom handler implementation versus the provided SpringDelegatingLambdaContainerHandler.

For SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(...) the ServletLambdaContainerHandlerBuilder configures a AwsHttpApiV2HttpServletRequestReader. This Reader instantiates a AwsHttpApiV2ProxyHttpServletRequest which extracts query parameters from the event's rawQueryString. During this parsing of the rawQueryString, only the key of the key-value pair is URL decoded. The value is not decoded. See https://github.com/aws/serverless-java-container/blob/main/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpApiV2ProxyHttpServletRequest.java#L488-L505

For the SpringDelegatingLambdaContainerHandler, the AwsSpringHttpProcessingUtils.generateHttpServletRequest() method is used to convert the event input stream to an HTTP request. This uses entirely different logic to extract data from the lambda event to create the HTTP request. The AwsSpringHttpProcessingUtils.generateRequest2() method obtains query parameters from the already-URL-decoded queryStringParameters structure of the lambda event.

Expected behavior

Query parameter values are URL decoded when using the handler returned by SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(...).

Actual behavior

Query parameter values are not URL decoded as expected.

Steps to reproduce

Follow the steps in https://github.com/aws/serverless-java-container/wiki/Quick-start---Spring-Boot3 using the StreamLambdaHandler example, and swap out the commented-out HTTP API V2 proxy model handler creation:

handler = SpringBootLambdaContainerHandler.getHttpApiV2ProxyHandler(Application.class);

Map a @RestController in Spring Boot with a String query parameter using @RequestParam. Print out the resulting parameter value in the controller.
Make a request with a URL-encoded query parameter.
The value printed will still be URL-encoded.

@deki
Copy link
Collaborator

deki commented Aug 19, 2024

Hey @jfennelly-ext,
great analysis. Would you be willing to create a PR with a unittest and a fix?

@jpfennelly
Copy link

Yes, I can work on that. (sorry I created this issue from the wrong Github account, so everything else will be coming from this one).

@deki
Copy link
Collaborator

deki commented Oct 22, 2024

Hi @jpfennelly, are you still on it? We plan to have a release within the next weeks and it would be great to include it.

@jpfennelly
Copy link

I've been working on it and it's gotten a little more complicated than I anticipated. When I started pulling things apart I found that some of the unit tests had issues and the URL encoding situation was a bit more widespread than I thought. I have made a lot of progress, however. Since there is a release goal, I can put some more time in this week and see where I get by Monday.

@jpfennelly
Copy link

PR opened with my changes: #1089

@deki
Copy link
Collaborator

deki commented Nov 22, 2024

@jpfennelly sorry for the delay. Now that Spring Boot 3.4.0 is out, we'll likely have a release next week (just waiting for spring-cloud-function-serverless-web). Could you please take a look at the review comments in #1089 so we can include it? Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants