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

com.amazonaws.util.RuntimeHttpUtils Maven / Gradle / Ivy

Go to download

The AWS SDK for Java - Core module holds the classes that are used by the individual service clients to interact with Amazon Web Services. Users need to depend on aws-java-sdk artifact for accessing individual client classes.

There is a newer version: 1.12.778
Show newest version
/*
 * Copyright 2010-2024 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.util;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.Request;
import com.amazonaws.SdkClientException;
import com.amazonaws.annotation.SdkProtectedApi;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.ProviderNameAware;
import com.amazonaws.retry.RetryMode;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.NTCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.Map;

public class RuntimeHttpUtils {
    private static final String COMMA = ", ";
    private static final String SPACE = " ";

    private static final String AWS_EXECUTION_ENV_PREFIX = "exec-env/";
    private static final String AWS_EXECUTION_ENV_NAME = "AWS_EXECUTION_ENV";

    private static final String RETRY_MODE_PREFIX = "cfg/retry-mode/";
    private static final String PROVIDER_NAME_PREFIX = "cfg/auth-source#";

    private static final String TRACE_ID_ENVIRONMENT_VARIABLE = "_X_AMZN_TRACE_ID";
    private static final String TRACE_ID_SYSTEM_PROPERTY = "com.amazonaws.xray.traceHeader";
    private static final String LAMBDA_FUNCTION_NAME_ENVIRONMENT_VARIABLE = "AWS_LAMBDA_FUNCTION_NAME";


    /**
     * Fetches a file from the URI given and returns an input stream to it.
     *
     * @param uri the uri of the file to fetch
     * @param config optional configuration overrides
     * @return an InputStream containing the retrieved data
     * @throws IOException on error
     */
    @SuppressWarnings("deprecation")
    public static InputStream fetchFile(
            final URI uri,
            final ClientConfiguration config) throws IOException {

        HttpParams httpClientParams = new BasicHttpParams();
        HttpProtocolParams.setUserAgent(
                httpClientParams, getUserAgent(config, null));

        HttpConnectionParams.setConnectionTimeout(
                httpClientParams, getConnectionTimeout(config));
        HttpConnectionParams.setSoTimeout(
                httpClientParams, getSocketTimeout(config));

        DefaultHttpClient httpclient = new DefaultHttpClient(httpClientParams);

        if (config != null) {
            String proxyHost = config.getProxyHost();
            int proxyPort = config.getProxyPort();

            if (proxyHost != null && proxyPort > 0) {

                HttpHost proxy = new HttpHost(proxyHost, proxyPort);
                httpclient.getParams().setParameter(
                        ConnRoutePNames.DEFAULT_PROXY, proxy);

                if (config.getProxyUsername() != null
                    && config.getProxyPassword() != null) {

                    httpclient.getCredentialsProvider().setCredentials(
                            new AuthScope(proxyHost, proxyPort),
                            new NTCredentials(config.getProxyUsername(),
                                              config.getProxyPassword(),
                                              config.getProxyWorkstation(),
                                              config.getProxyDomain()));
                }
            }
        }

        HttpResponse response = httpclient.execute(new HttpGet(uri));

        if (response.getStatusLine().getStatusCode() != 200) {
            throw new IOException("Error fetching file from " + uri + ": "
                                  + response);
        }

        return new HttpClientWrappingInputStream(
                httpclient,
                response.getEntity().getContent());
    }

    public static String getUserAgent(final ClientConfiguration config, final String userAgentMarker) {
        return getUserAgent(config, userAgentMarker, null);
    }

    public static String getUserAgent(final ClientConfiguration config, final String userAgentMarker,
                                      AWSCredentials credentials) {

        String userDefinedPrefix = "";
        String userDefinedSuffix = "";
        String retryModeName = "";
        String awsExecutionEnvironment = getEnvironmentVariable(AWS_EXECUTION_ENV_NAME);
        String providerName = getProviderName(credentials);

        if (config != null) {
            userDefinedPrefix = config.getUserAgentPrefix();
            userDefinedSuffix = config.getUserAgentSuffix();
            RetryMode retryMode = config.getRetryMode() == null ? config.getRetryPolicy().getRetryMode() : config.getRetryMode();
            retryModeName = retryMode != null ? retryMode.getName() : "";
        }

        StringBuilder userAgent = new StringBuilder(userDefinedPrefix.trim());

        if(!ClientConfiguration.DEFAULT_USER_AGENT.equals(userDefinedPrefix)) {
            userAgent.append(COMMA).append(ClientConfiguration.DEFAULT_USER_AGENT);
        }

        if(StringUtils.hasValue(retryModeName)) {
            userAgent.append(SPACE).append(RETRY_MODE_PREFIX).append(retryModeName.trim());
        }

        if (StringUtils.hasValue(providerName)) {
            userAgent.append(SPACE).append(PROVIDER_NAME_PREFIX).append(providerName);
        }

        if(StringUtils.hasValue(userDefinedSuffix)) {
            userAgent.append(COMMA).append(userDefinedSuffix.trim());
        }

        if(StringUtils.hasValue(awsExecutionEnvironment)) {
            userAgent.append(SPACE).append(AWS_EXECUTION_ENV_PREFIX).append(awsExecutionEnvironment.trim());
        }

        if(StringUtils.hasValue(userAgentMarker)) {
            userAgent.append(SPACE).append(userAgentMarker.trim());
        }

        return userAgent.toString();
    }

    private static String getProviderName(AWSCredentials credentials) {
        if (credentials instanceof ProviderNameAware) {
            ProviderNameAware providerNameAwareCredentials = (ProviderNameAware) credentials;
            return CredentialsProviderNameMapping.mapFrom(providerNameAwareCredentials.getProviderName());
        }
        return null;
    }

    private static String getEnvironmentVariable(String environmentVariableName) {
        try {
            return System.getenv(environmentVariableName);
        } catch (Exception e) {
            // Return an empty string if unable to get environment variable
            return "";
        }
    }

    private static String getSystemProperty(String systemProperty) {
        try {
            return System.getProperty(systemProperty);
        } catch (Exception e) {
            return null;
        }
    }

    private static int getConnectionTimeout(final ClientConfiguration config) {
        if (config != null) {
            return config.getConnectionTimeout();
        }
        return ClientConfiguration.DEFAULT_CONNECTION_TIMEOUT;
    }

    private static int getSocketTimeout(final ClientConfiguration config) {
        if (config != null) {
            return config.getSocketTimeout();
        }
        return ClientConfiguration.DEFAULT_SOCKET_TIMEOUT;
    }

    /**
     * Returns an URI for the given endpoint.
     * Prefixes the protocol if the endpoint given does not have it.
     *
     * @throws IllegalArgumentException if the inputs are null.
     */
    public static URI toUri(String endpoint, ClientConfiguration config) {

        if (config == null) {
            throw new IllegalArgumentException("ClientConfiguration cannot be null");
        }
        return toUri(endpoint, config.getProtocol());
    }

    /**
     * Returns an URI for the given endpoint.
     * Prefixes the protocol if the endpoint given does not have it.
     *
     * @throws IllegalArgumentException if the inputs are null.
     */
    public static URI toUri(String endpoint, Protocol protocol) {
        if (endpoint == null) {
            throw new IllegalArgumentException("endpoint cannot be null");
        }

        /*
         * If the endpoint doesn't explicitly specify a protocol to use, then
         * we'll defer to the default protocol specified in the client
         * configuration.
         */
        if (!endpoint.contains("://")) {
            endpoint = protocol.toString() + "://" + endpoint;
        }

        try {
            return new URI(endpoint);
        } catch (URISyntaxException e) {
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Converts the specified request object into a URL, containing all the specified parameters, the specified request endpoint,
     * etc.
     *
     * @param request                          The request to convert into a URL.
     * @param removeLeadingSlashInResourcePath Whether the leading slash in resource-path should be removed before appending to
     *                                         the endpoint.
     * @param urlEncode                        True if request resource path should be URL encoded
     * @return A new URL representing the specified request.
     * @throws SdkClientException If the request cannot be converted to a well formed URL.
     */
    @SdkProtectedApi
    public static URL convertRequestToUrl(Request request,
                                          boolean removeLeadingSlashInResourcePath,
                                          boolean urlEncode) {
        String resourcePath = urlEncode ?
                SdkHttpUtils.urlEncode(request.getResourcePath(), true)
                : request.getResourcePath();

        // Removed the padding "/" that was already added into the request's resource path.
        if (removeLeadingSlashInResourcePath
            && resourcePath.startsWith("/")) {
            resourcePath = resourcePath.substring(1);
        }

        // Some http client libraries (e.g. Apache HttpClient) cannot handle
        // consecutive "/"s between URL authority and path components.
        // So we escape "////..." into "/%2F%2F%2F...", in the same way as how
        // we treat consecutive "/"s in AmazonS3Client#presignRequest(...)

        String urlPath = "/" + resourcePath;
        urlPath = urlPath.replaceAll("(?<=/)/", "%2F");
        StringBuilder url = new StringBuilder(request.getEndpoint().toString());
        url.append(urlPath);

        StringBuilder queryParams = new StringBuilder();
        Map> requestParams = request.getParameters();
        for (Map.Entry> entry : requestParams.entrySet()) {
            for (String value : entry.getValue()) {
                queryParams = queryParams.length() > 0 ? queryParams
                        .append("&") : queryParams.append("?");
                queryParams.append(SdkHttpUtils.urlEncode(entry.getKey(), false))
                        .append("=")
                        .append(SdkHttpUtils.urlEncode(value, false));
            }
        }
        url.append(queryParams.toString());

        try {
            return new URL(url.toString());
        } catch (MalformedURLException e) {
            throw new SdkClientException(
                    "Unable to convert request to well formed URL: " + e.getMessage(), e);
        }
    }

    /**
     * Returns the value of the trace id environment variable, if it exists and if there is also
     * a lambda function name environment variable, indicating that the code executes within a lambda
     */
    public static String getLambdaEnvironmentTraceId() {
        String lambdafunctionName = getEnvironmentVariable(LAMBDA_FUNCTION_NAME_ENVIRONMENT_VARIABLE);
        String traceId = traceId();
        if (!StringUtils.isNullOrEmpty(lambdafunctionName) && !StringUtils.isNullOrEmpty(traceId)) {
            return traceId;
        };
        return null;
    }

    static String traceId() {
        String traceId = getSystemProperty(TRACE_ID_SYSTEM_PROPERTY);
        if (traceId == null) {
            traceId = getEnvironmentVariable(TRACE_ID_ENVIRONMENT_VARIABLE);
        }
        return traceId;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy