private void EndGetResponse(IAsyncResult ar) { HttpObsAsyncResult asyncResult = ar.AsyncState as HttpObsAsyncResult; asyncResult.IsTimeout = false; try { HttpResponse httpResponse = new HttpResponse(asyncResult.HttpWebRequest.EndGetResponse(ar) as HttpWebResponse); asyncResult.Set(httpResponse); } catch (WebException ex) { HttpWebResponse response = ex.Response as HttpWebResponse; if (response == null) { asyncResult.Abort(ex); } else { asyncResult.Set(new HttpResponse(ex, asyncResult.HttpWebRequest)); } } catch (Exception ex) { asyncResult.Abort(ex); } finally { if (LoggerMgr.IsInfoEnabled) { LoggerMgr.Info(string.Format("Send http request end, cost {0} ms", (DateTime.Now.Ticks - asyncResult.HttpStartDateTime.Ticks) / 10000)); } } }
private void EndGetRequestStream(IAsyncResult ar) { HttpObsAsyncResult asyncResult = ar.AsyncState as HttpObsAsyncResult; HttpWebRequest webRequest = asyncResult.HttpWebRequest; ObsConfig obsConfig = asyncResult.HttpContext.ObsConfig; Stream data = asyncResult.HttpRequest.Content; if (data == null) { data = new MemoryStream(); } try { using (Stream requestStream = webRequest.EndGetRequestStream(ar)) { ObsCallback callback = delegate() { asyncResult.IsTimeout = false; }; if (!webRequest.SendChunked) { CommonUtil.WriteTo(data, requestStream, webRequest.ContentLength, obsConfig.BufferSize, callback); } else { CommonUtil.WriteTo(data, requestStream, obsConfig.BufferSize, callback); } } asyncResult.Continue(this.EndGetResponse); } catch (Exception e) { asyncResult.Abort(e); } }
private void BeginSetContent(HttpObsAsyncResult asyncResult) { HttpWebRequest webRequest = asyncResult.HttpWebRequest; HttpRequest httpRequest = asyncResult.HttpRequest; long userSetContentLength = -1; if (httpRequest.Headers.ContainsKey(Constants.CommonHeaders.ContentLength)) { userSetContentLength = long.Parse(httpRequest.Headers[Constants.CommonHeaders.ContentLength]); } if (userSetContentLength >= 0) { webRequest.ContentLength = userSetContentLength; if (webRequest.ContentLength > Constants.DefaultStreamBufferThreshold) { webRequest.AllowWriteStreamBuffering = false; } } else { webRequest.SendChunked = true; webRequest.AllowWriteStreamBuffering = false; } webRequest.BeginGetRequestStream(this.EndGetRequestStream, asyncResult); }
private void BeginDoRequest(HttpObsAsyncResult asyncResult) { HttpRequest httpRequest = asyncResult.HttpRequest; HttpContext context = asyncResult.HttpContext; if (!context.SkipAuth) { this.GetSigner(context).DoAuth(httpRequest, context, this.GetIHeaders(context)); } if (!context.ObsConfig.KeepAlive && !httpRequest.Headers.ContainsKey(Constants.CommonHeaders.Connection)) { httpRequest.Headers.Add(Constants.CommonHeaders.Connection, "Close"); } HttpWebRequest request = HttpWebRequestFactory.BuildWebRequest(httpRequest, context); asyncResult.HttpWebRequest = request; asyncResult.HttpStartDateTime = DateTime.Now; if (httpRequest.Method == HttpVerb.PUT || httpRequest.Method == HttpVerb.POST || httpRequest.Method == HttpVerb.DELETE) { this.BeginSetContent(asyncResult); } else { asyncResult.Continue(this.EndGetResponse); } }
internal HttpObsAsyncResult BeginPerformRequest(HttpRequest request, HttpContext context, AsyncCallback callback, object state) { this.PrepareRequestAndContext(request, context); HttpObsAsyncResult result = new HttpObsAsyncResult(callback, state); result.HttpRequest = request; result.HttpContext = context; result.OriginPos = (request.Content != null && request.Content.CanSeek) ? request.Content.Position : -1L; result.RetryCount = 0; result.RequestStartDateTime = DateTime.Now; this.BeginDoRequest(result); return(result); }
internal HttpResponse EndPerformRequest(HttpObsAsyncResult result) { HttpResponse response = null; HttpRequest request = result.HttpRequest; HttpContext context = result.HttpContext; int maxErrorRetry = context.ObsConfig.MaxErrorRetry; long originPos = result.OriginPos; try { response = context.ObsConfig.AsyncSocketTimeout < 0 ? result.Get() : result.Get(context.ObsConfig.AsyncSocketTimeout); new MergeResponseHeaderHandler(this.GetIHeaders(context)); int statusCode = Convert.ToInt32(response.StatusCode); new MergeResponseHeaderHandler(this.GetIHeaders(context)).Handle(response); if (LoggerMgr.IsDebugEnabled) { LoggerMgr.Debug(string.Format("Response with statusCode {0} and headers {1}", statusCode, CommonUtil.ConvertHeadersToString(response.Headers))); } 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; result.RetryCount--; if (ShouldRetry(request, null, result.RetryCount, maxErrorRetry)) { PrepareRetry(request, response, result.RetryCount, originPos, true); result.Reset(); this.BeginDoRequest(result); return(this.EndPerformRequest(result)); } else if (result.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, result.RetryCount, maxErrorRetry)) { if (LoggerMgr.IsWarnEnabled) { LoggerMgr.Warn("Retrying connection that failed with RequestTimeout error"); } PrepareRetry(request, response, result.RetryCount, originPos, true); result.Reset(); this.BeginDoRequest(result); return(this.EndPerformRequest(result)); } else if (result.RetryCount > maxErrorRetry && LoggerMgr.IsErrorEnabled) { LoggerMgr.Error("Exceeded maximum number of retries for RequestTimeout errors"); } } throw exception; } else if (statusCode >= 500) { if (ShouldRetry(request, null, result.RetryCount, maxErrorRetry)) { PrepareRetry(request, response, result.RetryCount, originPos, true); result.Reset(); this.BeginDoRequest(result); return(this.EndPerformRequest(result)); } else if (result.RetryCount > maxErrorRetry && LoggerMgr.IsErrorEnabled) { LoggerMgr.Error("Encountered too many 5xx errors"); } throw ParseObsException(response, "Request error", context); } foreach (HttpResponseHandler handler in context.Handlers) { handler.Handle(response); } return(response); } catch (Exception ex) { try { if (ex is ObsException) { if (LoggerMgr.IsErrorEnabled) { LoggerMgr.Error("Rethrowing as a ObsException error in EndPerformRequest", ex); } throw ex; } else { if (ShouldRetry(request, ex, result.RetryCount, maxErrorRetry)) { PrepareRetry(request, response, result.RetryCount, originPos, true); result.Reset(); this.BeginDoRequest(result); return(this.EndPerformRequest(result)); } else if (result.RetryCount > 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, result.HttpContext); } } finally { CommonUtil.CloseIDisposable(response); } } }