Skip to content

Updating HttpContext.Request.Path inside middleware has no effect in selecting the endpoint for the request #49454

Closed
@kshyju

Description

@kshyju

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

As mentioned in issues such as this and this, Azure app service FE/proxy decodes the encoded parts of the request URL path. The recommendation is to use the X-WAWS-Unencoded-URL header value to get the un decoded/raw value.

What is the right extensibility point in aspnet core pipeline to replace the current request path string value to the value of the above mentioned header, so that the routing module uses it and route it to the correct endpoint? The use case here is having a route parameter for which the value contains %2F (encoded version of /) in it.

[HttpGet]
[Route("api/departments/{dept}")]
public IActionResult Get(string dept)
{
    _logger.LogInformation($"Request received for dept:{dept}");

    return new OkObjectResult($"Param dept:{dept}");
}

and a request like this api/departments/cloud%2Fdevdiv

This code works fine locally, but fails when deployed to app service.

I wrote a middleware which replaces the request path of httpcontext and registered as the very first middleware in the request processing pipeline, but that does not seems to work.

public async Task InvokeAsync(HttpContext context)
{
    if (context.Request.Headers.TryGetValue("X-Waws-Unencoded-Url", out var unencodedUrlValue))
    {
        _logger.LogInformation($"X-Waws-Unencoded-Url header value: {unencodedUrlValue.First()}");
        context.Request.Path = unencodedUrlValue.First();
    }

    // Call the next delegate/middleware in the pipeline.
    await _next(context);
}

and

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddControllers();
    var app = builder.Build();

    app.UseMiddleware<RequestPathCheckMiddleware>();
   // other middlewares are registered here.

    app.MapControllers();
    app.Run();
}

Is this not the right extensibility point to make this change?

AI logs of 2 requests, one resulted in 200 OK and the other is 404

image

Expected Behavior

Should be able to replace the request path value with the raw value received from header and the routing/endpoint selection should respect that during the same request processing. Not looking to return a redirect response.

Steps To Reproduce

Code shared in he issue description is enough to repro. To validate locally, you may also try to replace the path value with the route to a different endpoint like below.

app.Use(async (context, next) =>
{
    var url = context.Request.Path.Value;
    if (url.Contains("/api/products"))
    {
        context.Request.Path = "/api/tags";
    }

    await next();
});

Here, the expected behavior is that, the /api/products request to be invoking the code from the endpoint with /api/tags route decoration.

Exceptions (if any)

No response

.NET Version

net6.0

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    ✔️ Resolution: AnsweredResolved because the question asked by the original author has been answered.Status: Resolvedarea-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions