Exemple #1
0
        /// <summary>
        /// This method makes the actual web request and marshalls the response body or error returned from the service.
        /// For some error response a retry will be attempted after an exponential pause.
        /// </summary>
        /// <typeparam name="X">The user facing request type.</typeparam>
        /// <typeparam name="Y">The user facing response type.</typeparam>
        /// <param name="request">The wrapper around the user facing request.</param>
        /// <param name="signer">The type of signer to use for the request.</param>
        /// <param name="unmarshaller">The object used to unmarshall the response body.</param>
        /// <returns>The response object for the request</returns>
        internal Y Invoke <X, Y>(IRequest <X> request, AbstractAWSSigner signer, IResponseUnmarshaller <Y, UnmarshallerContext> unmarshaller)
        {
            Type   requestType = typeof(X);
            string requestName = requestType.Name;

            this.logger.DebugFormat("Starting request {0} at {1}", requestName, this.config.ServiceURL);
            request.Endpoint = new Uri(this.config.ServiceURL);
            signer.Sign(request, this.config, this.awsAccessKeyId, this.clearAwsSecretAccessKey, this.awsSecretAccessKey);

            string queryString = AWSSDKUtils.GetParametersAsString(request.Parameters);

            byte[] requestData = Encoding.UTF8.GetBytes(queryString);
            this.logger.DebugFormat("Request body's content [{0}] with size {1}", queryString, requestData.Length);

            int retries = 0;

            while (true)
            {
                retries++;

                try
                {
                    HttpWebRequest webRequest = this.ConfigureWebRequest <X>(request, requestData);
                    try
                    {
                        Y        result;
                        DateTime requestSent = DateTime.UtcNow;
                        using (HttpWebResponse httpResponse = webRequest.GetResponse() as HttpWebResponse)
                        {
                            DateTime responseReceived = DateTime.UtcNow;
                            this.logger.InfoFormat("Received response for {0} with status code {1} in {2} ms.", requestName, httpResponse.StatusCode, (responseReceived - requestSent).TotalMilliseconds);
                            XmlTextReader       reader  = new XmlTextReader(new StreamReader(httpResponse.GetResponseStream()));
                            UnmarshallerContext context = new UnmarshallerContext(reader);
                            result = unmarshaller.Unmarshall(context);
                        }

                        return(result);
                    }
                    catch (WebException we)
                    {
                        processWebException <X, Y>(requestName, we, webRequest, unmarshaller, request, retries);
                    }
                }
                catch (Exception e)
                {
                    this.logger.Error(string.Format("Error configuring web request {0} to {1}.", requestName, request.Endpoint.ToString()), e);
                    throw;
                }
            }
        }
        private void processWebException <X, Y>(string requestName, WebException we, HttpWebRequest webRequest, IResponseUnmarshaller <Y, UnmarshallerContext> unmarshaller, IRequest <X> request, int retries)
        {
            HttpStatusCode         statusCode;
            AmazonServiceException errorResponseException = null;

            using (HttpWebResponse httpErrorResponse = we.Response as HttpWebResponse)
            {
                if (httpErrorResponse == null)
                {
                    // Abort the unsuccessful request
                    webRequest.Abort();

                    // If it is a keep alive error then attempt a retry
                    if (we != null && retries <= config.MaxErrorRetry && we.Status == WebExceptionStatus.KeepAliveFailure)
                    {
                        pauseExponentially(retries);
                        return;
                    }
                    throw new AmazonServiceException(we);
                }
                statusCode = httpErrorResponse.StatusCode;

                XmlTextReader errorReader;
#if NOSTREAM
                string responseBody = new StreamReader(httpErrorResponse.GetResponseStream()).ReadToEnd();;
                errorReader = new XmlTextReader(new StringReader(responseBody));
#else
                errorReader = new XmlTextReader(new StreamReader(httpErrorResponse.GetResponseStream()));
#endif

                UnmarshallerContext errorContext = new UnmarshallerContext(errorReader);
                errorResponseException = unmarshaller.UnmarshallException(errorContext, we, statusCode);

                httpErrorResponse.Close();
                webRequest.Abort();

                if (isTemporaryRedirect(httpErrorResponse))
                {
                    string redirectedLocation = httpErrorResponse.Headers["location"];
                    this.logger.InfoFormat("Request {0} is being redirected to {1}.", requestName, redirectedLocation);
                    request.Endpoint = new Uri(redirectedLocation);
                    return;
                }
                else if (ShouldRetry(statusCode, this.config, errorResponseException, retries))
                {
                    this.logger.InfoFormat("Retry number {0} for request {1}.", retries, requestName);
                    pauseExponentially(retries);
                    return;
                }
            }

            if (errorResponseException != null)
            {
                this.logger.Error(string.Format("Error making request {0}.", requestName), errorResponseException);
                throw errorResponseException;
            }

            AmazonServiceException excep = new AmazonServiceException("Unable to make request", we, statusCode);
            this.logger.Error(string.Format("Error making request {0}.", requestName), excep);
            throw excep;
        }
        /// <summary>
        /// This method makes the actual web request and marshalls the response body or error returned from the service.
        /// For some error response a retry will be attempted after an exponential pause.
        /// </summary>
        /// <typeparam name="X">The user facing request type.</typeparam>
        /// <typeparam name="Y">The user facing response type.</typeparam>
        /// <param name="request">The wrapper around the user facing request.</param>
        /// <param name="signer">The type of signer to use for the request.</param>
        /// <param name="unmarshaller">The object used to unmarshall the response body.</param>
        /// <returns>The response object for the request</returns>
        internal Y Invoke <X, Y>(IRequest <X> request, AbstractAWSSigner signer, IResponseUnmarshaller <Y, UnmarshallerContext> unmarshaller) where X : AmazonWebServiceRequest
        {
            Type   requestType = typeof(X);
            string requestName = requestType.Name;

            request.Endpoint = new Uri(this.config.ServiceURL);
            request.Headers["User-Agent"]   = this.config.UserAgent;
            request.Headers["Content-Type"] = AWSSDKUtils.UrlEncodedContent;

            ProcessRequestHandlers(request);

            this.logger.DebugFormat("Starting request {0} at {1}", requestName, this.config.ServiceURL);
            signer.Sign(request, this.config, this.awsAccessKeyId, this.clearAwsSecretAccessKey, this.awsSecretAccessKey);

            string queryString = AWSSDKUtils.GetParametersAsString(request.Parameters);

            byte[] requestData = Encoding.UTF8.GetBytes(queryString);
            this.logger.DebugFormat("Request body's content [{0}] with size {1}", queryString, requestData.Length);

            int retries = 0;

            while (true)
            {
                retries++;

                try
                {
                    HttpWebRequest webRequest = this.ConfigureWebRequest <X>(request, requestData);
                    try
                    {
                        Y        result;
                        DateTime requestSent = DateTime.UtcNow;
                        using (HttpWebResponse httpResponse = webRequest.GetResponse() as HttpWebResponse)
                        {
                            DateTime responseReceived = DateTime.UtcNow;
                            this.logger.InfoFormat("Received response for {0} with status code {1} in {2} ms.", requestName, httpResponse.StatusCode, (responseReceived - requestSent).TotalMilliseconds);
                            XmlTextReader reader;

                            // Using NOSTREAM is the less effcient way of dealing with the response body but it is helpful
                            // for debug purposes to see the entire xml body coming back from the server.
#if NOSTREAM
                            string responseBody = new StreamReader(httpResponse.GetResponseStream()).ReadToEnd();;
                            reader = new XmlTextReader(new StringReader(responseBody));
#else
                            reader = new XmlTextReader(new StreamReader(httpResponse.GetResponseStream()));
#endif
                            UnmarshallerContext context = new UnmarshallerContext(reader);
                            result = unmarshaller.Unmarshall(context);
                        }

                        return(result);
                    }
                    catch (WebException we)
                    {
                        processWebException <X, Y>(requestName, we, webRequest, unmarshaller, request, retries);
                    }
                }
                catch (IOException e)
                {
                    if (this.isInnerExceptionThreadAbort(e))
                    {
                        throw;
                    }

                    this.logger.Error(string.Format("IOException making request {0} to {1}.", requestName, request.Endpoint.ToString()), e);
                    if (retries > this.config.MaxErrorRetry)
                    {
                        throw;
                    }
                    else
                    {
                        this.logger.Error(string.Format("IOException making request {0} to {1}. Attempting retry {2}.", requestName, request.Endpoint.ToString(), retries), e);
                    }
                }
                catch (Exception e)
                {
                    this.logger.Error(string.Format("Error configuring web request {0} to {1}.", requestName, request.Endpoint.ToString()), e);
                    throw;
                }
            }
        }