50#define URLPARSER_VERSION_MAJOR 2
51#define URLPARSER_VERSION_MINOR 1
52#define URLPARSER_VERSION_PATCH 0
54#define URLPARSER_VERSION_ENCODE(maj,min,pat) (((maj)*10000)+((min)*100)+(pat))
55#define URLPARSER_VERSION \
56 URLPARSER_VERSION_ENCODE(URLPARSER_VERSION_MAJOR,URLPARSER_VERSION_MINOR,URLPARSER_VERSION_PATCH)
59#define URLPARSER_VERSION_HEX \
60 ((URLPARSER_VERSION_MAJOR << 16) | (URLPARSER_VERSION_MINOR << 8) | URLPARSER_VERSION_PATCH)
63#define _URLPARSER_VERSION_XSTR(a,b,c) #a"."#b"."#c
64#define _URLPARSER_VERSION_STR(a,b,c) _URLPARSER_VERSION_XSTR(a,b,c)
67#define URLPARSER_VERSION_STRING \
68 _URLPARSER_VERSION_STR(URLPARSER_VERSION_MAJOR,URLPARSER_VERSION_MINOR,URLPARSER_VERSION_PATCH)
76#define URLPARSER_PUBLIC_SUFFIX_LIST_URL "https://publicsuffix.org/list/public_suffix_list.dat"
85#include <unordered_map>
198 bool operator==(const
hostname& other) const noexcept;
203 bool operator==(const std::
string& other) const noexcept;
206 const std::
string&
suffix() const noexcept;
208 const std::
string&
domain() const noexcept;
216 const std::
string&
str() const noexcept;
230 void ensure_parsed() const noexcept;
233 bool ignore_www_ = false;
234 mutable
bool parsed_ = false;
235 mutable std::
string domain_;
236 mutable std::
string subdomain_;
237 mutable std::
string suffix_;
238 mutable std::
string fulldomain_;
267 std::string_view source_url() const noexcept;
270 std::string_view
version() const noexcept {
return version_; }
280 void load_from_path(const std::
string& filepath);
287 void load_from_string(const std::
string& filestr);
296 bool is_suffix(std::string_view text) const noexcept;
305 std::
string suffix_of(const std::
string& hostname_text) const;
323 psl& operator=(const
psl&) = delete;
325 psl& operator=(
psl&&) noexcept;
328 explicit
psl(std::istream& stream);
330 size_t segment_count(const std::
string& text) const;
331 void add_rule(std::
string& rule,
int level_adjust,
size_t trim);
333 std::unique_ptr<detail::suffix_table> levels_;
334 std::
string version_;
362 static
bool is_valid(std::string_view text) noexcept;
365 static
ipv4 from_uint32(uint32_t address) noexcept;
374 std::
string str() const;
377 uint32_t to_uint32() const noexcept {
return value_; }
380 std::array<uint8_t, 4>
bytes() const noexcept;
402 value_ +=
static_cast<uint32_t
>(delta);
406 value_ -=
static_cast<uint32_t
>(delta);
414 return static_cast<int64_t
>(a.value_) -
static_cast<int64_t
>(b.value_);
425 explicit ipv4(uint32_t v) noexcept : value_(v) {}
456 static
bool is_valid(std::string_view text) noexcept;
459 static
ipv6 from_uint64_pair(uint64_t high, uint64_t low) noexcept;
468 std::
string str() const;
471 std::array<uint8_t, 16> bytes() const noexcept;
474 uint64_t high64() const noexcept {
return hi_; }
476 uint64_t
low64() const noexcept {
return lo_; }
488 add_bits(~uint64_t{0});
498 add_bits(
static_cast<uint64_t
>(delta));
505 add_bits(~
static_cast<uint64_t
>(delta) + 1);
513 return a.hi_ == b.hi_ && a.lo_ == b.lo_;
517 return a.hi_ != b.hi_ ? a.hi_ < b.hi_ : a.lo_ < b.lo_;
524 ipv6(uint64_t hi, uint64_t lo) noexcept : hi_(hi), lo_(lo) {}
528 void add_bits(uint64_t low64_bits)
noexcept;
560 result.value_ = std::move(h);
583 host(std::string_view host_text,
bool ignore_www = DEFAULT_IGNORE_WWW)
noexcept;
590 host(
const char* host_text,
bool ignore_www = DEFAULT_IGNORE_WWW)
noexcept;
599 host(std::string&& host_text,
bool ignore_www = DEFAULT_IGNORE_WWW)
noexcept;
605 static host from_url(std::string_view
url,
bool ignore_www = DEFAULT_IGNORE_WWW)
noexcept;
619 static host from_url(std::string&&
url,
bool ignore_www = DEFAULT_IGNORE_WWW)
noexcept;
621 bool is_hostname() const noexcept {
return std::holds_alternative<hostname>(value_); }
622 bool is_ipv4() const noexcept {
return std::holds_alternative<ipv4>(value_); }
623 bool is_ipv6() const noexcept {
return std::holds_alternative<ipv6>(value_); }
625 bool is_ip() const noexcept {
return !is_hostname(); }
637 const ipv4*
try_ipv4() const noexcept {
return std::get_if<ipv4>(&value_); }
639 const ipv6*
try_ipv6() const noexcept {
return std::get_if<ipv6>(&value_); }
683 static std::
string extract_host(std::string_view
url) noexcept;
692 static std::
string extract_host(const
char*
url) noexcept;
701 static std::
string extract_host(std::
string&&
url) noexcept;
710 url(std::string_view
url, const
bool ignore_www = DEFAULT_IGNORE_WWW);
721 bool operator==(const
url& other) const noexcept;
724 std::
string str() const noexcept;
726 std::string_view protocol() const noexcept {
return field(scheme_); }
728 std::string_view
query() const noexcept {
return field(query_); }
730 std::string_view
fragment() const noexcept {
return field(fragment_); }
732 std::string_view
userinfo() const noexcept {
return field(userinfo_); }
734 std::string_view
path() const noexcept {
return field(path_); }
758 std::
string normalized() const;
760 std::string_view host_text() const noexcept {
return field(host_); }
762 int port() const noexcept {
return port_; }
784 using
search_params = std::unordered_map<std::
string, std::vector<std::
string>>;
802 std::string_view field(Span s)
const noexcept {
803 return std::string_view(storage_).substr(s.pos, s.len);
808 std::
string storage_;
809 Span scheme_, userinfo_, host_, path_, params_, query_, fragment_;
811 bool has_params_ = false;
812 bool has_query_ = false;
813 bool ignore_www_ = false;
814 mutable std::optional<
urlparser::host> host_cache_;
815 mutable std::optional<std::
string> abspath_cache_;
865 operator const url&()
const noexcept {
return url_; }
983std::string to_ascii(std::string_view utf8_domain);
1009namespace percent_codec {
1013using character_set = std::array<uint64_t, 4>;
1015constexpr bool contains(
const character_set& set,
unsigned char c)
noexcept {
1016 return (set[c >> 6] >> (c & 63)) & 1ULL;
1021character_set unreserved_set();
1025character_set path_safe_set();
1034std::string decode(std::string_view input);
1041std::string encode(std::string_view input,
1042 const character_set& safe = unreserved_set());
1080std::string resolve(std::string_view base, std::string_view ref);
hostname, ipv4, or ipv6: whatever a URL's host actually is (RFC 3986's host grammar),...
Definition urlparser.h:550
bool is_ipv6() const noexcept
Definition urlparser.h:623
const variant_type & variant() const noexcept
Direct access to the underlying variant - for std::visit, std::get, etc.
Definition urlparser.h:645
static host wrap(ipv4 v) noexcept
Definition urlparser.h:563
bool is_ip() const noexcept
True for either IP family - the opposite of is_hostname().
Definition urlparser.h:625
static host from_url(const char *url, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Classify and parse the host of a URL string literal. Disambiguation overload, same reason as host(con...
const ipv6 & get_ipv6() const
Definition urlparser.h:632
const hostname & get_hostname() const
Definition urlparser.h:628
const hostname * try_hostname() const noexcept
nullptr if this isn't a hostname.
Definition urlparser.h:635
static host from_url(std::string_view url, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Extract the host from a full URL and classify/parse it, in one step.
const ipv4 & get_ipv4() const
Definition urlparser.h:630
static host from_url(std::string &&url, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Extract the host from a full URL and classify/parse it, taking ownership of the URL string - reuses i...
static host wrap(ipv6 v) noexcept
Definition urlparser.h:568
std::variant< hostname, ipv4, ipv6 > variant_type
Definition urlparser.h:552
host(const char *host_text, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Classify a host string literal. Disambiguation overload: without this, host("literal") would be ambig...
friend bool operator!=(const host &a, const host &b) noexcept
Definition urlparser.h:648
host(std::string &&host_text, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Classify an already-isolated host string, taking ownership of it. When the text turns out to be a dom...
host() noexcept=default
Default-constructs an empty hostname.
friend bool operator==(const host &a, const host &b) noexcept
Definition urlparser.h:647
std::string str() const
The text form, whichever of hostname/ipv4/ipv6 this is.
bool is_hostname() const noexcept
Definition urlparser.h:621
bool is_ipv4() const noexcept
Definition urlparser.h:622
host(std::string_view host_text, bool ignore_www=DEFAULT_IGNORE_WWW) noexcept
Classify and parse an already-isolated host string (no scheme, no path - e.g. what url::host_text() g...
const ipv4 * try_ipv4() const noexcept
nullptr if this isn't an ipv4.
Definition urlparser.h:637
const ipv6 * try_ipv6() const noexcept
nullptr if this isn't an ipv6.
Definition urlparser.h:639
A domain name used as a URL's host, e.g. "www.example.com".
Definition urlparser.h:128
std::string normalized_ascii() const
The IDNA/Punycode-normalized, all-ASCII form of str(). Unlike str(), which keeps whatever the input l...
const std::string & full_domain() const noexcept
The full domain of the host (e.g., "example.com").
static std::string_view remove_www(const std::string_view &host) noexcept
Remove "www." from the beginning of a hostname string.
std::string domain_name() const noexcept
The domain name, i.e. "<domain>.<suffix>".
const std::string & suffix() const noexcept
The suffix of the host (e.g., "com" in "example.com").
const std::string & domain() const noexcept
The domain of the host (e.g., "example" in "www.example.com").
static hostname from_url(const char *url, const bool ignore_www=DEFAULT_IGNORE_WWW)
Create a hostname from a URL string literal. Disambiguation overload: without this,...
static hostname from_url(std::string_view url, const bool ignore_www=DEFAULT_IGNORE_WWW)
Create a hostname from a URL string, without taking ownership. Prefer this overload when the caller o...
static hostname from_url(std::string &&url, const bool ignore_www=DEFAULT_IGNORE_WWW)
Create a hostname from a URL string, taking ownership of it. Prefer this overload when you already ha...
hostname(std::string host, const bool ignore_www=DEFAULT_IGNORE_WWW)
Construct a hostname object from a hostname string.
const std::string & subdomain() const noexcept
The subdomain of the host (e.g., "www" in "www.example.com").
static hostname from_url(const std::string &url, const bool ignore_www=DEFAULT_IGNORE_WWW)
Create a hostname from a URL string.
const std::string & str() const noexcept
The complete host string (same as full_domain()).
hostname() noexcept=default
Default constructor for the hostname class. Creates an empty hostname object.
An IPv4 address used as a URL's host, e.g. "192.0.2.1".
Definition urlparser.h:350
ipv4 operator++(int) noexcept
Definition urlparser.h:386
friend bool operator>=(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:422
friend int64_t operator-(const ipv4 &a, const ipv4 &b) noexcept
Distance between two addresses (always fits in int64_t: the range is only 2^32).
Definition urlparser.h:413
friend ipv4 operator-(ipv4 lhs, int64_t delta) noexcept
Definition urlparser.h:411
friend ipv4 operator+(ipv4 lhs, int64_t delta) noexcept
Definition urlparser.h:410
friend bool operator!=(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:418
friend bool operator==(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:417
ipv4() noexcept=default
Default-constructs 0.0.0.0.
std::array< uint8_t, 4 > bytes() const noexcept
The address as 4 bytes, most significant first.
friend bool operator>(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:421
ipv4 & operator--() noexcept
Definition urlparser.h:391
friend bool operator<(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:419
friend bool operator<=(const ipv4 &a, const ipv4 &b) noexcept
Definition urlparser.h:420
ipv4 & operator-=(int64_t delta) noexcept
Definition urlparser.h:405
ipv4 & operator+=(int64_t delta) noexcept
Steps the address by delta, wrapping around mod 2^32.
Definition urlparser.h:401
ipv4 operator--(int) noexcept
Definition urlparser.h:395
An IPv6 address used as a URL's host, e.g. "2001:db8::1".
Definition urlparser.h:442
uint64_t low64() const noexcept
The low 64 bits (last 8 bytes).
Definition urlparser.h:476
friend bool operator>=(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:521
ipv6 operator++(int) noexcept
Definition urlparser.h:482
friend ipv6 operator-(ipv6 lhs, int64_t delta) noexcept
Definition urlparser.h:510
friend bool operator<(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:516
ipv6 & operator++() noexcept
Definition urlparser.h:478
friend bool operator==(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:512
friend bool operator>(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:520
ipv6 & operator-=(int64_t delta) noexcept
Definition urlparser.h:501
friend ipv6 operator+(ipv6 lhs, int64_t delta) noexcept
Definition urlparser.h:509
ipv6 & operator--() noexcept
Definition urlparser.h:487
friend bool operator<=(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:519
ipv6() noexcept=default
Default-constructs "::" (all zero).
ipv6 operator--(int) noexcept
Definition urlparser.h:491
friend bool operator!=(const ipv6 &a, const ipv6 &b) noexcept
Definition urlparser.h:515
ipv6 & operator+=(int64_t delta) noexcept
Steps the address by delta, wrapping around mod 2^128.
Definition urlparser.h:497
Definition urlparser.h:261
bool is_loaded() const noexcept
Whether a PSL is currently loaded (true even for the bundled default).
static psl & instance() noexcept
The one, lazily-built, shared PSL instance.
Parses an SSH "scp-like" address - user@host:path (what scp, rsync, sshfs, and git all accept,...
Definition urlparser.h:834
scp_url(std::string_view input)
Parse input - scp-like or already a normal URI - as a URL. scp-like input is normalize()d to "ssh://"...
const url & as_url() const noexcept
The parsed result, as a normal url.
Definition urlparser.h:863
static std::string normalize(std::string_view input)
Rewrite an scp-like address to an equivalent "ssh://" URI. Input that doesn't match is_scp_like() is ...
static bool is_scp_like(std::string_view input) noexcept
True iff input matches the scp-like address shape: [user@]host:path. Per git's own rule for this synt...
bool was_scp_like() const noexcept
Whether input (as given to the constructor) was scp-like, as opposed to already a normal URI.
Definition urlparser.h:868
Represents a URL.
Definition urlparser.h:673
std::string_view userinfo() const noexcept
The userinfo of the URL (e.g., "username:password").
Definition urlparser.h:732
std::string_view path() const noexcept
The raw path of the URL, exactly as it appears in the source (no dot-segment resolution - see abspath...
Definition urlparser.h:734
std::string_view query() const noexcept
The query string of the URL (e.g., "a=1&b=2").
Definition urlparser.h:728
std::string_view fragment() const noexcept
The fragment of the URL (the part after '#').
Definition urlparser.h:730
std::string normalized() const
The URL's canonical, normalized form (roughly WHATWG URL "serialize a URL" / ada's normalize_url()): ...
query_params params() const noexcept
The '&'-separated query parameters, split into a vector.
const std::string & abspath() const noexcept
The path, with '.'/'..' segments resolved.
static bool is_psl_loaded() noexcept
Check if the Public Suffix List (PSL) is loaded.
int port() const noexcept
The port number of the URL, or 0 if not specified.
Definition urlparser.h:762
std::unordered_map< std::string, std::vector< std::string > > search_params
A decoded key → values map of the query string (like JS's URLSearchParams, or ada_url....
Definition urlparser.h:784
Exposes the library version (from the URLPARSER_VERSION_* macros) at runtime, without needing to #inc...
Definition urlparser.h:98
static unsigned int major() noexcept
Definition urlparser.h:100
static unsigned int hex() noexcept
Definition urlparser.h:103
static std::string_view string() noexcept
Definition urlparser.h:104
static unsigned int minor() noexcept
Definition urlparser.h:101
static unsigned int patch() noexcept
Definition urlparser.h:102
Definition urlparser.h:90
std::string build_search_params(const std::vector< std::pair< std::string, std::string > > &pairs)
Build an application/x-www-form-urlencoded query string from ordered key/value pairs - the inverse of...
constexpr bool DEFAULT_IGNORE_WWW
Definition urlparser.h:91
std::vector< std::string > query_params
A vector of strings representing query parameters in a URL.
Definition urlparser.h:114
std::string normalize(std::string_view input)
Convenience wrapper: url(input).normalized(). Prefer calling .normalized() directly on a url you alre...
Definition urlparser.h:917
#define URLPARSER_VERSION_STRING
Definition urlparser.h:67
#define URLPARSER_VERSION_MAJOR
Definition urlparser.h:50
std::ostream & operator<<(std::ostream &os, const urlparser::query_params &dt)
Output stream operator for query_params.
#define URLPARSER_VERSION_HEX
Definition urlparser.h:59
#define URLPARSER_VERSION_MINOR
Definition urlparser.h:51
#define URLPARSER_VERSION_PATCH
Definition urlparser.h:52