protected override void Dispose(bool disposing) { if (!_disposed) { base.Dispose(disposing); this.AdditionalState = null; CommonUtil.CloseIDisposable(this.HttpRequest); } }
private void PrepareRetry(HttpRequest request, HttpResponse response, int retryCount, long originPos, bool sleep) { CommonUtil.CloseIDisposable(response); if (request.Content != null && (originPos >= 0 && request.Content.CanSeek)) { request.Content.Seek(originPos, SeekOrigin.Begin); if (request.Content is TransferStream) { (request.Content as TransferStream).ResetReadProgress(); } } if (sleep) { int delay = (int)Math.Pow(2, retryCount) * 50; if (LoggerMgr.IsWarnEnabled) { LoggerMgr.Warn(string.Format("Send http request error, will retry in {0} ms", delay)); } Thread.Sleep(delay); } }
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); } } }