private void GetResponseCallBack_(TaskListener <HttpResponseMessage> listener, IAsyncResult result, HttpRequestMessage originalRequest, Logger logger, BackoffProvider backoffProvider) { if (!result.IsCompleted) { logger.Log(TraceLevel.Warn, Stage.General, StageType.RequestFailed, new { message = "result is not complete.", result }); return; } try { Task <HttpResponseMessage> resultAsTask = (Task <HttpResponseMessage>)result; if (resultAsTask.IsFaulted) { if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider)) { return; } listener.OnFail( new EyesException($"HttpRequestMessage request failed: {originalRequest.Method} {originalRequest.RequestUri}", resultAsTask.Exception)); return; } if (resultAsTask.IsCanceled) { if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider)) { return; } listener.OnFail( new TimeoutException($"HttpRequestMessage request timed out: {originalRequest.Method} {originalRequest.RequestUri}")); return; } HttpResponseMessage response = resultAsTask.Result; if (response.StatusCode >= HttpStatusCode.Ambiguous) { listener.OnFail(new EyesException($"Wrong response status: {response.StatusCode} {response.ReasonPhrase}")); } else { listener.OnComplete(response); } response.Dispose(); } catch (WebException ex) { if (MakeAnotherAttempt_(listener, originalRequest, logger, backoffProvider)) { return; } listener.OnFail(ex); } }
private void OnComplete_(HttpResponseMessage response) { Uri location = response.Headers.Location; RetryConditionHeaderValue secondsToWait = response.Headers.RetryAfter; try { HttpStatusCode status = response.StatusCode; if (status == HttpStatusCode.Created) { logger_?.Verbose("exit (CREATED)"); restClient_.SendAsyncRequest(listener_, location, "DELETE"); return; } if (status != HttpStatusCode.OK) { listener_.OnFail(new EyesException($"Got bad status code when polling from the server. Status code: {status}")); return; } } finally { response.Dispose(); } if (location != null) { pollingUrl_ = location; } int timeToWait = sleepDuration_; if (secondsToWait != null) { timeToWait = (int)secondsToWait.Delta.Value.TotalMilliseconds; } else if (requestCount_++ >= 5) { sleepDuration_ *= 2; requestCount_ = 0; sleepDuration_ = Math.Min(5000, sleepDuration_); } Thread.Sleep(timeToWait); logger_?.Verbose("polling..."); restClient_.SendAsyncRequest(this, pollingUrl_, "GET"); }
private void SendLongRequest_(TaskListener <HttpResponseMessage> listener, string path, string method, Stream body, string contentType, string accept, string contentEncoding) { Stopwatch sw = Stopwatch.StartNew(); HttpRequestMessage request = null; try { try { Uri requestUri = string.IsNullOrEmpty(path) ? ServerUrl : new Uri(ServerUrl, path); request = CreateHttpRequestMessage( requestUri, method, body, contentType, accept, contentEncoding); if (request == null) { throw new NullReferenceException("request is null"); } CancellationTokenSource cts = new CancellationTokenSource(Timeout); IAsyncResult asyncResult = GetHttpClient().SendAsync(request, cts.Token). AsApm(ar => OnLongRequestResponse_(ar, request), request, Logger); if (asyncResult != null && asyncResult.CompletedSynchronously) { Logger.Log(TraceLevel.Notice, Stage.General, new { message = "request.BeginGetResponse completed synchronously" }); OnLongRequestResponse_(asyncResult, request); } } catch (WebException ex) { if (request == null || ex.Response == null) { throw; } listener.OnFail(ex); } } catch (Exception ex2) { if (request != null && RequestFailed != null) { var args = new HttpRequestFailedEventArgs(sw.Elapsed, request, ex2); CommonUtils.DontThrow(() => RequestFailed(this, args)); } throw; } void OnLongRequestResponse_(IAsyncResult result, HttpRequestMessage originalRequest) { if (!result.IsCompleted) { Logger.Log(TraceLevel.Notice, Stage.General, new { message = "long request not complete" }); return; } try { Task <HttpResponseMessage> resultAsTask = (Task <HttpResponseMessage>)result; if (resultAsTask.IsFaulted) { listener.OnFail( new EyesException($"HttpRequestMessage request failed: {originalRequest.Method} {originalRequest.RequestUri}", resultAsTask.Exception)); return; } HttpResponseMessage response = resultAsTask.Result; if (response == null) { throw new NullReferenceException("response is null"); } Uri statusUrl = response.Headers.Location; RequestPollingTaskListener requestPollingListener = new RequestPollingTaskListener(this, statusUrl, listener); SendAsyncRequest(requestPollingListener, statusUrl, "GET"); } catch (Exception ex) { CommonUtils.LogExceptionStackTrace(Logger, Stage.General, ex); listener.OnFail(ex); } } }