Skip to main content

bare_host

Function bare_host 

Source
pub fn bare_host(host: &str) -> &str
Expand description

The host a URI names, with an IPv6 literal’s brackets removed.

[2001:db8::1] becomes 2001:db8::1; every other host — a name, an IPv4 literal, an already-bare v6 address — comes back untouched.

§Why this exists at all, and why in this crate

http::Uri::host() returns an IPv6 literal with its brackets, because that is what the URI says: RFC 3986 §3.2.2 puts IP-literal = "[" ( IPv6address / IPvFuture ) "]" in the authority’s grammar, not in the host’s. Nothing outside a URI wants them, and everything outside a URI is where this workspace kept meeting the same failure:

  • str::parse::<IpAddr>() rejects [::1], so a resolver’s literal shortcut falls through and asks DNS about a string no zone contains.
  • rustls_pki_types::ServerName::try_from rejects [::1] as both a DNS name and an address, so a TLS or QUIC handshake fails with invalid dns name before a byte of the exchange happens.

The duty is the caller’s, not the backend’s — see hclient_tls::TlsRequest::server_name, whose doc says so at the seam where it matters. A backend that stripped defensively would be the second place normalising, and two places normalising is how they drift; worse, it would have to guess, since a backend cannot tell a host that came from a URI from one a caller built by hand.

This crate is the home because it is the only one every consumer already has. hclient-native and hclient-h3 both hold a Uri and both feed a TLS seam; hclient-dns and hclient-dns-doh both parse literals; hclient-tls, whose doc has to name the duty, depends on this crate and not on any of them. Putting it in hclient-dns would make a TLS server name reach through a resolver crate for a fact about URI syntax, and putting it in hclient-tls would do the mirror image to a resolver.

§What it does not do

It is not a validator and not a parser. [ alone is not a bracketed host and comes back as [; [] is a bracketed empty host and comes back as the empty string, which every consumer downstream then refuses — ServerName::try_from("") and "".parse::<IpAddr>() both fail — rather than being quietly patched up here. Percent-encoding, ports and userinfo are http::Uri’s business and have already been removed by the time Uri::host() has answered.

§What must NOT be stripped

The Host header and HTTP/2’s :authority are authority syntax, so they keep their brackets (RFC 9110 §7.2 — Host = uri-host [ ":" port ]). Only the step out of URI-land takes them off.