Skip to contents

A policy predicate layered on top of standards-correct parsing. rurl's url_standard profiles deliberately match the URL standards rather than impose practical web/SEO hygiene, so hosts such as a+b.example (a valid RFC 3986 reg-name), _dmarc.example.com (a valid DNS owner name), or -example.com all parse successfully. is_valid_host() answers the separate, product-level question of whether such a host is usable as a practical web hostname, DNS owner name, registrable site host, or SEO-safe host.

Usage

is_valid_host(
  url,
  rule = c("web", "dns", "registrable", "seo", "url"),
  url_standard = "whatwg",
  scheme_policy = c("infer", "require"),
  scheme_acceptance = c("web", "general")
)

Arguments

url

A character vector of URLs.

rule

A single rule to test. One of:

"web"

(default) usable as an HTTP-authority host: an IP literal, or a strict letter-digit-hyphen (LDH) name host (labels 1–63 octets, no leading/trailing hyphen, no underscore, name \(\le\) 253).

"dns"

a legal DNS owner-name shape — the "web" rule but the underscore is permitted anywhere (as _dmarc, _dkim, SRV owner names require).

"registrable"

the host has a Public Suffix List registrable domain (equivalently get_host_type is "domain"); IP literals and single-label / unknown-suffix hosts are FALSE.

"seo"

SEO-safe: "web" and "registrable" and carrying no host-shape footgun diagnostic (e.g. an IPv4 written in a numeric or non-decimal shorthand).

"url"

the loosest rule: the selected standard admitted a host at all.

url_standard

Standard profile governing host interpretation: "whatwg" (default; the living web standard) or "rfc3986". The verdict can depend on the standard — 2130706433 is an "ipv4" host (web = TRUE) under "whatwg" but a reg-name under "rfc3986".

scheme_policy

Controls whether scheme-less, host-shaped input is accepted (an input-acceptance axis, distinct from protocol_handling, which only controls how the scheme is presented, and from url_standard, which controls interpretation). Defaults to "infer".

  • "infer": (Default) Fabricate http:// for scheme-less host-shaped input (e.g. example.com parses as http://example.com), a browser-omnibox-style affordance. This is the historical behavior.

  • "require": Reject scheme-less input — a scheme-less host-shaped value becomes parse_status = "error" rather than gaining a fabricated scheme. Use this for a strict, pure-parser posture. Note this governs only bare host input; scheme-relative //host input is governed separately by scheme_relative_handling.

scheme_acceptance

Which scheme tokens may enter parsing (a scheme-acceptance axis, distinct from scheme_policy, which governs scheme-less input, and from url_standard, which governs interpretation). Defaults to "web".

  • "web": (Default) Only the curated web-scheme allowlist (http/https/ftp/ftps/file) is admitted; a scheme-bearing input outside it is parse_status = "error". This is the historical, byte-for-byte compatible behavior.

  • "general": Admit any syntactically valid scheme token and parse opaque (mailto:x), non-special (foo://host), and RFC-generic URLs. Requires an explicit url_standard ("rfc3986" or "whatwg"), which decides the interpretation; general with url_standard = NULL is an error. Non-special / opaque hosts receive no www-stripping, no domain/TLD derivation, and are never run through the IDNA/punycode helpers. A non-special scheme with no // is an opaque path: it has no authority, so host, user, port and the domain/tld columns are all NA and the entire remainder is the path (query/fragment are still split off). This includes mailto: — the recipient's @ never re-triggers authority parsing. To decompose a mailto: recipient, use the accessors (get_host() / get_domain() / get_user(), ADR 0012 D7) or get_mailto_recipients(); those deliberately return a recipient's parts where this table presents NA, because a recipient domain is extraction metadata, not the URL's authority.

Value

A logical vector the same length as url. NA for a URL with no host to judge (a host-less scheme, or an input that did not parse).

A policy layer, not parser conformance

This never changes how a URL parses: it does not turn a hostname-policy failure into a parse error, does not affect get_parse_status, and adds no columns to safe_parse_url. It is also not a conformance oracle (see get_url_diagnostics and ADR 0012): a TRUE verdict means only that rurl found no practical footgun it checks for, never that the host is provably valid per every specification.

See also

check_hosts for a tabular report over several rules at once, get_host_type, get_url_diagnostics.

Examples

is_valid_host(c("http://example.com", "http://_dmarc.example.com"))
#> [1]  TRUE FALSE
# web: FALSE for the underscore host; dns: TRUE for it
is_valid_host("http://_dmarc.example.com", rule = "dns")
#> [1] TRUE
is_valid_host(
  c("http://a+b.example", "http://-example.com", "http://a..com"),
  rule = "web"
)
#> [1] FALSE FALSE FALSE
is_valid_host(
  c("http://example.com", "http://localhost", "http://192.168.0.1"),
  rule = "registrable"
)
#> [1]  TRUE FALSE FALSE