Giraffe.TokenRouter
Giraffe.TokenRouter copied to clipboard
Routing - no result on similar routes with first letter collision
I have unfortunately hit a rather subtle bug around similar routes and I am having trouble getting to the bottom of the route cause (there is quite a lot going on in the underlying algorithm that might make more sense to someone who knows the codebase). I am happy to dig in further but I may need a little help!
I have written a failing test that demonstrates the scenario:
[<Fact>]
let ``GET Similar routes should correctly resolve`` () =
let ctx = Substitute.For<HttpContext>()
let app =
router notFound [
GET [
routef "/api/%s" (fun _ -> text "a")
route "/api/csv" (text "b")
]
]
ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
ctx.Request.Path.ReturnsForAnyArgs (PathString("/api/cat")) |> ignore
ctx.Response.Body <- new MemoryStream()
let expected = "a"
task {
let! result = app next ctx
match result with
| None -> assertFailf "Result was expected to be %s" expected
| Some ctx -> Assert.Equal(expected, getBody ctx, true)
}
It looks like it is the first character of route segment that seems to be the issue here. If the first char is the same, it seems to bypass both routes and return NotFound. If I change either the positional parameter to "bat" for example, the example works.
In more complex scenarios this is leading to all sorts of problems. In my real app i have various routes like /api/guid/whatever, which seem to be spontaneously failing when using specific GUID's, which I have now discovered is because I have fixed routes of /api/{prefix}..../ which are colliding.
Please let me know where is best to go from here - I am happy to submit a PR with the failing test etc.