private async ValueTask <ForwarderError> HandleRequestFailureAsync(HttpContext context, StreamCopyHttpContent?requestContent, Exception requestException, HttpTransformer transformer, CancellationTokenSource requestCancellationSource) { if (requestException is OperationCanceledException) { if (!context.RequestAborted.IsCancellationRequested && requestCancellationSource.IsCancellationRequested) { return(await ReportErrorAsync(ForwarderError.RequestTimedOut, StatusCodes.Status504GatewayTimeout)); } else { return(await ReportErrorAsync(ForwarderError.RequestCanceled, StatusCodes.Status502BadGateway)); } } // Check for request body errors, these may have triggered the response error. if (requestContent?.ConsumptionTask.IsCompleted == true) { var(requestBodyCopyResult, requestBodyException) = requestContent.ConsumptionTask.Result; if (requestBodyCopyResult != StreamCopyResult.Success) { var error = HandleRequestBodyFailure(context, requestBodyCopyResult, requestBodyException !, requestException); await transformer.TransformResponseAsync(context, proxyResponse : null); return(error); } } // We couldn't communicate with the destination. return(await ReportErrorAsync(ForwarderError.Request, StatusCodes.Status502BadGateway)); async ValueTask <ForwarderError> ReportErrorAsync(ForwarderError error, int statusCode) { ReportProxyError(context, error, requestException); context.Response.StatusCode = statusCode; if (requestContent is not null && requestContent.InProgress) { requestCancellationSource.Cancel(); await requestContent.ConsumptionTask; } await transformer.TransformResponseAsync(context, null); return(error); } }
private static ValueTask <bool> CopyResponseStatusAndHeadersAsync(HttpResponseMessage source, HttpContext context, HttpTransformer transformer) { context.Response.StatusCode = (int)source.StatusCode; if (!ProtocolHelper.IsHttp2OrGreater(context.Request.Protocol)) { // Don't explicitly set the field if the default reason phrase is used if (source.ReasonPhrase != ReasonPhrases.GetReasonPhrase((int)source.StatusCode)) { context.Features.Get <IHttpResponseFeature>() !.ReasonPhrase = source.ReasonPhrase; } } // Copies headers return(transformer.TransformResponseAsync(context, source)); }