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

Routes to paths with URL-encoded chars fails to match and always results in 404 #2862

Open
4 tasks done
ludverse opened this issue Sep 7, 2024 · 1 comment
Open
4 tasks done
Labels
triage A bug report being investigated

Comments

@ludverse
Copy link

ludverse commented Sep 7, 2024

Rocket Version

0.5.1

Operating System

Debian Testing (upgraded last week)

Rust Toolchain Version

rustc 1.80.1 (3f5fd8dd4 2024-08-06)

What happened?

I'm trying to use URL-encoded chars in my routes and Rocket just responds with 404. Rocket manages to compile with the following test case, but the issue is that, as you can see in the log output:

GET /h%C3%A4cker:
   >> No matching routes for GET /h%C3%A4cker.
   >> No 404 catcher registered. Using Rocket default.

when i make the request to the exact same path as the get macro was defined as, Rocket fails to match my request to my route.

This way I've done it in the test case is a reasonable assumption to how Rocket would handle paths as according to this part of the docs, Origins should be URL-encoded.

Test Case

use rocket::{get, launch, routes};

#[get("/h%C3%A4cker")]
fn serve_hacker() -> &'static str {
    "Hello, world!"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![serve_hacker])
}

#[cfg(test)]
mod test {
    #[test]
    fn test_hacker_get() {
        use rocket::local::blocking::Client;

        let client = Client::tracked(super::rocket()).expect("valid `Rocket`");

        let response = client.get("/h%C3%A4cker").dispatch();
        assert_eq!(response.into_string().unwrap(), "Hello, world!");
    }
}

Log Output

> ROCKET_LOG_LEVEL=debug cargo test
   Compiling rocket-unicode-issue-test v0.1.0 (/home/ludv/coding/misc/rocket-unicode-issue-test)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1.11s
     Running unittests src/main.rs (target/debug/deps/rocket_unicode_issue_test-7fb95b3b05290781)

running 1 test
test test::test_hacker_get ... FAILED

failures:

---- test::test_hacker_get stdout ----
-- configuration trace information --
   >> "address" parameter source: rocket::Config::default()
   >> "port" parameter source: rocket::Config::default()
   >> "workers" parameter source: rocket::Config::default()
   >> "max_blocking" parameter source: rocket::Config::default()
   >> "keep_alive" parameter source: rocket::Config::default()
   >> "ident" parameter source: rocket::Config::default()
   >> "ip_header" parameter source: rocket::Config::default()
   >> "limits" parameter source: rocket::Config::default()
   >> "temp_dir" parameter source: rocket::Config::default()
   >> "log_level" parameter source: `ROCKET_` environment variable(s)
   >> "shutdown" parameter source: rocket::Config::default()
   >> "cli_colors" parameter source: rocket::Config::default()
🔧 Configured for debug.
   >> address: 127.0.0.1
   >> port: 8000
   >> workers: 12
   >> max blocking threads: 512
   >> ident: Rocket
   >> IP header: X-Real-IP
   >> limits: bytes = 8KiB, data-form = 2MiB, file = 1MiB, form = 32KiB, json = 1MiB, msgpack = 1MiB, string = 8KiB
   >> temp dir: /tmp
   >> http/2: true
   >> keep-alive: 5s
   >> tls: disabled
   >> shutdown: ctrlc = true, force = true, signals = [SIGTERM], grace = 2s, mercy = 3s
   >> log level: debug
   >> cli colors: true
📬 Routes:
   >> (serve_hacker) GET /h%C3%A4cker
📡 Fairings:
   >> Shield (liftoff, response, singleton)
🛡️  Shield:
   >> X-Frame-Options: SAMEORIGIN
   >> Permissions-Policy: interest-cohort=()
   >> X-Content-Type-Options: nosniff
🚀 Rocket has launched locally
GET /h%C3%A4cker:
   >> No matching routes for GET /h%C3%A4cker.
   >> No 404 catcher registered. Using Rocket default.
thread 'test::test_hacker_get' panicked at src/main.rs:22:9:
assertion `left == right` failed
  left: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"color-scheme\" content=\"light dark\">\n    <title>404 Not Found</title>\n</head>\n<body align=\"center\">\n    <div role=\"main\" align=\"center\">\n        <h1>404: Not Found</h1>\n        <p>The requested resource could not be found.</p>\n        <hr />\n    </div>\n    <div role=\"contentinfo\" align=\"center\">\n        <small>Rocket</small>\n    </div>\n</body>\n</html>"
 right: "Hello, world!"
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    test::test_hacker_get

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--bin rocket-unicode-issue-test`
Program exited erroneously with code 101

Additional Context

No response

System Checks

  • My bug report relates to functionality.
  • I have tested against the latest Rocket release or a recent git commit.
  • I have tested against the latest stable rustc toolchain.
  • I was unable to find this issue previously reported.
@ludverse ludverse added the triage A bug report being investigated label Sep 7, 2024
@ludverse
Copy link
Author

ludverse commented Sep 7, 2024

Oh ok, so actually I realized that the test case I gave actually does match, to /h%25C3%25A4cker, which is just /h%C3%A4cker URL-encoded another time.

So what happened was when I submitted this, was that I simplified the test case in the issue so much that I actually lost the root of the problem. The real problem disappeared when moved the /häcker/ from the rocket.mount() to the get macro. Here's an example that represents more my original code:

#[get("/")]
fn serve_hacker() -> &'static str {
    "Hello, world!"
}

#[get("/<id>")]
fn serve_id<'a>(id: &'a str) -> &'a str {
    id
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/häcker/", routes![serve_hacker, serve_id])
}

if you run this code, you will get an error:

> cargo run
   Compiling rocket-unicode-issue-test v0.1.0 (/home/ludv/coding/misc/rocket-unicode-issue-test)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.29s
     Running `target/debug/rocket-unicode-issue-test`
Error: invalid route base: /häcker/
   >> unexpected token byte 195 at index 2
   >> in src/main.rs:15:21
thread 'main' panicked at src/main.rs:15:21:
aborting due to route base error
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

So the issue I'm actually having is, Rocket::mount panics if you try to pass it any characters that aren't Unicode. So in actuality, I have a way of solving this problem by using the approach I showed off in the original post where I just put /häcker in the get macro instead of the mount base.

I'm sorry for my confusion here, ignore everything in the original post. What should I do with this issue now, should I close it and open a new one for the real problem or just edit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage A bug report being investigated
Projects
None yet
Development

No branches or pull requests

1 participant