public override void Process(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { ProcessAsync(message, pipeline, false).EnsureCompleted(); }
public override async Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); await BufferResponse(message, true).ConfigureAwait(false); }
protected static async Task ProcessNextAsync(ReadOnlyMemory <HttpPipelinePolicy> pipeline, HttpPipelineMessage message) { if (pipeline.IsEmpty) { throw new InvalidOperationException("last policy in the pipeline must be a transport"); } var next = pipeline.Span[0]; await next.ProcessAsync(message, pipeline.Slice(1)).ConfigureAwait(false); }
public override Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { Debug.Assert(pipeline.IsEmpty); return(_transport.ProcessAsync(message)); }
public override async ValueTask ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { await ProcessAsync(message, pipeline, true).ConfigureAwait(false); }
/// <summary> /// Applies the policy to the <see cref="message"/>. Implementers are expected to mutate <see cref="HttpPipelineMessage.Request"/> before calling <see cref="ProcessNextAsync"/> and observe the <see cref="HttpPipelineMessage.Response"/> changes after. /// Last policy in the pipeline is expected to set the <see cref="HttpPipelineMessage.Response"/> /// </summary> /// <param name="message">The <see cref="HttpPipelineMessage"/> this policy would be applied to.</param> /// <param name="pipeline">The set of <see cref="HttpPipelinePolicy"/> to execute after current one.</param> /// <returns></returns> public abstract Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline);
public abstract void Process(HttpPipelineMessage message);
private static async Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool async) { if (!s_eventSource.IsEnabled()) { if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } return; } s_eventSource.Request(message.Request); Encoding?requestTextEncoding = null; bool textRequest = message.Request.TryGetHeader(HttpHeader.Names.ContentType, out var contentType) && ContentTypeUtilities.TryGetTextEncoding(contentType, out requestTextEncoding); if (message.Request.Content != null) { if (textRequest) { if (async) { await s_eventSource.RequestContentTextAsync(message.Request, requestTextEncoding !, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.RequestContentText(message.Request, requestTextEncoding !, message.CancellationToken); } } else { if (async) { await s_eventSource.RequestContentAsync(message.Request, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.RequestContent(message.Request, message.CancellationToken); } } } var before = Stopwatch.GetTimestamp(); if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } var after = Stopwatch.GetTimestamp(); bool isError = message.ResponseClassifier.IsErrorResponse(message); var textResponse = ContentTypeUtilities.TryGetTextEncoding(message.Response.Headers.ContentType, out Encoding? responseTextEncoding); bool wrapResponseStream = message.Response.ContentStream != null && message.Response.ContentStream?.CanSeek == false && s_eventSource.ShouldLogContent(isError); if (wrapResponseStream) { message.Response.ContentStream = new LoggingStream( message.Response.ClientRequestId, s_eventSource, message.Response.ContentStream !, isError, responseTextEncoding); } if (isError) { s_eventSource.ErrorResponse(message.Response); if (!wrapResponseStream && message.Response.ContentStream != null) { if (textResponse) { if (async) { await s_eventSource.ErrorResponseContentTextAsync(message.Response, responseTextEncoding !, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.ErrorResponseContentText(message.Response, responseTextEncoding !); } } else { if (async) { await s_eventSource.ErrorResponseContentAsync(message.Response, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.ErrorResponseContent(message.Response); } } } } s_eventSource.Response(message.Response); if (!wrapResponseStream && message.Response.ContentStream != null) { if (textResponse) { if (async) { await s_eventSource.ResponseContentTextAsync(message.Response, responseTextEncoding !, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.ResponseContentText(message.Response, responseTextEncoding !); } } else { if (async) { await s_eventSource.ResponseContentAsync(message.Response, message.CancellationToken).ConfigureAwait(false); } else { s_eventSource.ResponseContent(message.Response); } } } var elapsedMilliseconds = (after - before) * 1000 / s_frequency; if (elapsedMilliseconds > DelayWarningThreshold) { s_eventSource.ResponseDelay(message.Response, elapsedMilliseconds); } }
public override void Process(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { Debug.Assert(pipeline.IsEmpty); _transport.Process(message); }
internal HttpMessageOptions(HttpPipelineMessage message) => _message = message;
/// <summary> /// Specifies if the response is not successful but can be retried. /// </summary> public virtual bool IsErrorResponse(HttpPipelineMessage message) { var statusKind = message.Response.Status / 100; return(statusKind == 4 || statusKind == 5); }
/// <summary> /// Specifies if the response should terminate the pipeline and not be retried. /// </summary> public virtual bool IsRetriableResponse(HttpPipelineMessage message) { return(message.Response.Status == 429 || message.Response.Status == 503); }
public override void Process(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { ProcessNext(message, pipeline); BufferResponse(message, false).EnsureCompleted(); }
/// <summary> /// Invokes the next <see cref="HttpPipelinePolicy"/> in the <see cref="pipeline"/>. /// </summary> /// <param name="message">The <see cref="HttpPipelineMessage"/> next policy would be applied to.</param> /// <param name="pipeline">The set of <see cref="HttpPipelinePolicy"/> to execute after next one.</param> /// <returns></returns> protected static Task ProcessNextAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { return(pipeline.Span[0].ProcessAsync(message, pipeline.Slice(1))); }
public abstract ValueTask ProcessAsync(HttpPipelineMessage message);
protected static void ProcessNext(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { pipeline.Span[0].Process(message, pipeline.Slice(1)); }
public override void Process(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { OnSendingRequest(message); ProcessNext(message, pipeline); OnReceivedResponse(message); }
private async Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool async) { int attempt = 0; List <Exception> exceptions = null; while (true) { Exception lastException = null; try { if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } } catch (Exception ex) { if (exceptions == null) { exceptions = new List <Exception>(); } exceptions.Add(ex); lastException = ex; } TimeSpan delay; attempt++; var shouldRetry = attempt <= _maxRetries; if (lastException != null) { if (shouldRetry && message.ResponseClassifier.IsRetriableException(lastException)) { GetDelay(attempt, out delay); } else { // Rethrow a singular exception if (exceptions.Count == 1) { ExceptionDispatchInfo.Capture(lastException).Throw(); } throw new AggregateException($"Retry failed after {attempt} tries.", exceptions); } } else if (message.ResponseClassifier.IsErrorResponse(message.Response)) { if (shouldRetry && message.ResponseClassifier.IsRetriableResponse(message.Response)) { GetDelay(message, attempt, out delay); } else { return; } } else { return; } if (delay > TimeSpan.Zero) { if (async) { await WaitAsync(delay, message.CancellationToken).ConfigureAwait(false); } else { Wait(delay, message.CancellationToken); } } HttpPipelineEventSource.Singleton.RequestRetrying(message.Request, attempt); } }
public virtual void OnSendingRequest(HttpPipelineMessage message) { }
private async ValueTask ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool async) { if (!s_eventSource.IsEnabled()) { if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } return; } s_eventSource.Request(message.Request); Encoding?requestTextEncoding = null; if (message.Request.TryGetHeader(HttpHeader.Names.ContentType, out var contentType)) { ContentTypeUtilities.TryGetTextEncoding(contentType, out requestTextEncoding); } var logWrapper = new ContentEventSourceWrapper(s_eventSource, _logContent, _maxLength, message.CancellationToken); await logWrapper.LogAsync(message.Request.ClientRequestId, message.Request.Content, requestTextEncoding, async).ConfigureAwait(false).EnsureCompleted(async); var before = Stopwatch.GetTimestamp(); if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } var after = Stopwatch.GetTimestamp(); bool isError = message.ResponseClassifier.IsErrorResponse(message); ContentTypeUtilities.TryGetTextEncoding(message.Response.Headers.ContentType, out Encoding? responseTextEncoding); bool wrapResponseContent = message.Response.ContentStream != null && message.Response.ContentStream.CanSeek == false && logWrapper.IsEnabled(isError); if (isError) { s_eventSource.ErrorResponse(message.Response); } else { s_eventSource.Response(message.Response); } if (wrapResponseContent) { message.Response.ContentStream = new LoggingStream(message.Response.ClientRequestId, logWrapper, _maxLength, message.Response.ContentStream !, isError, responseTextEncoding); } else { await logWrapper.LogAsync(message.Response.ClientRequestId, isError, message.Response.ContentStream, responseTextEncoding, async).ConfigureAwait(false).EnsureCompleted(async); } var elapsedMilliseconds = (after - before) * 1000 / Stopwatch.Frequency; if (elapsedMilliseconds > DelayWarningThreshold) { s_eventSource.ResponseDelay(message.Response, elapsedMilliseconds); } }
public virtual void OnReceivedResponse(HttpPipelineMessage message) { }
public abstract void Process(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline);
public override void Process(HttpPipelineMessage message) { // Intentionally blocking here ProcessAsync(message).GetAwaiter().GetResult(); }
protected static void ProcessNext(ReadOnlyMemory <HttpPipelinePolicy> pipeline, HttpPipelineMessage message) { if (pipeline.IsEmpty) { throw new InvalidOperationException("last policy in the pipeline must be a transport"); } pipeline.Span[0].Process(message, pipeline.Slice(1)); }
public ValueTask SendAsync(HttpPipelineMessage message, CancellationToken cancellationToken) { message.CancellationToken = cancellationToken; return(_pipeline.Span[0].ProcessAsync(message, _pipeline.Slice(1))); }
public override ValueTask ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline) { return(ProcessAsync(message, pipeline, true)); }
public void Send(HttpPipelineMessage message, CancellationToken cancellationToken) { message.CancellationToken = cancellationToken; _pipeline.Span[0].Process(message, _pipeline.Slice(1)); }
public override void OnSendingRequest(HttpPipelineMessage message) { message.Request.Headers.Add(HttpHeader.Names.UserAgent, _header); }
private async ValueTask ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool isAsync) { if (!_isDistributedTracingEnabled) { if (isAsync) { await ProcessNextAsync(message, pipeline, true).ConfigureAwait(false); } else { ProcessNextAsync(message, pipeline, false).EnsureCompleted(); } return; } if (!s_diagnosticSource.IsEnabled()) { await ProcessNextAsync(message, pipeline, isAsync).ConfigureAwait(false); return; } var activity = new Activity("Azure.Core.Http.Request"); activity.AddTag("http.method", message.Request.Method.Method); activity.AddTag("http.url", message.Request.Uri.ToString()); activity.AddTag("requestId", message.Request.ClientRequestId); if (message.Request.Headers.TryGetValue("User-Agent", out string?userAgent)) { activity.AddTag("http.user_agent", userAgent); } var diagnosticSourceActivityEnabled = s_diagnosticSource.IsEnabled(activity.OperationName, message); if (diagnosticSourceActivityEnabled) { s_diagnosticSource.StartActivity(activity, message); } else { activity.Start(); } if (isAsync) { await ProcessNextAsync(message, pipeline, true).ConfigureAwait(false); } else { ProcessNextAsync(message, pipeline, false).EnsureCompleted(); } activity.AddTag("http.status_code", message.Response.Status.ToString(CultureInfo.InvariantCulture)); activity.AddTag("serviceRequestId", message.Response.Headers.RequestId); if (diagnosticSourceActivityEnabled) { s_diagnosticSource.StopActivity(activity, message); } else { activity.Stop(); } }