Skip to content

Commit

Permalink
Merge pull request #674 from 3scale-rs/add-authority-fn
Browse files Browse the repository at this point in the history
url: add the authority method
  • Loading branch information
valenting authored Oct 26, 2022
2 parents 359bc90 + d8d4753 commit 1c1e406
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
43 changes: 43 additions & 0 deletions url/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,8 @@ impl Url {
/// URLs that do *not* are either path-only like `unix:/run/foo.socket`
/// or cannot-be-a-base like `data:text/plain,Stuff`.
///
/// See also the `authority` method.
///
/// # Examples
///
/// ```
Expand All @@ -817,6 +819,47 @@ impl Url {
self.slice(self.scheme_end..).starts_with("://")
}

/// Return the authority of this URL as an ASCII string.
///
/// Non-ASCII domains are punycode-encoded per IDNA if this is the host
/// of a special URL, or percent encoded for non-special URLs.
/// IPv6 addresses are given between `[` and `]` brackets.
/// Ports are omitted if they match the well known port of a special URL.
///
/// Username and password are percent-encoded.
///
/// See also the `has_authority` method.
///
/// # Examples
///
/// ```
/// use url::Url;
/// # use url::ParseError;
///
/// # fn run() -> Result<(), ParseError> {
/// let url = Url::parse("unix:/run/foo.socket")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("file:///tmp/foo")?;
/// assert_eq!(url.authority(), "");
/// let url = Url::parse("https://user:password@example.com/tmp/foo")?;
/// assert_eq!(url.authority(), "user:password@example.com");
/// let url = Url::parse("irc://àlex.рф.example.com:6667/foo")?;
/// assert_eq!(url.authority(), "%C3%A0lex.%D1%80%D1%84.example.com:6667");
/// let url = Url::parse("http://àlex.рф.example.com:80/foo")?;
/// assert_eq!(url.authority(), "xn--lex-8ka.xn--p1ai.example.com");
/// # Ok(())
/// # }
/// # run().unwrap();
/// ```
pub fn authority(&self) -> &str {
let scheme_separator_len = "://".len() as u32;
if self.has_authority() && self.path_start > self.scheme_end + scheme_separator_len {
self.slice(self.scheme_end + scheme_separator_len..self.path_start)
} else {
""
}
}

/// Return whether this URL is a cannot-be-a-base URL,
/// meaning that parsing a relative URL string with this URL as the base will return an error.
///
Expand Down
44 changes: 44 additions & 0 deletions url/tests/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,3 +1162,47 @@ fn test_make_relative() {
assert_eq!(make_relative, None, "base: {}, uri: {}", base, uri);
}
}

#[test]
fn test_has_authority() {
let url = Url::parse("mailto:joe@example.com").unwrap();
assert!(!url.has_authority());
let url = Url::parse("unix:/run/foo.socket").unwrap();
assert!(!url.has_authority());
let url = Url::parse("file:///tmp/foo").unwrap();
assert!(url.has_authority());
let url = Url::parse("http://example.com/tmp/foo").unwrap();
assert!(url.has_authority());
}

#[test]
fn test_authority() {
let url = Url::parse("mailto:joe@example.com").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("unix:/run/foo.socket").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("file:///tmp/foo").unwrap();
assert_eq!(url.authority(), "");
let url = Url::parse("http://example.com/tmp/foo").unwrap();
assert_eq!(url.authority(), "example.com");
let url = Url::parse("ftp://127.0.0.1:21/").unwrap();
assert_eq!(url.authority(), "127.0.0.1");
let url = Url::parse("ftp://user@127.0.0.1:2121/").unwrap();
assert_eq!(url.authority(), "user@127.0.0.1:2121");
let url = Url::parse("https://:@example.com/").unwrap();
assert_eq!(url.authority(), "example.com");
let url = Url::parse("https://:password@[::1]:8080/").unwrap();
assert_eq!(url.authority(), ":password@[::1]:8080");
let url = Url::parse("gopher://user:@àlex.example.com:70").unwrap();
assert_eq!(url.authority(), "user@%C3%A0lex.example.com:70");
let url = Url::parse("irc://àlex:àlex@àlex.рф.example.com:6667/foo").unwrap();
assert_eq!(
url.authority(),
"%C3%A0lex:%C3%A0lex@%C3%A0lex.%D1%80%D1%84.example.com:6667"
);
let url = Url::parse("https://àlex:àlex@àlex.рф.example.com:443/foo").unwrap();
assert_eq!(
url.authority(),
"%C3%A0lex:%C3%A0lex@xn--lex-8ka.xn--p1ai.example.com"
);
}

0 comments on commit 1c1e406

Please sign in to comment.