#hostname #validation #idna #publicsuffix #punycode

adbyss_psl

A minimal Public Suffix List hostname validator

59 releases (12 breaking)

0.15.1 Nov 28, 2024
0.14.0 Oct 22, 2024
0.11.1 Jul 25, 2024
0.10.1 Mar 21, 2024
0.4.2 Jul 29, 2021

#290 in Web programming

Download history 18/week @ 2024-08-12 157/week @ 2024-09-02 4/week @ 2024-09-09 7/week @ 2024-09-16 139/week @ 2024-09-23 8/week @ 2024-09-30 163/week @ 2024-10-14 201/week @ 2024-10-21 7/week @ 2024-10-28 40/week @ 2024-11-04 128/week @ 2024-11-11 28/week @ 2024-11-18 147/week @ 2024-11-25

344 downloads per month

WTFPL license

110KB
1K SLoC

Adbyss: Public Suffix

docs.rs changelog
crates.io ci deps.rs
license contributions welcome

This library contains a single public-facing struct — adbyss_psl::Domain — used for validating and normalizing Internet hostnames, like "www.domain.com".

It will:

  • Validate, normalize, and Puny-encode internationalized/Unicode labels (RFC 3492);
  • Validate and normalize the public suffix;
  • Ensure conformance with RFC 1123;
  • And locate the boundaries of the subdomain (if any), root (required), and suffix (required);

Examples

New instances of Domain can be initialized using either Domain::new or TryFrom<&str>.

use adbyss_psl::Domain;

// These are equivalent and fine:
assert!(Domain::new("www.MyDomain.com").is_some());
assert!(Domain::try_from("www.MyDomain.com").is_ok());

// The following is valid DNS, but invalid as an Internet hostname:
assert!(Domain::new("_acme-challenge.mydomain.com").is_none());

Valid Internet hostnames must be no longer than 253 characters, and contain both root and (valid) suffix components.

Their labels — the bits between the dots — must additionally:

  • Be no longer than 63 characters;
  • (Ultimately) contain only ASCII letters, digits, and -;
  • Start and end with an alphanumeric character;

Unicode/internationalized labels are allowed, but must be Puny-encodable and not contain any conflicting bidirectionality constraints. Domain will encode such labels using Punycode when it finds them, ensuring the resulting hostname will always be ASCII-only.

Post-parsing, Domain gives you access to each individual component, or the whole thing:

use adbyss_psl::Domain;

let dom = Domain::new("www.MyDomain.com").unwrap();

// Pull out the pieces if you're into that sort of thing.
assert_eq!(dom.host(), "www.mydomain.com");
assert_eq!(dom.subdomain(), Some("www"));
assert_eq!(dom.root(), "mydomain");
assert_eq!(dom.suffix(), "com");
assert_eq!(dom.tld(), "mydomain.com");

// If you just want the sanitized host back as an owned value, use
// `Domain::take` or `String::from`:
let owned = dom.take(); // "www.mydomain.com"

Optional Crate Features

  • serde: Enables serialization/deserialization support.

Dependencies

~2–3MB
~53K SLoC