Beispiel #1
0
        private AmazonWebServiceResponse UnmarshallResponse(UnmarshallerContext context,
                                                            IRequestContext requestContext)
        {
            try
            {
                var unmarshaller = requestContext.Unmarshaller;
                AmazonWebServiceResponse response = null;
                using (requestContext.Metrics.StartEvent(Metric.ResponseUnmarshallTime))
                {
                    response = unmarshaller.UnmarshallResponse(context);
                }

                requestContext.Metrics.AddProperty(Metric.StatusCode, response.HttpStatusCode);
                requestContext.Metrics.AddProperty(Metric.BytesProcessed, response.ContentLength);
                if (response.ResponseMetadata != null)
                {
                    requestContext.Metrics.AddProperty(Metric.AWSRequestID, response.ResponseMetadata.RequestId);
                }

                context.ValidateCRC32IfAvailable();
                return(response);
            }
            finally
            {
                var logResponseBody = ShouldLogResponseBody(_supportsResponseLogging, requestContext);

                if (logResponseBody)
                {
                    this.Logger.DebugFormat("Received response (truncated to {0} bytes): [{1}]",
                                            AWSConfigs.LoggingConfig.LogResponsesSizeLimit,
                                            context.ResponseBody);
                }
            }
        }
Beispiel #2
0
        private AmazonWebServiceResponse UnmarshallResponse(UnmarshallerContext context,
                                                            IRequestContext requestContext)
        {
            var unmarshaller = requestContext.Unmarshaller;
            AmazonWebServiceResponse response = null;

            using (requestContext.Metrics.StartEvent(Metric.ResponseUnmarshallTime))
            {
                response = unmarshaller.UnmarshallResponse(context);
            }

            requestContext.Metrics.AddProperty(Metric.StatusCode, response.HttpStatusCode);
            requestContext.Metrics.AddProperty(Metric.BytesProcessed, response.ContentLength);
            if (response.ResponseMetadata != null)
            {
                requestContext.Metrics.AddProperty(Metric.AWSRequestID, response.ResponseMetadata.RequestId);
            }

            var logResponseBody = _supportsResponseLogging && (requestContext.ClientConfig.LogResponse ||
                                                               AWSConfigs.LoggingConfig.LogResponses == ResponseLoggingOption.Always);

            if (logResponseBody)
            {
                this.Logger.DebugFormat("Received response: [{0}]", context.ResponseBody);
            }

            context.ValidateCRC32IfAvailable();
            return(response);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        void getResponseCallback(IAsyncResult result)
        {
            AsyncResult asyncResult = result as AsyncResult;

            if (asyncResult == null)
            {
                asyncResult = result.AsyncState as AsyncResult;
            }

            UnmarshallerContext context = null;

            asyncResult.RequestState.GetResponseCallbackCalled = true;
            bool shouldRetry = false;
            AmazonWebServiceResponse response = null;

            try
            {
                AsyncResult.AsyncRequestState state = asyncResult.RequestState;
                HttpWebResponse httpResponse        = null;
                try
                {
                    if (asyncResult.CompletedSynchronously)
                    {
                        httpResponse = state.WebRequest.GetResponse() as HttpWebResponse;
                    }
                    else
                    {
                        httpResponse = state.WebRequest.EndGetResponse(result) as HttpWebResponse;
                    }

                    using (asyncResult.Metrics.StartEvent(Metric.ResponseProcessingTime))
                    {
                        var unmarshaller = asyncResult.Unmarshaller;
                        LogResponse(asyncResult.Metrics, asyncResult.Request, httpResponse.StatusCode);

                        try
                        {
                            var httpResponseData = new HttpWebRequestResponseData(httpResponse);
                            context = unmarshaller.CreateContext(httpResponseData,
                                                                 this.SupportResponseLogging &&
                                                                 (Config.LogResponse || Config.ReadEntireResponse || AWSConfigs.LoggingConfig.LogResponses != ResponseLoggingOption.Never),
                                                                 httpResponseData.ResponseBody.OpenResponse(),
                                                                 asyncResult.Metrics);

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

                            response.ContentLength    = httpResponse.ContentLength;
                            response.HttpStatusCode   = httpResponse.StatusCode;
                            asyncResult.FinalResponse = response;
                            if (response.ResponseMetadata != null)
                            {
                                asyncResult.Metrics.AddProperty(Metric.AWSRequestID, response.ResponseMetadata.RequestId);
                            }

                            LogFinishedResponse(asyncResult.Metrics, context, httpResponse.ContentLength);
                        }
                        finally
                        {
                            if (!unmarshaller.HasStreamingProperty)
                            {
                                httpResponse.Close();
                            }
                        }
                    }
                }
                catch (WebException we)
                {
                    HttpWebResponse exceptionHttpResponse = we.Response as HttpWebResponse;

                    // If the error is a 404 and the request is configured to supress it. Then unmarshall as much as we can.
                    if (exceptionHttpResponse != null &&
                        exceptionHttpResponse.StatusCode == HttpStatusCode.NotFound &&
                        asyncResult.Request.Suppress404Exceptions)
                    {
                        var unmarshaller                 = asyncResult.Unmarshaller;
                        var httpResponseData             = new HttpWebRequestResponseData(exceptionHttpResponse);
                        UnmarshallerContext errorContext = unmarshaller.CreateContext(
                            httpResponseData,
                            Config.LogResponse || Config.ReadEntireResponse || AWSConfigs.LoggingConfig.LogResponses != ResponseLoggingOption.Never,
                            httpResponseData.ResponseBody.OpenResponse(),
                            asyncResult.Metrics);

                        try
                        {
                            response = unmarshaller.Unmarshall(errorContext);
                            response.ContentLength  = exceptionHttpResponse.ContentLength;
                            response.HttpStatusCode = exceptionHttpResponse.StatusCode;
                        }
                        catch (Exception e)
                        {
                            logger.Debug(e, "Failed to unmarshall 404 response when it was being supressed");
                        }

                        asyncResult.FinalResponse = response;
                    }
                    else
                    {
                        if (exceptionHttpResponse != null)
                        {
                            LogResponse(asyncResult.Metrics, asyncResult.Request, exceptionHttpResponse.StatusCode);
                        }
                        else
                        {
                            asyncResult.Metrics.StopEvent(Metric.HttpRequestTime);
                        }
                        shouldRetry = HandleHttpWebErrorResponse(asyncResult, we);
                    }
                }
                catch (IOException ioe)
                {
                    LogResponse(asyncResult.Metrics, asyncResult.Request, HttpStatusCode.Unused);
                    shouldRetry = HandleIOException(asyncResult, httpResponse, ioe);
                    if (!shouldRetry)
                    {
                        asyncResult.Exception = ioe;
                    }
                }

                if (shouldRetry)
                {
                    asyncResult.RequestState.WebRequest.Abort();
                    asyncResult.RetriesAttempt++;
                    InvokeHelper(asyncResult);
                }
                else
                {
                    LogFinalMetrics(asyncResult.Metrics);
                }
            }
            catch (Exception e)
            {
                if (context != null && AWSConfigs.LoggingConfig.LogResponses == ResponseLoggingOption.OnError)
                {
                    this.logger.Error(e, "Received response: [{0}]", context.ResponseBody);
                }

                asyncResult.RequestState.WebRequest.Abort();
                asyncResult.Exception = e;
                asyncResult.Metrics.AddProperty(Metric.Exception, e);
                asyncResult.Metrics.StopEvent(Metric.ClientExecuteTime);
                shouldRetry = false;
                if (Config.LogMetrics)
                {
                    logger.InfoFormat("Request metrics: {0}", asyncResult.Metrics);
                }

                ProcessExceptionHandlers(e, asyncResult.Request);
                logger.Error(e, "Error configuring web request {0} to {1}.", asyncResult.RequestName, asyncResult.Request.Endpoint.ToString());
            }
            finally
            {
                if (!shouldRetry)
                {
                    var responseData = context == null ? null : context.ResponseData;
                    ProcessResponseHandlers(response, asyncResult.Request, responseData);
                    asyncResult.InvokeCallback();
                }
            }
        }
        void getResponseCallback(IAsyncResult result)
        {
            AsyncResult asyncResult;

            if (result is AsyncResult)
            {
                asyncResult = result as AsyncResult;
            }
            else
            {
                asyncResult = result.AsyncState as AsyncResult;
            }

            UnmarshallerContext context = null;

            asyncResult.RequestState.GetResponseCallbackCalled = true;
            bool shouldRetry = false;

            try
            {
                AsyncResult.AsyncRequestState state = asyncResult.RequestState;
                HttpWebResponse httpResponse        = null;
                try
                {
                    if (asyncResult.CompletedSynchronously)
                    {
                        httpResponse = state.WebRequest.GetResponse() as HttpWebResponse;
                    }
                    else
                    {
                        httpResponse = state.WebRequest.EndGetResponse(result) as HttpWebResponse;
                    }

                    using (asyncResult.Metrics.StartEvent(RequestMetrics.Metric.ResponseProcessingTime))
                    {
                        var unmarshaller = asyncResult.Unmarshaller;
                        asyncResult.Metrics.AddProperty(RequestMetrics.Metric.StatusCode, httpResponse.StatusCode);
                        LogResponse(asyncResult, httpResponse.StatusCode);
                        try
                        {
                            context = unmarshaller.CreateContext(httpResponse, config.LogResponse || config.ReadEntireResponse || AWSConfigs.ResponseLogging != ResponseLoggingOption.Never, asyncResult);

                            AmazonWebServiceResponse response;
                            using (asyncResult.Metrics.StartEvent(RequestMetrics.Metric.ResponseUnmarshallTime))
                            {
                                response = unmarshaller.Unmarshall(context);
                            }
                            context.ValidateCRC32IfAvailable();

                            response.ContentLength    = httpResponse.ContentLength;
                            asyncResult.FinalResponse = response;
                            asyncResult.Metrics.AddProperty(RequestMetrics.Metric.AWSRequestID, response.ResponseMetadata.RequestId);

                            LogFinishedResponse(asyncResult, context, httpResponse.ContentLength);
                            ProcessResponseHandlers(response, asyncResult.Request);
                        }
                        finally
                        {
                            if (!unmarshaller.HasStreamingProperty)
                            {
                                httpResponse.Close();
                            }
                        }
                    }
                }
                catch (WebException we)
                {
                    HttpWebResponse exceptionHttpResponse = we.Response as HttpWebResponse;
                    if (exceptionHttpResponse != null)
                    {
                        LogResponse(asyncResult, exceptionHttpResponse.StatusCode);
                    }
                    else
                    {
                        asyncResult.Metrics.StopEvent(RequestMetrics.Metric.HttpRequestTime);
                    }
                    shouldRetry = handleHttpWebErrorResponse(asyncResult, we);
                }
                catch (IOException ioe)
                {
                    LogResponse(asyncResult, HttpStatusCode.Unused);
                    shouldRetry = handleIOException(asyncResult, httpResponse, ioe);
                }

                if (shouldRetry)
                {
                    asyncResult.RequestState.WebRequest.Abort();
                    asyncResult.RetriesAttempt++;
                    InvokeHelper(asyncResult);
                }
                else
                {
                    LogFinalMetrics(asyncResult);
                }
            }
            catch (Exception e)
            {
                if (context != null && AWSConfigs.ResponseLogging == ResponseLoggingOption.OnError)
                {
                    logger.Error(e, "Received response: [{0}]", context.ResponseBody);
                }

                asyncResult.RequestState.WebRequest.Abort();
                asyncResult.Exception = e;
                asyncResult.Metrics.AddProperty(RequestMetrics.Metric.Exception, e);
                asyncResult.Metrics.StopEvent(RequestMetrics.Metric.ClientExecuteTime);
                shouldRetry = false;
                if (config.LogMetrics)
                {
                    logger.InfoFormat("Request metrics: {0}", asyncResult.Metrics);
                }

                ProcessExceptionHandlers(e, asyncResult.Request);
                logger.Error(e, "Error configuring web request {0} to {1}.", asyncResult.RequestName, asyncResult.Request.Endpoint.ToString());
            }
            finally
            {
                if (!shouldRetry)
                {
                    asyncResult.SignalWaitHandle();
                    if (asyncResult.Callback != null)
                    {
                        asyncResult.Callback(asyncResult);
                    }
                }
            }
        }
        /// <summary>
        /// Invoked as a callback from the AmazonMainThreadDispatcher
        /// Processes the http response
        /// </summary>
        /// <param name="state">State is expected to be AsyncResult</param>
        private void ProcessHttpResponse(object state)
        {
            AsyncResult asyncResult = null;

            try
            {
                asyncResult = state as AsyncResult;
                AmazonWebServiceResponse response = null;
                UnmarshallerContext      context  = null;

                var responseData = asyncResult.ResponseData;

                if (!String.IsNullOrEmpty(responseData.Error))
                {
                    AmazonLogging.LogError(AmazonLogging.AmazonLoggingLevel.Critical,
                                           asyncResult.Request.ServiceName, responseData.Error);

                    if (HandleWWWErrorResponse(asyncResult))
                    {
                        if (++asyncResult.RetriesAttempt >= 3)
                        {
                            if (asyncResult.Exception == null)
                            {
                                asyncResult.Exception = new AmazonServiceException("Maximum retries attempts completed");
                            }
                            // maxretries
                            asyncResult.IsCompleted = true;
                            AmazonLogging.LogException(AmazonLogging.AmazonLoggingLevel.Errors,
                                                       asyncResult.Request.ServiceName, asyncResult.Exception);
                            asyncResult.HandleException(asyncResult.Exception);
                            return;
                        }
                        else
                        {
                            // retry here
                            InvokeHelper(asyncResult);
                            return;
                        }
                    }
                    else
                    {
                        // non-retriable error
                        asyncResult.IsCompleted = true;
                        asyncResult.HandleException(asyncResult.Exception);
                        return;
                    }
                }
                else
                {
                    using (asyncResult.Metrics.StartEvent(Metric.ResponseProcessingTime))
                    {
                        var unmarshaller = asyncResult.Unmarshaller;
                        LogResponse(asyncResult.Metrics, asyncResult.Request, HttpStatusCode.Accepted);

                        context = unmarshaller.CreateContext(responseData,
                                                             this.SupportResponseLogging &&
                                                             (Config.LogResponse || Config.ReadEntireResponse),
                                                             responseData.OpenResponse(),
                                                             asyncResult.Metrics);
                        try
                        {
                            using (asyncResult.Metrics.StartEvent(Metric.ResponseUnmarshallTime))
                            {
                                response = unmarshaller.Unmarshall(context);
                                if (responseData.IsHeaderPresent("STATUS"))
                                {
                                    response.HttpStatusCode = responseData.StatusCode;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            //unmarshalling exception
                            asyncResult.IsCompleted = true;
                            asyncResult.HandleException(e);
                            return;
                        }
                        context.ValidateCRC32IfAvailable();
                        if (responseData.IsHeaderPresent(HeaderKeys.ContentLengthHeader.ToUpper()))
                        {
                            response.ContentLength = Convert.ToInt32(responseData.GetHeaderValue(HeaderKeys.ContentLengthHeader.ToUpper()));
                        }
                        else
                        {
                            AmazonLogging.Log(AmazonLogging.AmazonLoggingLevel.Warnings, asyncResult.Request.ServiceName, "cannot find CONTENT-LENGTH header");
                        }

                        asyncResult.ServiceResult.Response = response;

                        if (response.ResponseMetadata != null)
                        {
                            asyncResult.Metrics.AddProperty(Metric.AWSRequestID, response.ResponseMetadata.RequestId);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                AmazonLogging.LogException(AmazonLogging.AmazonLoggingLevel.Errors, asyncResult.Request.ServiceName, e);
                asyncResult.HandleException(e);
            }

            asyncResult.IsCompleted = true;
            asyncResult.InvokeCallback();
            return;
        }