Description
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
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