Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
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.
/*
* 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.http;
import static com.amazonaws.SDKGlobalConfiguration.PROFILING_SYSTEM_PROPERTY;
import static com.amazonaws.event.SDKProgressPublisher.publishProgress;
import static com.amazonaws.event.SDKProgressPublisher.publishRequestContentLength;
import static com.amazonaws.event.SDKProgressPublisher.publishResponseContentLength;
import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolAvailableCount;
import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolLeasedCount;
import static com.amazonaws.util.AWSRequestMetrics.Field.HttpClientPoolPendingCount;
import static com.amazonaws.util.AWSRequestMetrics.Field.ThrottledRetryCount;
import static com.amazonaws.util.AwsClientSideMonitoringMetrics.MaxRetriesExceeded;
import static com.amazonaws.util.IOUtils.closeQuietly;
import com.amazonaws.AbortedException;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.AmazonWebServiceRequest;
import com.amazonaws.AmazonWebServiceResponse;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.Request;
import com.amazonaws.RequestClientOptions;
import com.amazonaws.RequestClientOptions.Marker;
import com.amazonaws.RequestConfig;
import com.amazonaws.ResetException;
import com.amazonaws.Response;
import com.amazonaws.ResponseMetadata;
import com.amazonaws.SDKGlobalTime;
import com.amazonaws.SdkBaseException;
import com.amazonaws.SdkClientException;
import com.amazonaws.annotation.SdkInternalApi;
import com.amazonaws.annotation.SdkTestInternalApi;
import com.amazonaws.annotation.ThreadSafe;
import com.amazonaws.auth.AccountIdAware;
import com.amazonaws.auth.AWS4Signer;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.CanHandleNullCredentials;
import com.amazonaws.auth.Signer;
import com.amazonaws.endpoints.AccountIdEndpointMode;
import com.amazonaws.endpoints.internal.AccountIdEndpointModeResolver;
import com.amazonaws.event.ProgressEventType;
import com.amazonaws.event.ProgressInputStream;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.handlers.CredentialsRequestHandler;
import com.amazonaws.handlers.HandlerAfterAttemptContext;
import com.amazonaws.handlers.HandlerBeforeAttemptContext;
import com.amazonaws.handlers.HandlerContextKey;
import com.amazonaws.handlers.RequestHandler2;
import com.amazonaws.http.apache.client.impl.ApacheHttpClientFactory;
import com.amazonaws.http.apache.client.impl.ConnectionManagerAwareHttpClient;
import com.amazonaws.http.apache.request.impl.ApacheHttpRequestFactory;
import com.amazonaws.http.apache.utils.ApacheUtils;
import com.amazonaws.http.client.HttpClientFactory;
import com.amazonaws.http.exception.HttpRequestTimeoutException;
import com.amazonaws.http.request.HttpRequestFactory;
import com.amazonaws.http.response.AwsResponseHandlerAdapter;
import com.amazonaws.http.settings.HttpClientSettings;
import com.amazonaws.http.timers.client.ClientExecutionAbortTrackerTask;
import com.amazonaws.http.timers.client.ClientExecutionTimeoutException;
import com.amazonaws.http.timers.client.ClientExecutionTimer;
import com.amazonaws.http.timers.client.SdkInterruptedException;
import com.amazonaws.http.timers.request.HttpRequestAbortTaskTracker;
import com.amazonaws.http.timers.request.HttpRequestTimer;
import com.amazonaws.internal.AmazonWebServiceRequestAdapter;
import com.amazonaws.internal.CRC32MismatchException;
import com.amazonaws.internal.ReleasableInputStream;
import com.amazonaws.internal.ResettableInputStream;
import com.amazonaws.internal.SdkBufferedInputStream;
import com.amazonaws.internal.TokenBucket;
import com.amazonaws.internal.auth.SignerProviderContext;
import com.amazonaws.metrics.AwsSdkMetrics;
import com.amazonaws.metrics.RequestMetricCollector;
import com.amazonaws.monitoring.internal.ClientSideMonitoringRequestHandler;
import com.amazonaws.retry.ClockSkewAdjuster;
import com.amazonaws.retry.ClockSkewAdjuster.AdjustmentRequest;
import com.amazonaws.retry.ClockSkewAdjuster.ClockSkewAdjustment;
import com.amazonaws.retry.RetryMode;
import com.amazonaws.retry.RetryPolicyAdapter;
import com.amazonaws.retry.RetryUtils;
import com.amazonaws.internal.SdkRequestRetryHeaderProvider;
import com.amazonaws.retry.internal.AuthErrorRetryStrategy;
import com.amazonaws.retry.internal.AuthRetryParameters;
import com.amazonaws.retry.v2.RetryPolicy;
import com.amazonaws.retry.v2.RetryPolicyContext;
import com.amazonaws.util.AWSRequestMetrics;
import com.amazonaws.util.AWSRequestMetrics.Field;
import com.amazonaws.util.AwsClientSideMonitoringMetrics;
import com.amazonaws.util.CapacityManager;
import com.amazonaws.util.CollectionUtils;
import com.amazonaws.util.CountingInputStream;
import com.amazonaws.util.FakeIOException;
import com.amazonaws.util.ImmutableMapParameter;
import com.amazonaws.util.MetadataCache;
import com.amazonaws.util.NullResponseMetadataCache;
import com.amazonaws.util.ResponseMetadataCache;
import com.amazonaws.util.RuntimeHttpUtils;
import com.amazonaws.util.SdkHttpUtils;
import com.amazonaws.util.StringUtils;
import com.amazonaws.util.UnreliableFilterInputStream;
import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.execchain.RequestAbortedException;
import org.apache.http.pool.ConnPoolControl;
import org.apache.http.pool.PoolStats;
import org.apache.http.protocol.HttpContext;
@ThreadSafe
public class AmazonHttpClient {
public static final String HEADER_USER_AGENT = "User-Agent";
public static final String HEADER_SDK_TRANSACTION_ID = "amz-sdk-invocation-id";
public static final String HEADER_SDK_RETRY_INFO = "amz-sdk-retry";
private static final String TRACE_ID_HEADER = "X-Amzn-Trace-Id";
/**
* Logger for more detailed debugging information, that might not be as useful for end users
* (ex: HTTP client configuration, etc).
*/
static final Log log = LogFactory.getLog(AmazonHttpClient.class);
/**
* Logger providing detailed information on requests/responses. Users can enable this logger to
* get access to AWS request IDs for responses, individual requests and parameters sent to AWS,
* etc.
*/
@SdkInternalApi
public static final Log requestLog = LogFactory.getLog("com.amazonaws.request");
private static final HttpClientFactory httpClientFactory = new
ApacheHttpClientFactory();
/**
* Used for testing via failure injection.
*/
private static UnreliableTestConfig unreliableTestConfig;
/**
* When throttled retries are enabled, each retry attempt will consume this much capacity.
* Successful retry attempts will release this capacity back to the pool while failed retries
* will not. Successful initial (non-retry) requests will always release 1 capacity unit to the
* pool.
*/
private static final int THROTTLED_RETRY_COST = 5;
/**
* The capacity to acquire for a connection timeout or socket timeout error.
*/
private static final int TIMEOUT_RETRY_COST = 10;
static {
// Customers have reported XML parsing issues with the following
// JVM versions, which don't occur with more recent versions, so
// if we detect any of these, give customers a heads up.
// https://bugs.openjdk.java.net/browse/JDK-8028111
List problematicJvmVersions = Arrays
.asList("1.6.0_06", "1.6.0_13", "1.6.0_17", "1.6.0_65", "1.7.0_45");
String jvmVersion = System.getProperty("java.version");
if (problematicJvmVersions.contains(jvmVersion)) {
log.warn("Detected a possible problem with the current JVM version (" + jvmVersion +
"). " +
"If you experience XML parsing problems using the SDK, try upgrading to a more recent JVM update.");
}
}
private final ClockSkewAdjuster clockSkewAdjuster = new ClockSkewAdjuster();
private final HttpRequestFactory httpRequestFactory =
new ApacheHttpRequestFactory();
private final AccountIdEndpointModeResolver accountIdEndpointModeResolver = new AccountIdEndpointModeResolver();
/**
* Internal client for sending HTTP requests
*/
private ConnectionManagerAwareHttpClient httpClient;
/**
* Client configuration options, such as proxy httpClientSettings, max retries, etc.
*/
private final ClientConfiguration config;
private final RetryPolicy retryPolicy;
/**
* Client configuration options, such as proxy httpClientSettings, max retries, etc.
*/
private final HttpClientSettings httpClientSettings;
/**
* Cache of metadata for recently executed requests for diagnostic purposes
*/
private final MetadataCache responseMetadataCache;
/**
* Timer to enforce HTTP request timeouts.
*/
private final HttpRequestTimer httpRequestTimer;
/**
* Retry capacity manager, used to manage throttled retry resource
*/
private final CapacityManager retryCapacity;
/**
* Token bucket used for rate limiting when {@link RetryMode#ADAPTIVE} retry mode is enabled.
*/
private TokenBucket tokenBucket;
/**
* Timer to enforce timeouts on the whole execution of the request (request handlers, retries,
* backoff strategy, unmarshalling, etc)
*/
private final ClientExecutionTimer clientExecutionTimer;
/**
* A request metric collector used specifically for this httpClientSettings client; or null if
* there is none. This collector, if specified, always takes precedence over the one specified
* at the AWS SDK level.
*
* @see AwsSdkMetrics
*/
private final RequestMetricCollector requestMetricCollector;
/**
* Used to generate UUID's for client transaction id. This gives a higher probability of id
* clashes but is more performant then using {@link UUID#randomUUID()} which uses SecureRandom
* internally.
**/
private final Random random = new Random();
/**
* The time difference in seconds between this client and AWS.
*/
private volatile int timeOffset = SDKGlobalTime.getGlobalTimeOffset();
private final RetryMode retryMode;
private final AccountIdEndpointMode accountIdEndpointMode;
private final SdkRequestRetryHeaderProvider sdkRequestHeaderProvider;
/**
* Constructs a new AWS client using the specified client configuration options (ex: max retry
* attempts, proxy httpClientSettings, etc).
*
* @param config Configuration options specifying how this client will communicate with AWS (ex:
* proxy httpClientSettings, retry count, etc.).
*/
public AmazonHttpClient(ClientConfiguration config) {
this(config, null);
}
/**
* Constructs a new AWS client using the specified client configuration options (ex: max retry
* attempts, proxy httpClientSettings, etc), and request metric collector.
*
* @param config Configuration options specifying how this client will
* communicate with AWS (ex: proxy httpClientSettings, retry
* count, etc.).
* @param requestMetricCollector client specific request metric collector, which takes
* precedence over the one at the AWS SDK level; or null if there
* is none.
*/
public AmazonHttpClient(ClientConfiguration config,
RequestMetricCollector requestMetricCollector) {
this(config, requestMetricCollector, false);
}
/**
* Constructs a new AWS client using the specified client configuration options (ex: max retry
* attempts, proxy httpClientSettings, etc), and request metric collector.
*
* @param config Configuration options specifying how this client will
* communicate with AWS (ex: proxy httpClientSettings, retry
* count, etc.).
* @param requestMetricCollector client specific request metric collector, which takes
* precedence over the one at the AWS SDK level; or null if there
* is none.
*/
public AmazonHttpClient(ClientConfiguration config,
RequestMetricCollector requestMetricCollector,
boolean useBrowserCompatibleHostNameVerifier) {
this(config, requestMetricCollector, useBrowserCompatibleHostNameVerifier, false);
}
/**
* Constructs a new AWS client using the specified client configuration options (ex: max retry
* attempts, proxy httpClientSettings, etc), and request metric collector.
*
* @param config Configuration options specifying how this client will
* communicate with AWS (ex: proxy httpClientSettings,
* retry count, etc.).
* @param requestMetricCollector client specific request metric collector, which takes
* precedence over the one at the AWS SDK level; or null
* if there is none.
* @param calculateCRC32FromCompressedData The flag indicating whether the CRC32 checksum is
* calculated from compressed data or not. It is only
* applicable when the header "x-amz-crc32" is set in
* the response.
*/
public AmazonHttpClient(ClientConfiguration config,
RequestMetricCollector requestMetricCollector,
boolean useBrowserCompatibleHostNameVerifier,
boolean calculateCRC32FromCompressedData) {
this(config,
null,
requestMetricCollector,
useBrowserCompatibleHostNameVerifier,
calculateCRC32FromCompressedData);
}
private AmazonHttpClient(ClientConfiguration config,
RetryPolicy retryPolicy,
RequestMetricCollector requestMetricCollector,
boolean useBrowserCompatibleHostNameVerifier,
boolean calculateCRC32FromCompressedData) {
this(config,
retryPolicy,
requestMetricCollector,
HttpClientSettings.adapt(config, useBrowserCompatibleHostNameVerifier, calculateCRC32FromCompressedData));
this.httpClient = httpClientFactory.create(this.httpClientSettings);
}
/**
* Package-protected constructor for unit test purposes.
*/
@SdkTestInternalApi
public AmazonHttpClient(ClientConfiguration clientConfig,
ConnectionManagerAwareHttpClient httpClient,
RequestMetricCollector requestMetricCollector,
TokenBucket tokenBucket) {
this(clientConfig,
null,
requestMetricCollector,
HttpClientSettings.adapt(clientConfig, false));
this.httpClient = httpClient;
this.tokenBucket = tokenBucket;
}
private AmazonHttpClient(ClientConfiguration clientConfig,
RetryPolicy retryPolicy,
RequestMetricCollector requestMetricCollector,
HttpClientSettings httpClientSettings) {
this.config = clientConfig;
this.retryPolicy =
retryPolicy == null ? new RetryPolicyAdapter(clientConfig.getRetryPolicy(), clientConfig) : retryPolicy;
this.retryMode =
clientConfig.getRetryMode() == null ? clientConfig.getRetryPolicy().getRetryMode() : clientConfig.getRetryMode();
this.accountIdEndpointMode = resolveAccountIdEndpointMode();
this.httpClientSettings = httpClientSettings;
this.requestMetricCollector = requestMetricCollector;
this.responseMetadataCache =
clientConfig.getCacheResponseMetadata() ?
new ResponseMetadataCache(clientConfig.getResponseMetadataCacheSize()) :
new NullResponseMetadataCache();
this.httpRequestTimer = new HttpRequestTimer();
this.clientExecutionTimer = new ClientExecutionTimer();
// When enabled, total retry capacity is computed based on retry cost
// and desired number of retries.
int throttledRetryMaxCapacity = clientConfig.useThrottledRetries()
? THROTTLED_RETRY_COST * config.getMaxConsecutiveRetriesBeforeThrottling() : -1;
this.retryCapacity = new CapacityManager(throttledRetryMaxCapacity);
this.tokenBucket = new TokenBucket();
this.sdkRequestHeaderProvider = new SdkRequestRetryHeaderProvider(config, this.retryPolicy, clockSkewAdjuster);
}
private AccountIdEndpointMode resolveAccountIdEndpointMode() {
if (config.getAccountIdEndpointMode() != null) {
return config.getAccountIdEndpointMode();
} else {
return accountIdEndpointModeResolver.accountIdEndpointMode();
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private ClientConfiguration clientConfig;
private RetryPolicy retryPolicy;
private RequestMetricCollector requestMetricCollector;
private boolean useBrowserCompatibleHostNameVerifier;
private boolean calculateCRC32FromCompressedData;
private Builder() {
}
public Builder clientConfiguration(ClientConfiguration clientConfig) {
this.clientConfig = clientConfig;
return this;
}
public Builder retryPolicy(RetryPolicy retryPolicy) {
this.retryPolicy = retryPolicy;
return this;
}
public Builder requestMetricCollector(RequestMetricCollector requestMetricCollector) {
this.requestMetricCollector = requestMetricCollector;
return this;
}
public Builder useBrowserCompatibleHostNameVerifier(boolean useBrowserCompatibleHostNameVerifier) {
this.useBrowserCompatibleHostNameVerifier = useBrowserCompatibleHostNameVerifier;
return this;
}
public Builder calculateCRC32FromCompressedData(boolean calculateCRC32FromCompressedData) {
this.calculateCRC32FromCompressedData = calculateCRC32FromCompressedData;
return this;
}
public AmazonHttpClient build() {
return new AmazonHttpClient(clientConfig,
retryPolicy,
requestMetricCollector,
useBrowserCompatibleHostNameVerifier,
calculateCRC32FromCompressedData);
}
}
private static boolean isTemporaryRedirect(org.apache.http.HttpResponse response) {
int status = response.getStatusLine().getStatusCode();
return status == HttpStatus.SC_TEMPORARY_REDIRECT && response.getHeaders("Location") != null
&& response.getHeaders("Location").length > 0;
}
@Override
protected void finalize() throws Throwable {
this.shutdown();
super.finalize();
}
/**
* Shuts down this HTTP client object, releasing any resources that might be held open. This is
* an optional method, and callers are not expected to call it, but can if they want to
* explicitly release any open resources. Once a client has been shutdown, it cannot be used to
* make more requests.
*/
public void shutdown() {
clientExecutionTimer.shutdown();
httpRequestTimer.shutdown();
IdleConnectionReaper.removeConnectionManager(httpClient.getHttpClientConnectionManager());
httpClient.getHttpClientConnectionManager().shutdown();
}
/**
* Used to configure the test conditions for injecting intermittent failures to the content
* input stream.
*
* @param config unreliable test configuration for failure injection; or null to disable such
* test.
*/
static void configUnreliableTestConditions(UnreliableTestConfig config) {
unreliableTestConfig = config;
}
/**
* Package protected for unit-testing
*/
@SdkTestInternalApi
public HttpRequestTimer getHttpRequestTimer() {
return this.httpRequestTimer;
}
/**
* Package protected for unit-testing
*/
@SdkTestInternalApi
public ClientExecutionTimer getClientExecutionTimer() {
return this.clientExecutionTimer;
}
/**
* Returns additional response metadata for an executed request. Response metadata isn't
* considered part of the standard results returned by an operation, so it's accessed instead
* through this diagnostic interface. Response metadata is typically used for troubleshooting
* issues with AWS support staff when services aren't acting as expected.
*
* @param request A previously executed AmazonWebServiceRequest object, whose response metadata
* is desired.
* @return The response metadata for the specified request, otherwise null if there is no
* response metadata available for the request.
*/
public ResponseMetadata getResponseMetadataForRequest(AmazonWebServiceRequest request) {
return responseMetadataCache.get(request);
}
/**
* Returns the httpClientSettings client specific request metric collector; or null if there is
* none.
*/
public RequestMetricCollector getRequestMetricCollector() {
return requestMetricCollector;
}
/**
* Returns the time difference in seconds between this client and AWS.
*/
public int getTimeOffset() {
return timeOffset;
}
/**
* Executes the request and returns the result.
*
* @param request The AmazonWebServices request to send to the remote server
* @param responseHandler A response handler to accept a successful response from the
* remote server
* @param errorResponseHandler A response handler to accept an unsuccessful response from the
* remote server
* @param executionContext Additional information about the context of this web service
* call
* @deprecated Use {@link #requestExecutionBuilder()} to configure and execute a HTTP request.
*/
@Deprecated
public Response execute(Request> request,
HttpResponseHandler> responseHandler,
HttpResponseHandler errorResponseHandler,
ExecutionContext executionContext) {
return execute(request, responseHandler, errorResponseHandler, executionContext,
new AmazonWebServiceRequestAdapter(request.getOriginalRequest()));
}
@SdkInternalApi
public Response execute(Request> request,
HttpResponseHandler> responseHandler,
HttpResponseHandler errorResponseHandler,
ExecutionContext executionContext,
RequestConfig requestConfig) {
HttpResponseHandler adaptedRespHandler = new AwsResponseHandlerAdapter(
getNonNullResponseHandler(responseHandler),
request,
executionContext.getAwsRequestMetrics(),
responseMetadataCache);
executionContext.setAccountIdEndpointMode(this.accountIdEndpointMode);
executionContext.setClientProtocol(this.config.getProtocol());
return requestExecutionBuilder()
.request(request)
.requestConfig(requestConfig)
.errorResponseHandler(new AwsErrorResponseHandler(errorResponseHandler, executionContext.getAwsRequestMetrics(), config))
.executionContext(executionContext)
.execute(adaptedRespHandler);
}
/**
* Ensures the response handler is not null. If it is this method returns a dummy response
* handler.
*
* @return Either original response handler or dummy response handler.
*/
private HttpResponseHandler getNonNullResponseHandler(
HttpResponseHandler responseHandler) {
if (responseHandler != null) {
return responseHandler;
} else {
// Return a Dummy, No-Op handler
return new HttpResponseHandler() {
@Override
public T handle(HttpResponse response) throws Exception {
return null;
}
@Override
public boolean needsConnectionLeftOpen() {
return false;
}
};
}
}
/**
* @return A builder used to configure and execute a HTTP request.
*/
public RequestExecutionBuilder requestExecutionBuilder() {
return new RequestExecutionBuilderImpl();
}
/**
* Interface to configure a request execution and execute the request.
*/
public interface RequestExecutionBuilder {
/**
* Fluent setter for {@link Request}
*
* @param request Request object
* @return This builder for method chaining.
*/
RequestExecutionBuilder request(Request> request);
/**
* Fluent setter for the error response handler
*
* @param errorResponseHandler Error response handler
* @return This builder for method chaining.
*/
RequestExecutionBuilder errorResponseHandler(
HttpResponseHandler extends SdkBaseException> errorResponseHandler);
/**
* Fluent setter for the execution context
*
* @param executionContext Execution context
* @return This builder for method chaining.
*/
RequestExecutionBuilder executionContext(ExecutionContext executionContext);
/**
* Fluent setter for {@link RequestConfig}
*
* @param requestConfig Request config object
* @return This builder for method chaining.
*/
RequestExecutionBuilder requestConfig(RequestConfig requestConfig);
/**
* Executes the request with the given configuration.
*
* @param responseHandler Response handler that outputs the actual result type which is
* preferred going forward.
* @param