servo / rust-url

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

URL with empty password is parsed as None #793

Open nemosupremo opened 2 years ago

nemosupremo commented 2 years ago

Trying to parse a URL with an empty password will (incorrectly?) have password be set to None. However if you set password to Some(""), then call url.to_string(), then the password separator in the url will be set. parse and to_string will fail to round trip in this edge case.

let mut url = match reqwest::Url::parse("rtsp://administrator:@google.com/") {
    Ok(u) => u,
    Err(err) => {
        println!("'{}': {}", url, err);
        return;
     }
};
assert_eq!(url.password(), Some("")); // fails
url.set_password(Some(""));
assert_eq!(url.to_string(), "rtsp://administrator:@google.com/"); // passes
valenting commented 2 years ago

According to the reference URL parser rtsp://administrator:@google.com/ should be parsed as rtsp://administrator@google.com/.

I think setting the password to "" should be special cased instead, to ensure we don't get a different behaviour.

tmccombs commented 2 years ago

FWIW, I believe that at least for http basic authentication, the absence of a password and an empty password are equivalent.

nemosupremo commented 2 years ago

Ok, interesting, the issue came up because we use this library for rtsp urls and the remote server was treating the absence of a password and an empty password differently. The fact that the round trip from parse -> to_string wasn't consistent is what led me to open the issue.

Can I assume this is probably a wont-fix then?

raccmonteiro commented 1 year ago

Accordingly to standard (https://url.spec.whatwg.org/#url-representation) when the url does not have a password we should get an empty string: "A URL’s password is an ASCII string identifying a password. It is initially the empty string." I created this PR https://github.com/servo/rust-url/pull/804, after merge the reported issue is a no issue, because the output will be "" (empty string) with rtsp://administrator:@google.com/ and rtsp://administrator@google.com/