matchit
matchit copied to clipboard
Route with underscore produces unexpected `ExtraTrailingSlash` error instead of `NotFound`
Hi,
I encountered this behaviour when working with axum. I'm not sure whether this is intended or not but for me it was unexpected.
This code returns an MissingTrailingSlash
error instead of a NotFound
error:
let mut with_underscore = Router::new();
with_underscore.insert("/frontend_api", "Welcome!")?;
with_underscore.insert("/frontend/aaaa", "A User")?;
with_underscore.at("/frontend/").unwrap();
This seems to happen when adding two routes, one with an underscore at the same position where the other one has a slash.
I tried different combinations of routes and only the version described above returned an unintuitive error:
use matchit::Router;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// ExtraTrailingSlash, expected NotFound
let mut with_underscore = Router::new();
with_underscore.insert("/frontend_api", "Welcome!")?;
with_underscore.insert("/frontend/aaaa", "A User")?;
let with_underscore = with_underscore.at("/frontend/");
match with_underscore{
Ok(_) => {}
Err(e) => {
println!("with_underscore: \t {e}");
}
}
// NotFound
let mut without_underscore = Router::new();
without_underscore.insert("/frontend/api", "Welcome!")?;
without_underscore.insert("/frontend/aaaa", "A User")?;
let without_underscore = without_underscore.at("/frontend/");
match without_underscore{
Ok(_) => {}
Err(e) => {
println!("without_underscore: \t {e}");
}
}
// NotFound
let mut underscore_at_dif_pos = Router::new();
underscore_at_dif_pos.insert("/front_endapi", "Welcome!")?;
underscore_at_dif_pos.insert("/frontend/aaaa", "A User")?;
let underscore_at_dif_pos = underscore_at_dif_pos.at("/frontend/");
match underscore_at_dif_pos{
Ok(_) => {}
Err(e) => {
println!("underscore_at_dif_pos: \t {e}");
}
}
// NotFound
let mut without_second_route = Router::new();
without_second_route.insert("/frontend/aaaa", "A User")?;
let without_second_route = without_second_route.at("/frontend/");
match without_second_route{
Ok(_) => {}
Err(e) => {
println!("without_second_route: \t {e}");
}
}
// ExtraTrailingSlash
let mut only_frontend = Router::new();
only_frontend.insert("/frontend", "A User")?;
let only_frontend = only_frontend.at("/frontend/");
match only_frontend{
Ok(_) => {}
Err(e) => {
println!("only_frontend: \t\t {e}");
}
}
// NotFound
let mut different_name = Router::new();
different_name.insert("/something_else", "Welcome!")?;
different_name.insert("/frontend/aaaa", "A User")?;
let different_name = different_name.at("/frontend/");
match different_name{
Ok(_) => {}
Err(e) => {
println!("different_name: \t {e}");
}
}
Ok(())
}
Cargo.toml:
[dependencies]
matchit = "0.6.0"
This does look like a bug. I'll look into it.
Seems it's not only an underscore that causes an issue, any character after the matching prefix causes a false positive in the check here.
Keeping this open until the fix is released.
Released in 0.7.0.