Skip to content

Commit 9d16cff

Browse files
authored
Merge pull request #32 from awslabs/servlet-improvements
Merging bug fixes
2 parents 463295d + 37653e0 commit 9d16cff

File tree

7 files changed

+119
-20
lines changed

7 files changed

+119
-20
lines changed

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public class LambdaHandler implements RequestHandler<AwsProxyRequest, AwsProxyRe
8585
}
8686
```
8787

88-
## Security context
88+
# Security context
8989
The `aws-serverless-java-container-core` contains a default implementation of the `SecurityContextWriter` that supports API Gateway's proxy integration. The generated security context uses the API Gateway `$context` object to establish the request security context. The context looks for the following values in order and returns the first matched type:
9090

9191
1. Cognito My User Pools
@@ -98,7 +98,7 @@ The String values for these are exposed as static variables in the `AwsProxySecu
9898
2. `AUTH_SCHEME_CUSTOM`
9999
3. `AUTH_SCHEME_IAM`
100100

101-
## Supporting other event types
101+
# Supporting other event types
102102
The `RequestReader` and `ResponseWriter` interfaces in the core package can be used to support event types and generate different responses. For example, ff you have configured mapping templates in
103103
API Gateway to create a custom event body or response you can create your own implementation of the `RequestReader` and `ResponseWriter` to handle these.
104104

@@ -115,23 +115,26 @@ JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler =
115115
jaxRsApplication);
116116
```
117117

118-
## Jersey Servlet request
119-
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.
118+
# Jersey Servlet injection
119+
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.
120120

121121
```java
122122
ResourceConfig app = new ResourceConfig()
123123
.packages("com.amazonaws.serverless.proxy.test.jersey")
124124
.register(new AbstractBinder() {
125125
@Override
126126
protected void configure() {
127-
bindFactory(JerseyAwsProxyServletRequestFactory.class)
127+
bindFactory(AwsProxyServletRequestFactory.class)
128128
.to(HttpServletRequest.class)
129129
.in(RequestScoped.class);
130+
bindFactory(AwsProxyServletContextFactory.class)
131+
.to(ServletContext.class)
132+
.in(RequestScoped.class);
130133
}
131134
});
132135
```
133136

134-
Once the factory is registered, you can receive `HttpServletRequest` objects in your methods.
137+
Once the factory is registered, you can receive `HttpServletRequest` and `ServletContext` objects in your methods using the `@Context` annotation.
135138

136139
```java
137140
@Path("/my-servlet") @GET

aws-serverless-java-container-core/src/main/java/com/amazonaws/serverless/proxy/internal/servlet/AwsHttpServletResponse.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,29 @@ public boolean containsHeader(String s) {
9191

9292
@Override
9393
public String encodeURL(String s) {
94-
return URLEncoder.encode(s);
94+
// We do not support session tracking using the URL right now, we do not encode urls
95+
return s;
9596
}
9697

9798

9899
@Override
99100
public String encodeRedirectURL(String s) {
100-
return URLEncoder.encode(s);
101+
// Return the URL without changing it, we do not support session tracking using URLs
102+
return s;
101103
}
102104

103105

104106
@Override
107+
@Deprecated
105108
public String encodeUrl(String s) {
106-
return URLEncoder.encode(s);
109+
return this.encodeURL(s);
107110
}
108111

109112

110113
@Override
114+
@Deprecated
111115
public String encodeRedirectUrl(String s) {
112-
return URLEncoder.encode(s);
116+
return this.encodeRedirectURL(s);
113117
}
114118

115119

aws-serverless-java-container-jersey/src/main/java/com/amazonaws/serverless/proxy/jersey/JerseyAwsProxyRequestReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ protected Class<? extends AwsProxyRequest> getRequestClass() {
142142
// Methods - Package
143143
//-------------------------------------------------------------
144144

145-
static AwsProxyRequest getCurrentRequest() {
145+
public static AwsProxyRequest getCurrentRequest() {
146146
return currentRequest;
147147
}
148148

149149

150-
static Context getCurrentLambdaContext() {
150+
public static Context getCurrentLambdaContext() {
151151
return currentLambdaContext;
152152
}
153153
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
5+
* with the License. A copy of the License is located at
6+
*
7+
* http://aws.amazon.com/apache2.0/
8+
*
9+
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
10+
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11+
* and limitations under the License.
12+
*/
13+
package com.amazonaws.serverless.proxy.jersey.factory;
14+
15+
16+
import org.glassfish.hk2.api.Factory;
17+
18+
import javax.servlet.ServletContext;
19+
20+
21+
/**
22+
* Implementation of Jersey's <code>Factory</code> object for <code>ServletContext</code> objects. This can be used
23+
* by Jersey to generate a Servlet context given an <code>AwsProxyRequest</code> event.
24+
*
25+
* <pre>
26+
* <code>
27+
* ResourceConfig app = new ResourceConfig().packages("my.app.package")
28+
* .register(new AbstractBinder() {
29+
* {@literal @}Override
30+
* protected void configure() {
31+
* bindFactory(AwsProxyServletContextFactory.class)
32+
* .to(ServletContext.class)
33+
* .in(RequestScoped.class);
34+
* }
35+
* });
36+
* </code>
37+
* </pre>
38+
*/
39+
public class AwsProxyServletContextFactory implements Factory<ServletContext> {
40+
@Override
41+
public ServletContext provide() {
42+
return AwsProxyServletRequestFactory.getRequest().getServletContext();
43+
}
44+
45+
46+
@Override
47+
public void dispose(ServletContext servletContext) {
48+
49+
}
50+
}
Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010
* OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
1111
* and limitations under the License.
1212
*/
13-
package com.amazonaws.serverless.proxy.jersey;
13+
package com.amazonaws.serverless.proxy.jersey.factory;
1414

1515

16+
import com.amazonaws.serverless.exceptions.InvalidRequestEventException;
1617
import com.amazonaws.serverless.proxy.internal.AwsProxySecurityContextWriter;
1718
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest;
19+
import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequestReader;
20+
import com.amazonaws.serverless.proxy.jersey.JerseyAwsProxyRequestReader;
21+
1822
import org.glassfish.hk2.api.Factory;
1923

2024
import javax.servlet.http.HttpServletRequest;
@@ -29,30 +33,42 @@
2933
* .register(new AbstractBinder() {
3034
* {@literal @}Override
3135
* protected void configure() {
32-
* bindFactory(JerseyAwsProxyServletRequestFactory.class)
36+
* bindFactory(AwsProxyServletRequestFactory.class)
3337
* .to(HttpServletRequest.class)
3438
* .in(RequestScoped.class);
3539
* }
3640
* });
3741
* </code>
3842
* </pre>
3943
*/
40-
public class JerseyAwsProxyServletRequestFactory
44+
public class AwsProxyServletRequestFactory
4145
implements Factory<HttpServletRequest> {
4246

47+
private static AwsProxyHttpServletRequestReader requestReader = new AwsProxyHttpServletRequestReader();
48+
4349
//-------------------------------------------------------------
4450
// Implementation - Factory
4551
//-------------------------------------------------------------
4652

4753
@Override
4854
public HttpServletRequest provide() {
49-
return new AwsProxyHttpServletRequest(JerseyAwsProxyRequestReader.getCurrentRequest(),
50-
JerseyAwsProxyRequestReader.getCurrentLambdaContext(),
51-
AwsProxySecurityContextWriter.getCurrentContext());
55+
return getRequest();
5256
}
5357

5458

5559
@Override
5660
public void dispose(HttpServletRequest httpServletRequest) {
5761
}
62+
63+
public static HttpServletRequest getRequest() {
64+
try {
65+
return requestReader.readRequest(JerseyAwsProxyRequestReader.getCurrentRequest(),
66+
AwsProxySecurityContextWriter.getCurrentContext(),
67+
JerseyAwsProxyRequestReader.getCurrentLambdaContext());
68+
} catch (InvalidRequestEventException e) {
69+
e.printStackTrace();
70+
return null;
71+
}
72+
73+
}
5874
}

aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/EchoJerseyResource.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.amazonaws.serverless.proxy.test.jersey.model.MapResponseModel;
1818
import com.amazonaws.serverless.proxy.test.jersey.model.SingleValueModel;
1919

20+
import javax.servlet.ServletContext;
2021
import javax.servlet.http.HttpServletRequest;
2122
import javax.ws.rs.*;
2223
import javax.ws.rs.container.ContainerRequestContext;
@@ -57,6 +58,15 @@ public MapResponseModel echoServletHeaders(@Context HttpServletRequest context)
5758
return headers;
5859
}
5960

61+
@Path("/servlet-context") @GET
62+
@Produces(MediaType.APPLICATION_JSON)
63+
public SingleValueModel echoContextInformation(@Context ServletContext context) {
64+
SingleValueModel singleValueModel = new SingleValueModel();
65+
singleValueModel.setValue(context.getServerInfo());
66+
67+
return singleValueModel;
68+
}
69+
6070
@Path("/query-string") @GET
6171
@Produces(MediaType.APPLICATION_JSON)
6272
public MapResponseModel echoQueryString(@Context UriInfo context) {

aws-serverless-java-container-jersey/src/test/java/com/amazonaws/serverless/proxy/test/jersey/JerseyAwsProxyTest.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
import com.amazonaws.serverless.proxy.internal.model.AwsProxyRequest;
1717
import com.amazonaws.serverless.proxy.internal.model.AwsProxyResponse;
18-
import com.amazonaws.serverless.proxy.jersey.JerseyAwsProxyServletRequestFactory;
18+
import com.amazonaws.serverless.proxy.internal.servlet.AwsServletContext;
19+
import com.amazonaws.serverless.proxy.jersey.factory.AwsProxyServletContextFactory;
20+
import com.amazonaws.serverless.proxy.jersey.factory.AwsProxyServletRequestFactory;
1921
import com.amazonaws.serverless.proxy.jersey.JerseyLambdaContainerHandler;
2022
import com.amazonaws.serverless.proxy.test.jersey.model.MapResponseModel;
2123
import com.amazonaws.serverless.proxy.test.jersey.model.SingleValueModel;
@@ -31,6 +33,7 @@
3133
import org.glassfish.jersey.server.ResourceConfig;
3234
import org.junit.Test;
3335

36+
import javax.servlet.ServletContext;
3437
import javax.servlet.http.HttpServletRequest;
3538

3639
import java.io.IOException;
@@ -52,9 +55,12 @@ public class JerseyAwsProxyTest {
5255
.register(new AbstractBinder() {
5356
@Override
5457
protected void configure() {
55-
bindFactory(JerseyAwsProxyServletRequestFactory.class)
58+
bindFactory(AwsProxyServletRequestFactory.class)
5659
.to(HttpServletRequest.class)
5760
.in(RequestScoped.class);
61+
bindFactory(AwsProxyServletContextFactory.class)
62+
.to(ServletContext.class)
63+
.in(RequestScoped.class);
5864
}
5965
});
6066
private static JerseyLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler = JerseyLambdaContainerHandler.getAwsProxyHandler(app);
@@ -89,6 +95,16 @@ public void headers_servletRequest_echo() {
8995
validateMapResponseModel(output);
9096
}
9197

98+
@Test
99+
public void context_serverInfo_correctContext() {
100+
AwsProxyRequest request = new AwsProxyRequestBuilder("/echo/servlet-context", "GET").build();
101+
AwsProxyResponse output = handler.proxy(request, lambdaContext);
102+
assertEquals(200, output.getStatusCode());
103+
assertEquals("application/json", output.getHeaders().get("Content-Type"));
104+
105+
validateSingleValueModel(output, AwsServletContext.SERVER_INFO);
106+
}
107+
92108
@Test
93109
public void queryString_uriInfo_echo() {
94110
AwsProxyRequest request = new AwsProxyRequestBuilder("/echo/query-string", "GET")

0 commit comments

Comments
 (0)