asp.net-corerequestmiddlewarems-yarp

Detect when YARP has forwarded a request while inside middleware


I have an ASP.NET middleware that I only want to run when it's not being forwarded with YARP.

Is there a way through Headers or anything else to detect that the current request is being forwarded with YARP?

Currently, I'm using the YARP setup that Microsoft adds when using the upgrade assistant for a .NET Framework to .NET 8 conversion.

var builder = WebApplication.CreateBuilder(args);
...    
builder.Services.AddHttpForwarder();
...
var app = builder.Build();
...
app.MapForwarder("/{**catch-all}", proxyTo)
    .Add(static builder => ((RouteEndpointBuilder)builder).Order = int.MaxValue);

Updated MapForwarder call based on advice from Qiang Fu:

app.MapForwarder("/{**catch-all}", proxyTo, (options) => 
{
    options.AddRequestTransform(async transformContext =>
    {
        Console.WriteLine($"Forwarding request to: {transformContext.DestinationPrefix}");
        await Task.CompletedTask;
    });
    options.AddResponseTransform(async transformContext =>
    {
        Console.WriteLine($"Response received with status code: {transformContext.HttpContext.Response.StatusCode}");
        await Task.CompletedTask;
    });
})
.Add(static builder => ((RouteEndpointBuilder)builder).Order = int.MaxValue);

The above will help you do any sort of logging inside of a redirect, but what I really wanted, and I've updated the title to be more clear, was the ability to detect a redirect inside of middleware so that I can choose if I really want it to run. Here is how I was able to do that:

Context.GetEndpoint()?.DisplayName == "/{**catch-all}";

Solution

  • You could use Transforms to detect the forwarding events.

    builder.Services.AddReverseProxy()
                .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
                    .AddTransforms(transformBuilderContext =>
                    {
                        // Before forwarding the request to the destination
                        transformBuilderContext.AddRequestTransform(async transformContext =>
                        {
                            Console.WriteLine($"Forwarding request to: {transformContext.DestinationPrefix}");
                            await Task.CompletedTask;
                        });
    
                        // After receiving the response from the destination
                        transformBuilderContext.AddResponseTransform(async transformContext =>
                        {
                            Console.WriteLine($"Response received with status code: {transformContext.HttpContext.Response.StatusCode}");
                            await Task.CompletedTask;
                        });
                    });