From 4c1b6f1710a565887df13052b98c6f6a6e74fe03 Mon Sep 17 00:00:00 2001 From: sapessi Date: Wed, 3 May 2017 10:41:09 -0700 Subject: [PATCH 1/2] Changed encodeURL logic in servlet response MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The encodeURL should only encode when it is necessary and it’s adding a session id to the URL for browsers that do not support cookies. The framework doesn’t support cookies or session tracking so changed the methods to return the plain urls. This addresses issue #27 --- .../internal/servlet/AwsHttpServletResponse.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java index 691e4fd59..871f7975e 100644 --- a/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java +++ b/aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java @@ -91,25 +91,29 @@ public boolean containsHeader(String s) { @Override public String encodeURL(String s) { - return URLEncoder.encode(s); + // We do not support session tracking using the URL right now, we do not encode urls + return s; } @Override public String encodeRedirectURL(String s) { - return URLEncoder.encode(s); + // Return the URL without changing it, we do not support session tracking using URLs + return s; } @Override + @Deprecated public String encodeUrl(String s) { - return URLEncoder.encode(s); + return this.encodeURL(s); } @Override + @Deprecated public String encodeRedirectUrl(String s) { - return URLEncoder.encode(s); + return this.encodeRedirectURL(s); } From 37653e0505bafd75d69f7bd42b54510ef1c4b5dd Mon Sep 17 00:00:00 2001 From: sapessi Date: Wed, 3 May 2017 13:24:16 -0700 Subject: [PATCH 2/2] Added Jersey ServletContext factory to address #30 --- README.md | 15 +++--- .../jersey/JerseyAwsProxyRequestReader.java | 4 +- .../AwsProxyServletContextFactory.java | 50 +++++++++++++++++++ .../AwsProxyServletRequestFactory.java} | 28 ++++++++--- .../proxy/test/jersey/EchoJerseyResource.java | 10 ++++ .../proxy/test/jersey/JerseyAwsProxyTest.java | 20 +++++++- 6 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletContextFactory.java rename aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/{JerseyAwsProxyServletRequestFactory.java => factory/AwsProxyServletRequestFactory.java} (63%) diff --git a/README.md b/README.md index 6c088e71a..a081b4d78 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ public class LambdaHandler implements RequestHandler handler = jaxRsApplication); ``` -## Jersey Servlet request -The `aws-serverless-java-container-jersey` includes a Jersey factory class to produce `HttpServletRequest` objects for your methods. First, you will need to register the factory with your Jersey application. +# Jersey Servlet injection +The `aws-serverless-java-container-jersey` includes Jersey factory classes to produce `HttpServletRequest` and `ServletContext` objects for your methods. First, you will need to register the factory with your Jersey application. ```java ResourceConfig app = new ResourceConfig() @@ -124,14 +124,17 @@ ResourceConfig app = new ResourceConfig() .register(new AbstractBinder() { @Override protected void configure() { - bindFactory(JerseyAwsProxyServletRequestFactory.class) + bindFactory(AwsProxyServletRequestFactory.class) .to(HttpServletRequest.class) .in(RequestScoped.class); + bindFactory(AwsProxyServletContextFactory.class) + .to(ServletContext.class) + .in(RequestScoped.class); } }); ``` -Once the factory is registered, you can receive `HttpServletRequest` objects in your methods. +Once the factory is registered, you can receive `HttpServletRequest` and `ServletContext` objects in your methods using the `@Context` annotation. ```java @Path("/my-servlet") @GET diff --git a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyRequestReader.java b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyRequestReader.java index cf699af2d..ced94ba71 100644 --- a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyRequestReader.java +++ b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyRequestReader.java @@ -142,12 +142,12 @@ protected Class getRequestClass() { // Methods - Package //------------------------------------------------------------- - static AwsProxyRequest getCurrentRequest() { + public static AwsProxyRequest getCurrentRequest() { return currentRequest; } - static Context getCurrentLambdaContext() { + public static Context getCurrentLambdaContext() { return currentLambdaContext; } } diff --git a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletContextFactory.java b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletContextFactory.java new file mode 100644 index 000000000..4144d8db6 --- /dev/null +++ b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletContextFactory.java @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance + * with the License. A copy of the License is located at + * + * http://aws.amazon.com/apache2.0/ + * + * or in the "license" file accompanying this file. This file 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 com.amazonaws.serverless.proxy.jersey.factory; + + +import org.glassfish.hk2.api.Factory; + +import javax.servlet.ServletContext; + + +/** + * Implementation of Jersey's Factory object for ServletContext objects. This can be used + * by Jersey to generate a Servlet context given an AwsProxyRequest event. + * + *
+ * 
+ *     ResourceConfig app = new ResourceConfig().packages("my.app.package")
+ *         .register(new AbstractBinder() {
+ *             {@literal @}Override
+ *             protected void configure() {
+ *                 bindFactory(AwsProxyServletContextFactory.class)
+ *                     .to(ServletContext.class)
+ *                     .in(RequestScoped.class);
+ *            }
+ *       });
+ * 
+ * 
+ */ +public class AwsProxyServletContextFactory implements Factory { + @Override + public ServletContext provide() { + return AwsProxyServletRequestFactory.getRequest().getServletContext(); + } + + + @Override + public void dispose(ServletContext servletContext) { + + } +} diff --git a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyServletRequestFactory.java b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletRequestFactory.java similarity index 63% rename from aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyServletRequestFactory.java rename to aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletRequestFactory.java index 27ed940cd..667d5326c 100644 --- a/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyServletRequestFactory.java +++ b/aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/factory/AwsProxyServletRequestFactory.java @@ -10,11 +10,15 @@ * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions * and limitations under the License. */ -package com.amazonaws.serverless.proxy.jersey; +package com.amazonaws.serverless.proxy.jersey.factory; +import com.amazonaws.serverless.exceptions.InvalidRequestEventException; import com.amazonaws.serverless.proxy.internal.AwsProxySecurityContextWriter; import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest; +import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequestReader; +import com.amazonaws.serverless.proxy.jersey.JerseyAwsProxyRequestReader; + import org.glassfish.hk2.api.Factory; import javax.servlet.http.HttpServletRequest; @@ -29,7 +33,7 @@ * .register(new AbstractBinder() { * {@literal @}Override * protected void configure() { - * bindFactory(JerseyAwsProxyServletRequestFactory.class) + * bindFactory(AwsProxyServletRequestFactory.class) * .to(HttpServletRequest.class) * .in(RequestScoped.class); * } @@ -37,22 +41,34 @@ * * */ -public class JerseyAwsProxyServletRequestFactory +public class AwsProxyServletRequestFactory implements Factory { + private static AwsProxyHttpServletRequestReader requestReader = new AwsProxyHttpServletRequestReader(); + //------------------------------------------------------------- // Implementation - Factory //------------------------------------------------------------- @Override public HttpServletRequest provide() { - return new AwsProxyHttpServletRequest(JerseyAwsProxyRequestReader.getCurrentRequest(), - JerseyAwsProxyRequestReader.getCurrentLambdaContext(), - AwsProxySecurityContextWriter.getCurrentContext()); + return getRequest(); } @Override public void dispose(HttpServletRequest httpServletRequest) { } + + public static HttpServletRequest getRequest() { + try { + return requestReader.readRequest(JerseyAwsProxyRequestReader.getCurrentRequest(), + AwsProxySecurityContextWriter.getCurrentContext(), + JerseyAwsProxyRequestReader.getCurrentLambdaContext()); + } catch (InvalidRequestEventException e) { + e.printStackTrace(); + return null; + } + + } } diff --git a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/EchoJerseyResource.java b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/EchoJerseyResource.java index 1715d6b63..33d54392d 100644 --- a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/EchoJerseyResource.java +++ b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/EchoJerseyResource.java @@ -17,6 +17,7 @@ import com.amazonaws.serverless.proxy.test.jersey.model.MapResponseModel; import com.amazonaws.serverless.proxy.test.jersey.model.SingleValueModel; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; import javax.ws.rs.container.ContainerRequestContext; @@ -57,6 +58,15 @@ public MapResponseModel echoServletHeaders(@Context HttpServletRequest context) return headers; } + @Path("/servlet-context") @GET + @Produces(MediaType.APPLICATION_JSON) + public SingleValueModel echoContextInformation(@Context ServletContext context) { + SingleValueModel singleValueModel = new SingleValueModel(); + singleValueModel.setValue(context.getServerInfo()); + + return singleValueModel; + } + @Path("/query-string") @GET @Produces(MediaType.APPLICATION_JSON) public MapResponseModel echoQueryString(@Context UriInfo context) { diff --git a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/JerseyAwsProxyTest.java b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/JerseyAwsProxyTest.java index a467c0662..781af55d9 100644 --- a/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/JerseyAwsProxyTest.java +++ b/aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/JerseyAwsProxyTest.java @@ -15,7 +15,9 @@ import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest; import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse; -import com.amazonaws.serverless.proxy.jersey.JerseyAwsProxyServletRequestFactory; +import com.amazonaws.serverless.proxy.internal.servlet.AwsServletContext; +import com.amazonaws.serverless.proxy.jersey.factory.AwsProxyServletContextFactory; +import com.amazonaws.serverless.proxy.jersey.factory.AwsProxyServletRequestFactory; import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler; import com.amazonaws.serverless.proxy.test.jersey.model.MapResponseModel; import com.amazonaws.serverless.proxy.test.jersey.model.SingleValueModel; @@ -31,6 +33,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.junit.Test; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @@ -52,9 +55,12 @@ public class JerseyAwsProxyTest { .register(new AbstractBinder() { @Override protected void configure() { - bindFactory(JerseyAwsProxyServletRequestFactory.class) + bindFactory(AwsProxyServletRequestFactory.class) .to(HttpServletRequest.class) .in(RequestScoped.class); + bindFactory(AwsProxyServletContextFactory.class) + .to(ServletContext.class) + .in(RequestScoped.class); } }); private static JerseyLambdaContainerHandler handler = JerseyLambdaContainerHandler.getAwsProxyHandler(app); @@ -89,6 +95,16 @@ public void headers_servletRequest_echo() { validateMapResponseModel(output); } + @Test + public void context_serverInfo_correctContext() { + AwsProxyRequest request = new AwsProxyRequestBuilder("/echo/servlet-context", "GET").build(); + AwsProxyResponse output = handler.proxy(request, lambdaContext); + assertEquals(200, output.getStatusCode()); + assertEquals("application/json", output.getHeaders().get("Content-Type")); + + validateSingleValueModel(output, AwsServletContext.SERVER_INFO); + } + @Test public void queryString_uriInfo_echo() { AwsProxyRequest request = new AwsProxyRequestBuilder("/echo/query-string", "GET")