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

feat: A username method for Authority #596

Open
WhyNotHugo opened this issue Mar 29, 2023 · 5 comments
Open

feat: A username method for Authority #596

WhyNotHugo opened this issue Mar 29, 2023 · 5 comments

Comments

@WhyNotHugo
Copy link

WhyNotHugo commented Mar 29, 2023

A function to extract usernames from Uris/Authoritys would be super userful. E.g.:

/// Returns None if there is no `@` in the authority section.
fn (self: Authority) -> Option<&str>

The docs for http::uri::Uri::authority mention:

The authority also includes a username:password component, however the use of this is deprecated and should be avoided.

However, I can't find any reference to this being deprecated anywhere. rfc6764 is still current and expects this format to be used in the context of caldav and carddav (which is just xml over http). rfc6068 also still uses this, albeit in the context of email.

@WhyNotHugo
Copy link
Author

WhyNotHugo commented Mar 29, 2023

Huh, looks like http::uri::Uri::authority is broken for URIs that are not URLs. This should fail:

let u : Uri = "mailto:someone@example.com".parse().unwrap();
assert_eq!(u.authority().unwrap().as_str(), "mailto:someone@example.com");

So while this should work, the fact that FromStr is broken is a blocker here:

pub fn username_from_uri(uri: &Uri) -> Option<&str> {
    let mut parts = uri.authority()?.as_str().rsplit('@');
    parts.next().expect("split always yields at least one item");
    parts.next()?.split(':').next()
}

@WhyNotHugo
Copy link
Author

The docs for http::uri::Uri are correct in the description of an Uri:

abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
|-|   |-------------------------------||--------| |-------------------| |-----|
 |                  |                       |               |              |
scheme          authority                 path            query         fragment

But the implementation is broken; only URLs are parsed correctly, anything without :// (which is indicated optional above) fails to parse:

    #[test]
    fn should_fail() {
        let u : Uri = "mailto:someone@example.com".parse().unwrap();
        assert_eq!(u.authority().unwrap().as_str(), "mailto:someone@example.com");
        assert_eq!(u.scheme(), None);
    }

@WhyNotHugo
Copy link
Author

WhyNotHugo commented Mar 29, 2023

src/uri/scheme.rs:296 bails from parsing the scheme with comment Not a scheme if the colon is not followed by //.

@WhyNotHugo
Copy link
Author

Actually fixing this is a lot harder that it seems, because of these two very ugly (but valid) edge cases:

  • localhost:3000 (not sure if strictly valid, but currently accepted).
  • mailto:root (perfectly valid).

@WhyNotHugo
Copy link
Author

For context, I'm writing a caldav client. As per the rfc, a user should only need to input an Uri, which can be either mailto: or http(s). Discovery of the exact server host and port is done via DNS using the domain part of the mailto: Uri.

The natural choice for me is to use the existing Uri type, but the same functions can take as input both Uri variants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant