leptos-rs / leptos

Build fast web applications with Rust.
https://leptos.dev
MIT License
16.43k stars 658 forks source link

router/ParamsMap: URL wildcard match containing "%2F" cannot be distinguished from "/" #3183

Open wrl opened 4 weeks ago

wrl commented 4 weeks ago

The current ParamsMap implementation always unescapes param values. This means that, in a wildcard match at the end of a URL, the app has no way of distinguishing a slash as a URL separator from a slash that was originally a "%2F".

Example code:

let mut p = leptos_router::params::ParamsMap::new();
p.insert("rest", "/foo/bar/one%2Ftwo/".into());
assert_eq!(p.get_str("rest"), Some("/foo/bar/one/two/"));
gbj commented 3 weeks ago

This is an accurate statement.

Could you say more about what the issue is? For example, "I'm trying to parse the string by splitting it apart at / so I want to preserve the escape characters"?

Related discussion re: escaped vs unescaped characters in (query or path) params in #2601 #2602 #2651.

gbj commented 3 weeks ago

(Thinking on it a little more, the fact that it's a wildcard segment and specifically the escape code for / is what makes this different from all other cases, I guess.)

wrl commented 3 weeks ago

(Thinking on it a little more, the fact that it's a wildcard segment and specifically the escape code for / is what makes this different from all other cases, I guess.)

Yeah, that's it, the wildcard match is all delivered as one string and the app is responsible for splitting it into segments. There's other ways of approaching this – for example, a wildcard segment could instead handle the splitting before inserting into the params map, and then wildcard segments would be Vec<String> or Box<[String]> instead of just String.

gbj commented 3 weeks ago

There is also another, very simple solution here: When you have this particular kind of wildcard route, simply parse the URL yourself. It is only a line or two to .strip_prefix("...") from the path.