private async Task <bool> HandleHttpErrorResponseAsync(WebRequestState state, HttpResponseMessage httpErrorResponse, HttpClientResponseData responseData, CancellationToken cancellationToken)
        {
            HttpStatusCode         statusCode;
            AmazonServiceException errorResponseException = null;

            UnmarshallerContext errorContext = null;

            statusCode = httpErrorResponse.StatusCode;
            state.Metrics.AddProperty(Metric.StatusCode, statusCode);
            string redirectedLocation = responseData.GetHeaderValue("location");

            state.Metrics.AddProperty(Metric.RedirectLocation, redirectedLocation);

            var responseStream = await responseData.OpenResponseAsync()
                                 .ConfigureAwait(continueOnCapturedContext: false);

            errorContext = state.Unmarshaller.CreateContext(responseData,
                                                            Config.LogResponse || Config.ReadEntireResponse || AWSConfigs.LoggingConfig.LogResponses != ResponseLoggingOption.Never,
                                                            responseStream,
                                                            state.Metrics);
            errorResponseException = state.Unmarshaller.UnmarshallException(errorContext, null, statusCode);
            if (Config.LogResponse || AWSConfigs.LoggingConfig.LogResponses != ResponseLoggingOption.Never)
            {
                this.logger.Error(errorResponseException, "Received error response: [{0}]", errorContext.ResponseBody);
            }
            state.Metrics.AddProperty(Metric.AWSRequestID, errorResponseException.RequestId);
            state.Metrics.AddProperty(Metric.AWSErrorCode, errorResponseException.ErrorCode);

            if (CanRetry(state))
            {
                if (isTemporaryRedirect(statusCode, redirectedLocation))
                {
                    this.logger.DebugFormat("Request {0} is being redirected to {1}.", state.Request.RequestName, redirectedLocation);
                    state.Request.Endpoint = new Uri(redirectedLocation);
                    return(true);
                }
                else if (ShouldRetry(statusCode, this.Config, errorResponseException, state.RetriesAttempt))
                {
                    this.logger.DebugFormat("Retry number {0} for request {1}.", state.RetriesAttempt, state.Request.RequestName);
                    pauseExponentially(state);
                    cancellationToken.ThrowIfCancellationRequested();
                    return(true);
                }
            }

            if (errorResponseException != null)
            {
                this.logger.Error(errorResponseException, "Error making request {0}.", state.Request.RequestName);
                state.Metrics.AddProperty(Metric.Exception, errorResponseException);
                throw errorResponseException;
            }


            AmazonServiceException excep = new AmazonServiceException("Unable to make request", null, statusCode);

            this.logger.Error(excep, "Error making request {0}.", state.Request.RequestName);
            state.Metrics.AddProperty(Metric.Exception, excep);
            throw excep;
        }
예제 #2
0
        private async Task <AmazonWebServiceResponse> HandleHttpContentAsync(WebRequestState state, HttpResponseMessage httpResponse)
        {
            LogResponse(state.Metrics, state.Request, httpResponse.StatusCode);
            AmazonWebServiceResponse response     = null;
            HttpClientResponseData   responseData = new HttpClientResponseData(httpResponse);
            UnmarshallerContext      context      = null;

            try
            {
                var responseStream = await responseData.OpenResponseAsync()
                                     .ConfigureAwait(continueOnCapturedContext: false);

                context = state.Unmarshaller.CreateContext(responseData,
                                                           this.SupportResponseLogging &&
                                                           (Config.LogResponse || Config.ReadEntireResponse || AWSConfigs.ResponseLogging != ResponseLoggingOption.Never),
                                                           responseStream,
                                                           state.Metrics);

                using (state.Metrics.StartEvent(Metric.ResponseUnmarshallTime))
                {
                    response = state.Unmarshaller.Unmarshall(context);
                }
                context.ValidateCRC32IfAvailable();

                var contentHeaders = httpResponse.Content.Headers as HttpContentHeaders;
                if (contentHeaders != null)
                {
                    response.ContentLength  = contentHeaders.ContentLength.GetValueOrDefault();
                    response.HttpStatusCode = httpResponse.StatusCode;
                }

                if (response.ResponseMetadata != null)
                {
                    state.Metrics.AddProperty(Metric.AWSRequestID, response.ResponseMetadata.RequestId);
                }
                LogFinishedResponse(state.Metrics, context, response.ContentLength);

                return(response);
            }
            finally
            {
                if (!state.Unmarshaller.HasStreamingProperty)
                {
                    httpResponse.Dispose();
                }

                ProcessResponseHandlers(response, state.Request, responseData);
            }
        }