Example #1
0
        internal HttpResponse PerformRequest(HttpRequest request, HttpContext context, int retryCount)
        {
            long         originPos = -1;
            HttpResponse response  = null;

            try
            {
                if (request.Content != null && request.Content.CanSeek)
                {
                    originPos = request.Content.Position;
                }
                response = this.DoRequest(request, context);

                new MergeResponseHeaderHandler(this.GetIHeaders(context)).Handle(response);

                int statusCode = Convert.ToInt32(response.StatusCode);

                if (LoggerMgr.IsDebugEnabled)
                {
                    LoggerMgr.Debug(string.Format("Response with statusCode {0} and headers {1}", statusCode, CommonUtil.ConvertHeadersToString(response.Headers)));
                }

                int maxErrorRetry = context.ObsConfig.MaxErrorRetry;

                if (statusCode >= 300 && statusCode < 400 && statusCode != 304)
                {
                    if (response.Headers.ContainsKey(Constants.CommonHeaders.Location))
                    {
                        string location = response.Headers[Constants.CommonHeaders.Location];
                        if (!string.IsNullOrEmpty(location))
                        {
                            if (location.IndexOf("?") < 0)
                            {
                                location += "?" + CommonUtil.ConvertParamsToString(request.Params);
                            }
                            if (LoggerMgr.IsWarnEnabled)
                            {
                                LoggerMgr.Warn(string.Format("Redirect to {0}", location));
                            }
                            context.RedirectLocation = location;
                            retryCount--;
                            if (ShouldRetry(request, null, retryCount, maxErrorRetry))
                            {
                                PrepareRetry(request, response, retryCount, originPos, false);
                                return(PerformRequest(request, context, ++retryCount));
                            }
                            else if (retryCount > maxErrorRetry)
                            {
                                throw ParseObsException(response, "Exceeded 3xx redirect limit", context);
                            }
                        }
                    }
                    throw ParseObsException(response, "Try to redirect, but location is null!", context);
                }
                else if ((statusCode >= 400 && statusCode < 500) || statusCode == 304)
                {
                    ObsException exception = ParseObsException(response, "Request error", context);
                    if (Constants.RequestTimeout.Equals(exception.ErrorCode))
                    {
                        if (ShouldRetry(request, null, retryCount, maxErrorRetry))
                        {
                            if (LoggerMgr.IsWarnEnabled)
                            {
                                LoggerMgr.Warn("Retrying connection that failed with RequestTimeout error");
                            }
                            PrepareRetry(request, response, retryCount, originPos, false);
                            return(PerformRequest(request, context, ++retryCount));
                        }
                        else if (retryCount > maxErrorRetry && LoggerMgr.IsErrorEnabled)
                        {
                            LoggerMgr.Error("Exceeded maximum number of retries for RequestTimeout errors");
                        }
                    }
                    throw exception;
                }
                else if (statusCode >= 500)
                {
                    if (ShouldRetry(request, null, retryCount, maxErrorRetry))
                    {
                        PrepareRetry(request, response, retryCount, originPos, true);
                        return(PerformRequest(request, context, ++retryCount));
                    }
                    else if (retryCount > maxErrorRetry && LoggerMgr.IsErrorEnabled)
                    {
                        LoggerMgr.Error("Encountered too many 5xx errors");
                    }
                    throw ParseObsException(response, "Request error", context);
                }
                return(response);
            }
            catch (Exception ex)
            {
                try
                {
                    if (ex is ObsException)
                    {
                        if (LoggerMgr.IsErrorEnabled)
                        {
                            LoggerMgr.Error("Rethrowing as a ObsException error in PerformRequest", ex);
                        }
                        throw ex;
                    }
                    else
                    {
                        if (ShouldRetry(request, ex, retryCount, context.ObsConfig.MaxErrorRetry))
                        {
                            PrepareRetry(request, response, retryCount, originPos, true);
                            return(PerformRequest(request, context, ++retryCount));
                        }
                        else if (retryCount > context.ObsConfig.MaxErrorRetry && LoggerMgr.IsWarnEnabled)
                        {
                            LoggerMgr.Warn("Too many errors excced the max error retry count", ex);
                        }
                        if (LoggerMgr.IsErrorEnabled)
                        {
                            LoggerMgr.Error("Rethrowing as a ObsException error in PerformRequest", ex);
                        }
                        throw ParseObsException(response, ex.Message, ex, context);
                    }
                }
                finally
                {
                    CommonUtil.CloseIDisposable(response);
                }
            }
        }