servo / rust-url

URL parser for Rust
https://docs.rs/url/
Apache License 2.0
1.31k stars 325 forks source link

Disabling "remove dot segments" behavior #874

Open jwodder opened 11 months ago

jwodder commented 11 months ago

I have a use-case where I need to be able to construct URLs that end in …/. or …/..[^1]; however, the url crate insists on removing dot segments no matter what API I go through, even when the dots are percent-escaped, e.g.:

fn main() {
    let url = url::Url::parse("https://example.com/path/%2e%2e").unwrap();
    // Prints "https://example.com/":
    println!("{url}");
}

Is there currently a method to construct a URL like this using this crate? If not, could such a method be added?

[^1]: Specifically, this is for manipulating GitHub labels via the GitHub REST API; if a user names a label with dot or dot-dot, the URL ends up with dots at the end.

valenting commented 11 months ago

This replacement is mandated by the URL standard, so I'd be slightly surprised if the server side doesn't parse the URLs in a similar way. Have a look at whether encoding the % sign works, so instead of %2e use %252e


use url::Url;

fn main() {
    let bs: &str = "https://example.org/path_to_replace";
    let mut base = Url::parse(bs).unwrap();
    base.path_segments_mut().unwrap().pop().push("%2e%2e");
    println!("{:?}", base); // prints path: "/%252e%252e"
}
jwodder commented 11 months ago

@valenting Testing GitHub's REST API via curl, curl https://api.github.com/repos/jwodder/test/labels/.. and …/labels/%252e%252e both result in 404; only …/labels/%2e%2e works.