setUserAgent(request);
int retryCount = 0;
URI redirectedURI = null;
HttpEntity entity = null;
AmazonServiceException exception = null;
// Make a copy of the original request params and headers so that we can
// permute it in this loop and start over with the original every time.
Map<String, String> originalParameters = new HashMap<String, String>();
originalParameters.putAll(request.getParameters());
Map<String, String> originalHeaders = new HashMap<String, String>();
originalHeaders.putAll(request.getHeaders());
while (true) {
awsRequestMetrics.setCounter(Field.AttemptCount.name(), retryCount+1);
if ( retryCount > 0 ) {
request.setParameters(originalParameters);
request.setHeaders(originalHeaders);
}
HttpRequestBase httpRequest = null;
org.apache.http.HttpResponse response = null;
try {
// Sign the request if a signer was provided
if (executionContext.getSigner() != null && executionContext.getCredentials() != null) {
awsRequestMetrics.startEvent(Field.RequestSigningTime.name());
executionContext.getSigner().sign(request, executionContext.getCredentials());
awsRequestMetrics.endEvent(Field.RequestSigningTime.name());
}
if (requestLog.isDebugEnabled()) {
requestLog.debug("Sending Request: " + request.toString());
}
httpRequest = httpRequestFactory.createHttpRequest(request, config, entity, executionContext);
if (httpRequest instanceof HttpEntityEnclosingRequest) {
entity = ((HttpEntityEnclosingRequest)httpRequest).getEntity();
}
if (redirectedURI != null) {
httpRequest.setURI(redirectedURI);
}
if ( retryCount > 0 ) {
awsRequestMetrics.startEvent(Field.RetryPauseTime.name());
pauseExponentially(retryCount, exception, executionContext.getCustomBackoffStrategy());
awsRequestMetrics.endEvent(Field.RetryPauseTime.name());
}
if ( entity != null ) {
InputStream content = entity.getContent();
if ( retryCount > 0 ) {
if ( content.markSupported() ) {
content.reset();
content.mark(-1);
}
} else {
if ( content.markSupported() ) {
content.mark(-1);
}
}
}
exception = null;
awsRequestMetrics.startEvent(Field.HttpRequestTime.name());
response = httpClient.execute(httpRequest);
awsRequestMetrics.endEvent(Field.HttpRequestTime.name());
if (isRequestSuccessful(response)) {
awsRequestMetrics.addProperty(Field.StatusCode.name(), response.getStatusLine().getStatusCode());
/*
* If we get back any 2xx status code, then we know we should
* treat the service call as successful.
*/
leaveHttpConnectionOpen = responseHandler.needsConnectionLeftOpen();
return handleResponse(request, responseHandler, httpRequest, response, executionContext);
} else if (isTemporaryRedirect(response)) {
/*
* S3 sends 307 Temporary Redirects if you try to delete an
* EU bucket from the US endpoint. If we get a 307, we'll
* point the HTTP method to the redirected location, and let
* the next retry deliver the request to the right location.
*/
Header[] locationHeaders = response.getHeaders("location");
String redirectedLocation = locationHeaders[0].getValue();
log.debug("Redirecting to: " + redirectedLocation);
redirectedURI = URI.create(redirectedLocation);
httpRequest.setURI(redirectedURI);
awsRequestMetrics.addProperty(Field.StatusCode.name(), response.getStatusLine().getStatusCode());
awsRequestMetrics.addProperty(Field.RedirectLocation.name(), redirectedLocation);
awsRequestMetrics.addProperty(Field.AWSRequestID.name(), null);
} else {
leaveHttpConnectionOpen = errorResponseHandler.needsConnectionLeftOpen();
exception = handleErrorResponse(request, errorResponseHandler, httpRequest, response);
awsRequestMetrics.addProperty(Field.AWSRequestID.name(), exception.getRequestId());
awsRequestMetrics.addProperty(Field.AWSErrorCode.name(), exception.getErrorCode());
awsRequestMetrics.addProperty(Field.StatusCode.name(), exception.getStatusCode());
if (!shouldRetry(httpRequest, exception, retryCount)) {
throw exception;
}