All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.serverless.proxy.model.ContainerConfig Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2020 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.model;

import com.amazonaws.serverless.proxy.internal.servlet.AwsProxyHttpServletRequest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

/**
 * Configuration parameters for the framework
 */
public class ContainerConfig {
    public static final String DEFAULT_URI_ENCODING = "UTF-8";
    public static final String DEFAULT_CONTENT_CHARSET = "ISO-8859-1";
    private static final List DEFAULT_FILE_PATHS = new ArrayList() {{ add("/tmp"); add("/var/task"); }};
    private static final int DEFAULT_MAX_INIT_TIMEOUT_MS = 20_000;
    private static final String MAX_INIT_TIMEOUT_ENVIRONMENT_VARIABLE_NAME = "AWS_SERVERLESS_JAVA_CONTAINER_MAX_INIT_TIMEOUT";
    private static final int MAX_INIT_TIMEOUT_MS = Integer.parseInt(System.getenv().getOrDefault(
            MAX_INIT_TIMEOUT_ENVIRONMENT_VARIABLE_NAME, Integer.toString(DEFAULT_MAX_INIT_TIMEOUT_MS)));

    public static ContainerConfig defaultConfig() {
        ContainerConfig configuration = new ContainerConfig();
        configuration.setStripBasePath(false);
        configuration.setUriEncoding(DEFAULT_URI_ENCODING);
        configuration.setConsolidateSetCookieHeaders(false);
        configuration.setUseStageAsServletContext(false);
        configuration.setValidFilePaths(DEFAULT_FILE_PATHS);
        configuration.setQueryStringCaseSensitive(false);
        configuration.addBinaryContentTypes("application/octet-stream", "image/jpeg", "image/png", "image/gif");
        configuration.setDefaultContentCharset(DEFAULT_CONTENT_CHARSET);
        configuration.setInitializationTimeout(MAX_INIT_TIMEOUT_MS);
        configuration.setDisableExceptionMapper(false);

        return configuration;
    }

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

    private String serviceBasePath;
    private boolean stripBasePath;
    private String uriEncoding;
    private String defaultContentCharset;
    private boolean consolidateSetCookieHeaders;
    private boolean useStageAsServletContext;
    private List validFilePaths;
    private List customDomainNames;
    private boolean queryStringCaseSensitive;
    private final HashSet binaryContentTypes;
    private int initializationTimeout;
    private boolean disableExceptionMapper;

    public ContainerConfig() {
        validFilePaths = new ArrayList<>();
        customDomainNames = new ArrayList<>();
        binaryContentTypes = new HashSet<>();
    }


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


    /**
     * Returns the base path configured in the container. This configuration variable is used in conjuction with {@link #setStripBasePath(boolean)} to route
     * the request. When requesting the context path from an HttpServletRequest: {@link AwsProxyHttpServletRequest#getContextPath()} this base path is added
     * to the context even though it was initially stripped for the purpose of routing the request. We decided to add it to the context to address GitHub issue
     * #84 and allow framework's link builders to it.
     *
     * @return The base path configured for the container
     */
    public String getServiceBasePath() {
        return serviceBasePath;
    }


    /**
     * Configures a base path  that can be stripped from the request path before passing it to the framework-specific implementation. This can be used to
     * remove API Gateway's base path mappings from the request.
     * @param serviceBasePath The base path mapping to be removed.
     */
    public void setServiceBasePath(String serviceBasePath) {
        if (serviceBasePath == null) {
            this.serviceBasePath = null;
            return;
        }
        // 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;
    }


    /**
     * Whether this framework should strip the base path mapping specified with the {@link #setServiceBasePath(String)} method from a request before
     * passing it to the framework-specific implementations
     * @param stripBasePath
     */
    public void setStripBasePath(boolean stripBasePath) {
        this.stripBasePath = stripBasePath;
    }


    public String getUriEncoding() {
        return uriEncoding;
    }


    /**
     * Sets the charset used to URLEncode and Decode request paths.
     * @param uriEncoding The charset. By default this is set to UTF-8
     */
    public void setUriEncoding(String uriEncoding) {
        this.uriEncoding = uriEncoding;
    }


    public boolean isConsolidateSetCookieHeaders() {
        return consolidateSetCookieHeaders;
    }


    /**
     * Tells the library to consolidate multiple Set-Cookie headers into a single Set-Cookie header with multiple, comma-separated values. This is allowed
     * by the RFC 2109 (https://tools.ietf.org/html/rfc2109). However, since not all clients support this, we consider it optional. When this value is set
     * to true the framework will consolidate all Set-Cookie headers into a single header, when it's set to false, the framework will only return the first
     * Set-Cookie header specified in a response.
     *
     * Because API Gateway needs header keys to be unique, we give an option to configure this.
     * @param consolidateSetCookieHeaders Whether to consolidate the cookie headers or not.
     */
    public void setConsolidateSetCookieHeaders(boolean consolidateSetCookieHeaders) {
        this.consolidateSetCookieHeaders = consolidateSetCookieHeaders;
    }


    /**
     * Tells whether the stage name passed in the request should be added to the context path: {@link AwsProxyHttpServletRequest#getContextPath()}.
     * @return true if the stage will be included in the context path, false otherwise.
     */
    public boolean isUseStageAsServletContext() {
        return useStageAsServletContext;
    }


    /**
     * Sets whether the API Gateway stage name should be included in the servlet context path.
     * @param useStageAsServletContext true if you want the stage to appear as the root of the context path, false otherwise.
     */
    public void setUseStageAsServletContext(boolean useStageAsServletContext) {
        this.useStageAsServletContext = useStageAsServletContext;
    }


    /**
     * Returns the list of file paths that the servlet accepts read/write requests to
     * @return A List of file paths. By default this is set to /tmp and /var/task
     */
    public List getValidFilePaths() {
        return validFilePaths;
    }


    /**
     * Sets a list of valid file paths for the servlet to read/write from.
     * @param validFilePaths A populated list of base paths
     */
    public void setValidFilePaths(List validFilePaths) {
        this.validFilePaths = validFilePaths;
    }


    /**
     * Adds a new base path to the list of allowed paths.
     * @param filePath The base path
     */
    public void addValidFilePath(String filePath) {
        validFilePaths.add(filePath);
    }


    /**
     * Adds a new custom domain name to the list of allowed domains
     * @param name The new custom domain name, excluding the scheme ("https") and port
     */
    public void addCustomDomain(String name) {
        customDomainNames.add(name);
    }


    /**
     * Returns the list of custom domain names enabled for the application
     * @return The configured custom domain names
     */
    public List getCustomDomainNames() {
        return customDomainNames;
    }


    /**
     * Enables localhost custom domain name for testing. This setting should be used only in local
     * with SAM local
     */
    public void enableLocalhost() {
        customDomainNames.add("localhost");
    }


    /**
     * Whether query string parameters in the request should be case sensitive or not. By default
     * this is set to false for backward compatibility.
     * @return true if the parameter matching algorithm is case sensitive
     */
    public boolean isQueryStringCaseSensitive() {
        return queryStringCaseSensitive;
    }


    /**
     * Sets whether query string parameter names should be treated as case sensitive. The default
     * value of this option is false for backward compatibility.
     * @param queryStringCaseSensitive Tells the framework to treat query string parameter names as case sensitive
     */
    public void setQueryStringCaseSensitive(boolean queryStringCaseSensitive) {
        this.queryStringCaseSensitive = queryStringCaseSensitive;
    }

    /**
     * Configure specified content type(s) as binary
     * @param contentTypes list of exact content types that will be considered as binary
     */
    public void addBinaryContentTypes(String... contentTypes) {
        if(contentTypes != null) {
            binaryContentTypes.addAll(Arrays.asList(contentTypes));
        }
    }

    /**
     * Determine if specified content type has been configured as binary
     * @param contentType content type to query
     * @return
     */
    public boolean isBinaryContentType(String contentType) {
        return contentType != null && binaryContentTypes.contains(contentType.trim());
    }


    /**
     * Returns the name of the default charset appended to the Content-Type header if no charset is specified by the request. The
     * default value of this is ISO-8859-1.
     * @return The name of the default charset for the Content-Type header
     */
    public String getDefaultContentCharset() {
        return defaultContentCharset;
    }


    /**
     * Sets the default charset value for the Content-Type header if no charset is specified with a request. The default value of this
     * is ISO-8859-1. If a request specifies a Content-Type header without a charset property, the value of
     * this field is automatically appended to the header.
     * @param defaultContentCharset The name of the charset for the content type header.
     */
    public void setDefaultContentCharset(String defaultContentCharset) {
        this.defaultContentCharset = defaultContentCharset;
    }

    /**
     * Returns the maximum amount of time (in milliseconds) set for the initialization time. See documentation on the
     * {@link #setInitializationTimeout(int)} for additional details.
     * @return The max time allocated for initialization
     */
    public int getInitializationTimeout() {
        return initializationTimeout;
    }

    /**
     * Sets the initialization timeout. When using an async {@link com.amazonaws.serverless.proxy.InitializationWrapper}
     * the underlying framework is initialized in a separate thread. Serverless Java Container will wait for the maximum
     * time available during AWS Lambda's init step (~10 seconds) and then return control to the main thread. In the meanwhile,
     * the initialization process of the underlying framework can continue in a separate thread. AWS Lambda will then call
     * the handler class to handle an event. This timeout is the maximum amount of time Serverless Java Container framework
     * will wait for the underlying framework to initialize before returning an error. By default, this is set to 10 seconds.
     * @param initializationTimeout The maximum amount of time to wait for the underlying framework initialization after
     *                              an event is received in milliseconds.
     */
    public void setInitializationTimeout(int initializationTimeout) {
        this.initializationTimeout = initializationTimeout;
    }

    /**
     * Whether the framework will run exception thrown by the application through the implementation of
     * {@link com.amazonaws.serverless.proxy.ExceptionHandler}. When this parameter is set to false the Lambda
     * container handler object lets the Exception propagate upwards to the Lambda handler class.
     * @return true if exception mapping is disabled, false otherwise.
     */
    public boolean isDisableExceptionMapper() {
        return disableExceptionMapper;
    }

    /**
     * This configuration parameter tells the container whether it should skip exception mapping and simply let any
     * Exception thrown by the underlying application bubble up to the Lambda handler class.
     * @param disable Set this value to true to disable exception mapping, false otherwise.
     */
    public void setDisableExceptionMapper(boolean disable) {
        this.disableExceptionMapper = disable;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy