Converts DNS hostnames to their canonical comparison form following the
ratified canonical-host normalization contract: Unicode NFC, case mapping,
UTS-46 label mapping and validation (non-transitional, with
UseSTD3ASCIIRules, CheckHyphens, CheckBidi, and CheckJoiners),
conversion to lowercase ASCII A-labels, and DNS length verification, while
preserving whether the input carried a single terminal root dot.
Usage
host_normalize(
x,
check_hyphens = TRUE,
use_std3 = TRUE,
verify_dns_length = TRUE,
unicode_version = NULL
)Arguments
- x
Character vector of hostnames.
NAelements pass through asNA(missing, not invalid). Names are preserved.- check_hyphens
Logical scalar. When
TRUE(the default) the UTS #46CheckHyphensrule rejects"--"in the 3rd/4th positions and leading or trailing hyphens.FALSEdrops that check.- use_std3
Logical scalar. When
TRUE(the default)UseSTD3ASCIIRulesrestricts ASCII to letters, digits, and hyphen.FALSEadmits other ASCII (e.g."_") that the selected Unicode table set marks STD3-disallowed-but-valid.- verify_dns_length
Logical scalar. When
TRUE(the default) each A-label must be 1-63 octets and the whole host <= 253.FALSEdrops the length limits (empty labels are still rejected as structural errors).- unicode_version
Character scalar naming a Unicode table set this build ships, or
NULL(the default) for the pinned one. Seeunicode_versions(). An unshipped version is an error.
Value
A character vector the same length as x. Each element is the
canonical lowercase ASCII A-label host, or NA_character_ when the input
is NA or invalid under the profile.
Details
Unlike puny_encode(), invalid input is reported by returning
NA_character_ (never by aborting), so a caller can layer its own policy.
See normalization_profile_info() for the machine-readable identity of the
profile a given call applies.
A build ships one or more Unicode table sets and pins one of them as the
default; unicode_version selects among them and unicode_versions() lists
what is available. Naming a version the build does not ship is an error, not
a fall back to the default — a silent fallback would let a caller record a
profile identity describing a normalization that never ran. The Unicode
version is a parameter of UTS #46 conformance (all three conformance clauses
are phrased "Given a version of Unicode..."), so selecting one stays
conformant.
This is a UTS #46 profile, not IDNA2008 / RFC 5891 conformance. UTS #46
is compatibility processing and deliberately differs from IDNA2008 — it
accepts labels IDNA2008 would reject (e.g. a label whose first character is
the symbol U+2615 HOT BEVERAGE becomes "xn--53h.example"). The pipeline
draws on RFC 3492 (the Punycode
transform), NFC per UAX #15, the RFC 5892 ContextJ rules via CheckJoiners
(ZWJ/ZWNJ only — full RFC 5892 CONTEXTO is not checked), the RFC 5893
Bidi rule via CheckBidi, and STD 3 (RFC 952 + RFC 1123) host-name rules via
UseSTD3ASCIIRules. IDNA2003 / Nameprep (RFC 3490/3491/3454) is not used.
The default applies the full strict UTS #46 profile
(uts46-nontransitional-std3-v2). The check_hyphens, use_std3, and
verify_dns_length arguments are UTS #46 processing flags that can each be
relaxed independently; pass the same values to
normalization_profile_info() to obtain the identity of the resulting
profile. These are standard UTS #46 parameters, not a browser mode:
CheckBidi and CheckJoiners always apply and are never knobs, and full
WHATWG host policy (where beStrict = false flips exactly these three) lives
upstack in rurl, not here.
See also
normalization_profile_info() for the profile identity,
unicode_versions() for the table sets available,
puny_encode() for the lower-level RFC 3492 transform.
Examples
host_normalize(c("Example.COM", "münchen.de", "example.com."))
#> [1] "example.com" "xn--mnchen-3ya.de" "example.com."
host_normalize("a_b.com") # NA: STD3 rejects "_"
#> [1] NA
host_normalize("a_b.com", use_std3 = FALSE) # "a_b.com"
#> [1] "a_b.com"
host_normalize("example.com", unicode_version = unicode_versions()[[1L]])
#> [1] "example.com"