Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

%s matches components of a path #347

Closed
alisterw opened this issue Mar 16, 2019 · 7 comments
Closed

%s matches components of a path #347

alisterw opened this issue Mar 16, 2019 · 7 comments
Labels
bug Reproducible bug ready for release Issue has been already resolved in the development branch

Comments

@alisterw
Copy link

I'm not sure if this is a bug or expected behaviour, but if I have this route:

routef "/foo/%s/%s" (fun (s1, s2) -> text (sprintf "%s,%s" s1 s2))

Then when I request /foo/a/b/c/d the first string contains a/b/c and the second contains d.

This is actually the behaviour I want, but it's very surprising to me. Can I rely on it, or is it unintended and liable to be fixed in future, thereby breaking me?

@alisterw alisterw changed the title %s matches components of a route %s matches components of a path Mar 16, 2019
@alisterw
Copy link
Author

As another experiment, I added this route:

routef "/bar/%c/%s" (fun (c1, s2) -> text (sprintf "%c,%s" c1 s2))

then requested /bar//xyzzy, which gave me / and xyzzy.

This also seems surprising.

@johlrich
Copy link

I also found this counter-intuitive and noticed routeBind works differently and matches the routes I originally expected routef to match. The following will not match /foo/a/b/c/d:

routeBind<TestRoute> "/foo/{s1}/{s2}" (fun route -> text (sprintf "%s,%s" route.s1 route.s2))

[<CLIMutable>]
type TestRoute = {
  s1: string
  s2: string
}

After taking a closer look, routef would match like routeBind if the %s regex were to map to "([^/]+)"

This failing test would pass with that change (without affecting any other test case):

[<Fact>]
let ``routef: GET "/foo/bar/baz/qux" returns 404 "Not found"`` () =
    let ctx = Substitute.For<HttpContext>()
    let app =
        GET >=> choose [
            routef "/foo/%s/%s" (fun (s1, s2) -> text (sprintf "%s,%s" s1 s2))
            setStatusCode 404 >=> text "Not found" ]

    ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
    ctx.Request.Path.ReturnsForAnyArgs (PathString("/foo/bar/baz/qux")) |> ignore
    ctx.Response.Body <- new MemoryStream()
    let expected = "Not found"

    task {
        let! result = app next ctx

        match result with
        | None     -> assertFailf "Result was expected to be %s" expected
        | Some ctx ->
            let body = getBody ctx
            Assert.Equal(expected, body)
            Assert.Equal(404, ctx.Response.StatusCode)
    }

It feels like a bug, but maybe changing routef is not a good idea since folks may depend on the current behavior even though it's not covered by a test. If the current behavior is expected, perhaps some documentation and an additional route* function is a more appropriate way to offer both options?

@alisterw
Copy link
Author

Agreed on the regex. I've also been toying with an implementation of catch-all routing for routeBind, so that you can have things like:

routeBind "/{*Foo}/{Bar}"

where Foo is a string, and then /a/b/c/d will route with Foo = "a/b/c" and Bar = d.

But it adds a fair bit of complexity so I might not bother submitting it as a PR.

@dustinmoris
Copy link
Member

dustinmoris commented Apr 16, 2019

@johlrich I will have a close look at your change and test today. I would prefer to fix the library to follow expected conventions rather than adding much documentation to explain unexpected behaviour. This would be a big breaking change indeed, but at this point I think the responsible thing to do is to mention this in big capital letters at the top of the release notes and increase the major version. I'll have a dig at this later today!

@dustinmoris dustinmoris added bug Reproducible bug ready for release Issue has been already resolved in the development branch labels Apr 20, 2019
@Lanayx
Copy link

Lanayx commented May 23, 2019

@dustinmoris Hi, I'm running into this issue as well, can you share when we should expect the 4.0 release to be out?

@maxdeviant
Copy link

Just ran into this as well (we're using routeCif, but I'm assuming the same fix applies).

@OnurGumus
Copy link

@dustinmoris, what if we want the old behavior?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Reproducible bug ready for release Issue has been already resolved in the development branch
Projects
None yet
Development

No branches or pull requests

6 participants