Sovite.IDNA (sovite v0.6.0)

Copy Markdown View Source

Internationalized domain names (IDNA2008, RFC 5890–5893): conversion between U-labels (bücher.example) and A-labels (xn--bcher-kva.example), and their validation.

iex> Sovite.IDNA.to_ascii("Bücher.example")
{:ok, "xn--bcher-kva.example"}
iex> Sovite.IDNA.to_unicode("xn--bcher-kva.example")
{:ok, "bücher.example"}
iex> Sovite.IDNA.to_ascii("xn--bcher-kva.example")
{:ok, "xn--bcher-kva.example"}

to_ascii/1 maps its input first, as RFC 5895 suggests for names people type: it is lower-cased, normalized to NFC, and the ideographic full stops (。, ., 。) separate labels like .. Every label must then be an LDH label (letters, digits, and hyphens), an A-label whose decoding is a valid U-label, or a valid U-label: only code points IDNA2008 allows (see Sovite.IDNA.CodePoints), in NFC, not starting with a combining mark, without -- in the third and fourth positions, and following the contextual rules and, in domains with right-to-left labels, the Bidi rule. Results are lower-case.

A-labels are at most 63 octets, and the whole name in A-labels at most 253 octets. A trailing dot (the DNS root) is not accepted.

Summary

Types

Why a name is not a valid IDNA2008 domain name.

Functions

Whether name has A-labels or non-ASCII characters, so it is internationalized.

Converts a domain name to A-labels.

Converts a domain name to U-labels, checking it as to_ascii/1 does.

Whether name is a valid domain name in either form.

Types

error()

@type error() ::
  :empty_label
  | :too_long
  | :invalid_ldh
  | :invalid_a_label
  | :hyphen
  | :leading_combining_mark
  | :disallowed
  | :context
  | :bidi
  | :not_nfc

Why a name is not a valid IDNA2008 domain name.

Functions

international?(name)

@spec international?(String.t()) :: boolean()

Whether name has A-labels or non-ASCII characters, so it is internationalized.

to_ascii(name)

@spec to_ascii(String.t()) :: {:ok, String.t()} | {:error, error()}

Converts a domain name to A-labels.

to_unicode(name)

@spec to_unicode(String.t()) :: {:ok, String.t()} | {:error, error()}

Converts a domain name to U-labels, checking it as to_ascii/1 does.

valid?(name)

@spec valid?(term()) :: boolean()

Whether name is a valid domain name in either form.

iex> Sovite.IDNA.valid?("münchen.example")
true
iex> Sovite.IDNA.valid?("a b.example")
false