diff --git a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/ApiGatewayServletRequest.java b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/ApiGatewayServletRequest.java index 69d794ebd6..d98baadc96 100644 --- a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/ApiGatewayServletRequest.java +++ b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/ApiGatewayServletRequest.java @@ -36,6 +36,7 @@ import io.micronaut.http.MutableHttpRequest; import io.micronaut.http.cookie.Cookie; import io.micronaut.http.cookie.Cookies; +import io.micronaut.http.uri.UriBuilder; import io.micronaut.servlet.http.MutableServletHttpRequest; import io.micronaut.servlet.http.BodyBuilder; import io.micronaut.servlet.http.ServletExchange; @@ -108,6 +109,30 @@ protected ApiGatewayServletRequest( public abstract byte[] getBodyBytes() throws IOException; + /** + * Given a path and the query params from the event, build a URI. + * + * @param path the request path + * @param queryParameters the query parameters from the event + * @param multiQueryParameters the multi-value query parameters from the event + * @return the URI + * @since 4.0.3 + */ + protected static URI buildUri( + String path, + @Nullable Map queryParameters, + @Nullable Map> multiQueryParameters + ) { + UriBuilder uriBuilder = UriBuilder.of(path); + if (queryParameters != null) { + queryParameters.forEach((key, value) -> splitCommaSeparatedValue(value).forEach(token -> uriBuilder.queryParam(key, token))); + } + if (multiQueryParameters != null) { + multiQueryParameters.forEach((key, values) -> values.forEach(value -> uriBuilder.queryParam(key, value))); + } + return uriBuilder.build(); + } + protected static HttpMethod parseMethod(Supplier httpMethodConsumer) { try { return HttpMethod.valueOf(httpMethodConsumer.get()); diff --git a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/alb/ApplicationLoadBalancerServletRequest.java b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/alb/ApplicationLoadBalancerServletRequest.java index 4c3d6136af..f665f9b5aa 100644 --- a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/alb/ApplicationLoadBalancerServletRequest.java +++ b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/alb/ApplicationLoadBalancerServletRequest.java @@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.net.URI; /** * Implementation of {@link ServletHttpRequest} for Application Load Balancer events. @@ -54,7 +53,11 @@ public ApplicationLoadBalancerServletRequest( super( conversionService, requestEvent, - URI.create(requestEvent.getPath()), + ApiGatewayServletRequest.buildUri( + requestEvent.getPath(), + requestEvent.getQueryStringParameters(), + requestEvent.getMultiValueQueryStringParameters() + ), parseMethod(requestEvent::getHttpMethod), LOG, bodyBuilder diff --git a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload1/ApiGatewayProxyServletRequest.java b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload1/ApiGatewayProxyServletRequest.java index 36a4b637a3..9b949eed6c 100644 --- a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload1/ApiGatewayProxyServletRequest.java +++ b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload1/ApiGatewayProxyServletRequest.java @@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.net.URI; import java.util.Base64; /** @@ -56,7 +55,11 @@ public ApiGatewayProxyServletRequest( super( conversionService, requestEvent, - URI.create(requestEvent.getPath()), + ApiGatewayServletRequest.buildUri( + requestEvent.getPath(), + requestEvent.getQueryStringParameters(), + requestEvent.getMultiValueQueryStringParameters() + ), parseMethod(requestEvent::getHttpMethod), LOG, bodyBuilder diff --git a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload2/APIGatewayV2HTTPEventServletRequest.java b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload2/APIGatewayV2HTTPEventServletRequest.java index 1a2857de67..1f9c947d4f 100644 --- a/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload2/APIGatewayV2HTTPEventServletRequest.java +++ b/function-aws-api-proxy/src/main/java/io/micronaut/function/aws/proxy/payload2/APIGatewayV2HTTPEventServletRequest.java @@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.net.URI; import java.util.Collections; /** @@ -55,7 +54,11 @@ public APIGatewayV2HTTPEventServletRequest( super( conversionService, requestEvent, - URI.create(requestEvent.getRequestContext().getHttp().getPath()), + ApiGatewayServletRequest.buildUri( + requestEvent.getRequestContext().getHttp().getPath(), + requestEvent.getQueryStringParameters(), + Collections.emptyMap() + ), parseMethod(() -> requestEvent.getRequestContext().getHttp().getMethod()), LOG, bodyBuilder diff --git a/test-suite-http-server-tck-function-aws-api-gateway-proxy-alb/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java b/test-suite-http-server-tck-function-aws-api-gateway-proxy-alb/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java new file mode 100644 index 0000000000..a8182f8219 --- /dev/null +++ b/test-suite-http-server-tck-function-aws-api-gateway-proxy-alb/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.lambda.tests; + +import io.micronaut.context.annotation.Requires; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.tck.AssertionUtils; +import io.micronaut.http.tck.HttpResponseAssertion; +import io.micronaut.http.uri.UriBuilder; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static io.micronaut.http.tck.TestScenario.asserts; + +//TODO Delete when https://github.com/micronaut-projects/micronaut-core/pull/9791 +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class RequestUriContainsQueryValueTest { + + public static final String SPEC_NAME = "RequestUriContainsQueryValueTest"; + + @Test + void testRequestUriContainsQueryValue() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET(UriBuilder.of("/requesturi").queryParam("foo", "bar").build()), + (server, request) -> AssertionUtils.assertDoesNotThrow(server, request, + HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .body("/requesturi?foo=bar") + .build())); + } + + @Requires(property = "spec.name", value = SPEC_NAME) + @Controller("/requesturi") + static class TestController { + @Get + String index(HttpRequest request) { + return request.getUri().toASCIIString(); + } + } +} diff --git a/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv1/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java b/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv1/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java new file mode 100644 index 0000000000..a8182f8219 --- /dev/null +++ b/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv1/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.lambda.tests; + +import io.micronaut.context.annotation.Requires; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.tck.AssertionUtils; +import io.micronaut.http.tck.HttpResponseAssertion; +import io.micronaut.http.uri.UriBuilder; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static io.micronaut.http.tck.TestScenario.asserts; + +//TODO Delete when https://github.com/micronaut-projects/micronaut-core/pull/9791 +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class RequestUriContainsQueryValueTest { + + public static final String SPEC_NAME = "RequestUriContainsQueryValueTest"; + + @Test + void testRequestUriContainsQueryValue() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET(UriBuilder.of("/requesturi").queryParam("foo", "bar").build()), + (server, request) -> AssertionUtils.assertDoesNotThrow(server, request, + HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .body("/requesturi?foo=bar") + .build())); + } + + @Requires(property = "spec.name", value = SPEC_NAME) + @Controller("/requesturi") + static class TestController { + @Get + String index(HttpRequest request) { + return request.getUri().toASCIIString(); + } + } +} diff --git a/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv2/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java b/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv2/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java new file mode 100644 index 0000000000..a8182f8219 --- /dev/null +++ b/test-suite-http-server-tck-function-aws-api-gateway-proxy-payloadv2/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.lambda.tests; + +import io.micronaut.context.annotation.Requires; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.tck.AssertionUtils; +import io.micronaut.http.tck.HttpResponseAssertion; +import io.micronaut.http.uri.UriBuilder; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static io.micronaut.http.tck.TestScenario.asserts; + +//TODO Delete when https://github.com/micronaut-projects/micronaut-core/pull/9791 +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class RequestUriContainsQueryValueTest { + + public static final String SPEC_NAME = "RequestUriContainsQueryValueTest"; + + @Test + void testRequestUriContainsQueryValue() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET(UriBuilder.of("/requesturi").queryParam("foo", "bar").build()), + (server, request) -> AssertionUtils.assertDoesNotThrow(server, request, + HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .body("/requesturi?foo=bar") + .build())); + } + + @Requires(property = "spec.name", value = SPEC_NAME) + @Controller("/requesturi") + static class TestController { + @Get + String index(HttpRequest request) { + return request.getUri().toASCIIString(); + } + } +} diff --git a/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/MicronautLambdaHandlerHttpServerTestSuite.java b/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/MicronautLambdaHandlerHttpServerTestSuite.java index 526ab067ad..903f2f905c 100644 --- a/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/MicronautLambdaHandlerHttpServerTestSuite.java +++ b/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/MicronautLambdaHandlerHttpServerTestSuite.java @@ -6,7 +6,10 @@ import org.junit.platform.suite.api.SuiteDisplayName; @Suite -@SelectPackages("io.micronaut.http.server.tck.tests") +@SelectPackages({ + "io.micronaut.http.server.tck.tests", + "io.micronaut.http.server.tck.lambda.tests" +}) @ExcludeClassNamePatterns({ "io.micronaut.http.server.tck.tests.LocalErrorReadingBodyTest", // Binding body different type (e.g. a String in error handler) "io.micronaut.http.server.tck.tests.FilterProxyTest" // Immmutable request diff --git a/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java b/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java new file mode 100644 index 0000000000..a8182f8219 --- /dev/null +++ b/test-suite-http-server-tck-function-aws-api-proxy-test/src/test/java/io/micronaut/http/server/tck/lambda/tests/RequestUriContainsQueryValueTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.lambda.tests; + +import io.micronaut.context.annotation.Requires; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.tck.AssertionUtils; +import io.micronaut.http.tck.HttpResponseAssertion; +import io.micronaut.http.uri.UriBuilder; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static io.micronaut.http.tck.TestScenario.asserts; + +//TODO Delete when https://github.com/micronaut-projects/micronaut-core/pull/9791 +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class RequestUriContainsQueryValueTest { + + public static final String SPEC_NAME = "RequestUriContainsQueryValueTest"; + + @Test + void testRequestUriContainsQueryValue() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET(UriBuilder.of("/requesturi").queryParam("foo", "bar").build()), + (server, request) -> AssertionUtils.assertDoesNotThrow(server, request, + HttpResponseAssertion.builder() + .status(HttpStatus.OK) + .body("/requesturi?foo=bar") + .build())); + } + + @Requires(property = "spec.name", value = SPEC_NAME) + @Controller("/requesturi") + static class TestController { + @Get + String index(HttpRequest request) { + return request.getUri().toASCIIString(); + } + } +}