reverse-proxy
reverse-proxy copied to clipboard
Request "/foo/" incorrectly matches to Ingress rule with Exact Path "/foo"
Describe the bug
@miaxzhitong found an issue when Ingress rule with Exact Path "/foo" matches a request "/foo/" (and the other way around too). Per https://kubernetes.io/docs/concepts/services-networking/ingress/#examples it should not match:
| Kind | Path(s) | Request path(s) | Matches? |
|---|---|---|---|
| Exact | /foo | /foo/ | No |
| Exact | /foo/ | /foo | No |
YARP inherits this behavior from ASP.NET Core's routing. Note that if you define routes that only differ by the trailing slash, requests will match both (and fail).
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/foo", (HttpRequest request) => $"Foo - {request.Path}");
app.MapGet("/bar/", (HttpRequest request) => $"Bar - {request.Path}");
app.MapGet("/baz", () => "Baz");
app.MapGet("/baz/", () => "Baz/");
const string Url = "http://localhost:5000";
_ = Task.Run(async () =>
{
using var client = new HttpClient();
Console.WriteLine(await client.GetStringAsync($"{Url}/foo")); // Matches foo
Console.WriteLine(await client.GetStringAsync($"{Url}/foo/")); // Matches foo
Console.WriteLine(await client.GetStringAsync($"{Url}/bar")); // Matches bar/
Console.WriteLine(await client.GetStringAsync($"{Url}/bar/")); // Matches bar/
Console.WriteLine((await client.GetAsync($"{Url}/baz")).StatusCode); // Ambiguous (500)
Console.WriteLine((await client.GetAsync($"{Url}/baz/")).StatusCode); // Ambiguous (500)
});
app.Run(Url);
Is this causing you problems in practice?