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

Cannot capture the correct param #88

Open
kingluo opened this issue Jun 6, 2021 · 5 comments
Open

Cannot capture the correct param #88

kingluo opened this issue Jun 6, 2021 · 5 comments
Labels
help wanted Extra attention is needed

Comments

@kingluo
Copy link

kingluo commented Jun 6, 2021

The url is:
.get("/hello/*/:name/*", hello_handler)

The handler:

async fn hello_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    let user = req.param("*").unwrap();
    let name = req.param("name").unwrap();
    Ok(Response::new(Body::from(format!(
        "Hello {:?}, {:?}",
        user, name
    ))))
}

The response should be:

$ curl -X GET -s -i localhost:8080/hello/foo/bar/foobar
HTTP/1.1 200 OK
content-length: 21
date: Sun, 06 Jun 2021 09:09:49 GMT

Hello "foobar", "bar"

But it gives wrong result:

$ curl -X GET -s -i localhost:8080/hello/foo/bar/foobar
HTTP/1.1 200 OK
x-powered-by: Routerify v2.0.1
content-length: 18
date: Sun, 06 Jun 2021 09:14:37 GMT

Hello "", "foobar"
@ta3pks
Copy link
Contributor

ta3pks commented Jun 6, 2021

here you are basically saying match everything and a name parameter your syntax is incorrect
Since you say match everything with * it matches everything until the last part which is captured by :name

@ta3pks ta3pks added the help wanted Extra attention is needed label Jun 6, 2021
@kingluo
Copy link
Author

kingluo commented Jun 7, 2021

Sorry, I don't understand what you mean.

The * would be replaced by (.*), and :name would be replaced by ([^/]+):
https://github.com/routerify/routerify/blob/master/src/regex_generator/mod.rs#L20

After matching, the second * would overwrite the first one. So, * should be foobar, and :name should be bar:
https://github.com/routerify/routerify/blob/master/src/route/mod.rs#L127

In my repo router-lite, the result is correct, but I don't figure out why it's different from routerify because I reuse the same codes from routerify.

You could try it in python and get the same result:

>>> import re
>>> m = re.match(r'^(.*)/([^/]+)/(.*)$', 'foo/foobar/bar')
>>> m.group(1)
'foo'
>>> m.group(2)
'foobar'
>>> m.group(3)
'bar'

@ta3pks
Copy link
Contributor

ta3pks commented Jun 7, 2021

.* matches everything until the last part that is matched by [^/]+ and the last catchall is basically empty.
https://regexr.com/5uvoo here I made a demo
Am I missing something? this seems to be the expected behaviour

@kingluo
Copy link
Author

kingluo commented Jun 7, 2021

Similarly, I found another issue. Routerify returns a capture value with an unexpected tailed slash.

The url:
.get("/hello/*", hello_handler)

The handler:

async fn hello_handler(req: Request<Body>) -> Result<Response<Body>, RouteError> {
    let user = req.param("*").unwrap();
    Ok(Response::new(Body::from(format!("Hello {:?}", user))))
}

The result:

$ curl -X GET -s -i localhost:8080/hello/foobar
HTTP/1.1 200 OK
x-powered-by: Routerify v2.0.1
content-length: 15
date: Mon, 07 Jun 2021 04:08:59 GMT

Hello "foobar/"

@kingluo
Copy link
Author

kingluo commented Jun 7, 2021

.* matches everything until the last part that is matched by [^/]+ and the last catchall is basically empty.
https://regexr.com/5uvoo here I made a demo
Am I missing something? this seems to be the expected behaviour

You miss the slash between the groups.
That is ^(.*)/([^/]+)/(.*)$, not ^(.*)([^/]+)(.*)$

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants