Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions aws-serverless-java-container-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@
<version>1.10.19</version>
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package com.amazonaws.serverless.proxy.internal;


import com.amazonaws.serverless.proxy.internal.model.ContainerConfig;
import com.amazonaws.services.lambda.runtime.Context;

import javax.ws.rs.core.SecurityContext;
Expand All @@ -36,6 +37,7 @@ public abstract class LambdaContainerHandler<RequestType, ResponseType, Containe

public static final String SERVER_INFO = "aws-serverless-java-container";


//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------
Expand All @@ -45,6 +47,15 @@ public abstract class LambdaContainerHandler<RequestType, ResponseType, Containe
private SecurityContextWriter<RequestType> securityContextWriter;
private ExceptionHandler<ResponseType> exceptionHandler;

protected Context lambdaContext;


//-------------------------------------------------------------
// Variables - Private - Static
//-------------------------------------------------------------

private static ContainerConfig config = ContainerConfig.defaultConfig();


//-------------------------------------------------------------
// Constructors
Expand Down Expand Up @@ -76,6 +87,19 @@ protected abstract void handleRequest(ContainerRequestType containerRequest, Con
// Methods - Public
//-------------------------------------------------------------

/**
* Configures the library to strip a base path from incoming requests before passing them on to the wrapped
* framework. This was added in response to issue #34 (https://github.com/awslabs/aws-serverless-java-container/issues/34).
* When creating a base path mapping for custom domain names in API Gateway we want to be able to strip the base path
* from the request - the underlying service may not recognize this path.
* @param basePath The base path to be stripped from the request
*/
public void stripBasePath(String basePath) {
config.setStripBasePath(true);
config.setServiceBasePath(basePath);
}


/**
* Proxies requests to the underlying container given the incoming Lambda request. This method returns a populated
* return object for the Lambda function.
Expand All @@ -85,11 +109,12 @@ protected abstract void handleRequest(ContainerRequestType containerRequest, Con
* @return A valid response type
*/
public ResponseType proxy(RequestType request, Context context) {
lambdaContext = context;
try {
SecurityContext securityContext = securityContextWriter.writeSecurityContext(request, context);
CountDownLatch latch = new CountDownLatch(1);
ContainerResponseType containerResponse = getContainerResponse(latch);
ContainerRequestType containerRequest = requestReader.readRequest(request, securityContext, context);
ContainerRequestType containerRequest = requestReader.readRequest(request, securityContext, context, config);

handleRequest(containerRequest, containerResponse, context);

Expand All @@ -98,13 +123,22 @@ public ResponseType proxy(RequestType request, Context context) {
return responseWriter.writeResponse(containerResponse, context);
} catch (Exception e) {
context.getLogger().log("Error while handling request: " + e.getMessage());

/*for (StackTraceElement el : e.getStackTrace()) {
context.getLogger().log(el.toString());
}*/
e.printStackTrace();

return exceptionHandler.handle(e);
}
}


//-------------------------------------------------------------
// Methods - Getter/Setter
//-------------------------------------------------------------

/**
* Returns the current container configuration object.
* @return
*/
public static ContainerConfig getContainerConfig() {
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


import com.amazonaws.serverless.exceptions.InvalidRequestEventException;
import com.amazonaws.serverless.proxy.internal.model.ContainerConfig;
import com.amazonaws.services.lambda.runtime.Context;

import com.fasterxml.jackson.databind.ObjectMapper;
Expand Down Expand Up @@ -67,9 +68,36 @@ public abstract class RequestReader<RequestType, ContainerRequestType> {
* @return A valid request object for the underlying container
* @throws InvalidRequestEventException This exception is thrown if anything goes wrong during the creation of the request object
*/
protected abstract ContainerRequestType readRequest(RequestType request, SecurityContext securityContext, Context lambdaContext)
protected abstract ContainerRequestType readRequest(RequestType request, SecurityContext securityContext, Context lambdaContext, ContainerConfig config)
throws InvalidRequestEventException;


protected abstract Class<? extends RequestType> getRequestClass();


//-------------------------------------------------------------
// Methods - Protected
//-------------------------------------------------------------

/**
* Strips the base path from the request path if the container configuration object requires it
* @param requestPath The incoming request path
* @param config The container configuration object
* @return The final request path
*/
protected String stripBasePath(String requestPath, ContainerConfig config) {
if (!config.isStripBasePath()) {
return requestPath;
}

if (requestPath.startsWith(config.getServiceBasePath())) {
String newRequestPath = requestPath.replaceFirst(config.getServiceBasePath(), "");
if (!newRequestPath.startsWith("/")) {
newRequestPath = "/" + newRequestPath;
}
return newRequestPath;
}

return requestPath;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.amazonaws.serverless.proxy.internal.model;


/**
* Configuration paramters used by the <code>RequestReader</code> and <code>ResponseWriter</code> objects.
*/
public class ContainerConfig {

public static ContainerConfig defaultConfig() {
ContainerConfig configuration = new ContainerConfig();
configuration.setStripBasePath(false);

return configuration;
}

//-------------------------------------------------------------
// Variables - Private
//-------------------------------------------------------------

private String serviceBasePath;
private boolean stripBasePath;


//-------------------------------------------------------------
// Methods - Getter/Setter
//-------------------------------------------------------------

public String getServiceBasePath() {
return serviceBasePath;
}


public void setServiceBasePath(String serviceBasePath) {
// clean up base path before setting it, we want a "/" at the beginning but not at the end.
String finalBasePath = serviceBasePath;
if (!finalBasePath.startsWith("/")) {
finalBasePath = "/" + serviceBasePath;
}
if (finalBasePath.endsWith("/")) {
finalBasePath = finalBasePath.substring(0, finalBasePath.length() - 1);
}
this.serviceBasePath = finalBasePath;
}


public boolean isStripBasePath() {
return stripBasePath;
}


public void setStripBasePath(boolean stripBasePath) {
this.stripBasePath = stripBasePath;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


Expand Down Expand Up @@ -56,6 +62,9 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {

private Context lambdaContext;
private Map<String, Object> attributes;
private ServletContext servletContext;

protected DispatcherType dispatcherType;


//-------------------------------------------------------------
Expand All @@ -72,6 +81,7 @@ public abstract class AwsHttpServletRequest implements HttpServletRequest {
attributes = new HashMap<>();
}


//-------------------------------------------------------------
// Implementation - HttpServletRequest
//-------------------------------------------------------------
Expand Down Expand Up @@ -119,6 +129,7 @@ public boolean isRequestedSessionIdFromURL() {


@Override
@Deprecated
public boolean isRequestedSessionIdFromUrl() {
return false;
}
Expand Down Expand Up @@ -185,7 +196,7 @@ public int getLocalPort() {

@Override
public ServletContext getServletContext() {
return AwsServletContext.getInstance(lambdaContext);
return servletContext;
}


Expand Down Expand Up @@ -213,6 +224,19 @@ public DispatcherType getDispatcherType() {
}


//-------------------------------------------------------------
// Methods - Getter/Setter
//-------------------------------------------------------------

public void setDispatcherType(DispatcherType type) {
dispatcherType = type;
}

public void setServletContext(ServletContext context) {
servletContext = context;
}


//-------------------------------------------------------------
// Methods - Protected
//-------------------------------------------------------------
Expand All @@ -223,7 +247,6 @@ public DispatcherType getDispatcherType() {
* @return An array of Cookie objects from the header
*/
protected Cookie[] parseCookieHeaderValue(String headerValue) {

List<Map.Entry<String, String>> parsedHeaders = this.parseHeaderValue(headerValue);

return parsedHeaders.stream()
Expand All @@ -232,6 +255,7 @@ protected Cookie[] parseCookieHeaderValue(String headerValue) {
.toArray(Cookie[]::new);
}


/**
* Given a map of key/values query string parameters from API Gateway, creates a query string as it would have
* been in the original url.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public void setStatus(int i) {


@Override
@Deprecated
public void setStatus(int i, String s) {
statusCode = i;
statusMessage = s;
Expand Down
Loading