crow

Utility library


Project maintained by CaptainCrowbar Hosted on GitHub Pages — Theme by mattgraham

URI

Crow Library by Ross Smith

#include "crow/uri.hpp"
namespace Crow;

URI class

class Uri;

This class holds a URI, assumed to follow the format:

scheme: [//] [ [user [:password] @] host [:port] ] [/path] [?query] [#fragment]
static constexpr int Uri::lone_keys = 1;

Flag used in the make_query() function.

Uri::Uri() noexcept;

The default constructor produces an empty URI.

explicit Uri::Uri(std::string_view s);

This constructor parses a URI supplied as a string. This will throw std::invalid_argument if the URI is invalid.

Uri::Uri(std::string_view scheme,
    std::string_view user, std::string_view password,
    std::string_view host, uint16_t port = 0,
    std::string_view path = {}, std::string_view query = {},
    std::string_view fragment = {});

This constructor assembles a URI from its component parts (following the same rules as the individual set_*() functions described below). This will throw std::invalid_argument if the arguments do not form a valid URI.

Uri::Uri(const Uri& u);
Uri::Uri(Uri&& u) noexcept;
Uri::~Uri() noexcept;
Uri& Uri::operator=(const Uri& u);
Uri& Uri::operator=(Uri&& u) noexcept;

Other life cycle functions.

bool Uri::has_slashes() const noexcept;
bool Uri::has_user() const noexcept;
bool Uri::has_password() const noexcept;
bool Uri::has_host() const noexcept;
bool Uri::has_port() const noexcept;
bool Uri::has_path() const noexcept;
bool Uri::has_query() const noexcept;
bool Uri::has_fragment() const noexcept;

Query whether a given URI element is present. There is no has_scheme() because the scheme is always present if the URI is not empty.

std::string Uri::scheme() const;
std::string Uri::user() const;
std::string Uri::password() const;
std::string Uri::host() const;
uint16_t Uri::port() const noexcept;
std::string Uri::path() const;
std::string Uri::query() const;
std::string Uri::fragment() const;

Query the value of a given URI element. The returned strings do not include the associated punctuation (e.g. scheme() will not have a trailing colon or slashes). In some cases this means that the corresponding has_*() function must also be checked in order to distinguish between an element that is absent and one that is present but with an empty value (e.g. a URI ending in a question mark is considered to include an empty query string, which is not the same thing as one with no query part).

void Uri::set_scheme(std::string_view new_scheme, bool smart = true);
void Uri::set_user(std::string_view new_user);
void Uri::set_password(std::string_view new_password);
void Uri::set_host(std::string_view new_host);
void Uri::set_port(uint16_t new_port);
void Uri::set_path(std::string_view new_path);
void Uri::set_query(std::string_view new_query);
void Uri::set_fragment(std::string_view new_fragment);

Change the value of a given URI element. The string supplied will be escaped when necessary. Passing an empty string is equivalent to clearing the element only for elements that do not distinguish between an empty value and a missing element; this is not true of the query and fragment elements (e.g. set_user("") is equivalent to clear_user(), but set_query("") is not equivalent to clear_query()).

The scheme will always be converted to lower case. If the smart argument to set_scheme() is true (this is the default), and the scheme supplied does not end in "://", the colon will be added, and the slashes unless the scheme is "mailto".

All of these except set_scheme() will throw std::invalid_argument if the existing URI is empty, or under the following circumstances:

void Uri::clear_user() noexcept;
void Uri::clear_password() noexcept;
void Uri::clear_host() noexcept;
void Uri::clear_port() noexcept;
void Uri::clear_path() noexcept;
void Uri::clear_query() noexcept;
void Uri::clear_fragment() noexcept;

Remove a given URI element. There is no function to clear the scheme because the scheme is always required.

void Uri::append_path(std::string_view new_path);
Uri& Uri::operator/=(std::string_view s);
Uri operator/(const Uri& u, std::string_view s);

Append one or more file path elements to the URI’s path. Appending an absolute path (one that starts with a slash) will discard the original path and behave like set_path(). These will throw std::invalid_argument if the path is invalid (contains two consecutive slashes).

void Uri::clear() noexcept;

Resets the URI to an empty string.

Uri Uri::doc() const;
Uri Uri::base() const;
Uri Uri::parent() const;
Uri Uri::root() const;

These return related URLs:

bool Uri::empty() const noexcept;

True if the URI is empty.

size_t Uri::hash() const noexcept;
struct std::hash<Uri>;

Hash functions.

bool Uri::is_root() const noexcept;

True if the URI refers to the root of the host directory tree (the path part is empty or "/").

std::string Uri::path_dir() const;
std::string Uri::path_leaf() const;

Split the path element into a directory path and a leaf name. If path_dir() is not empty, it will always start and end with a slash (it may just be a lone slash). If the whole path ends with a slash, it is assumed to be a directory name, and path_leaf() will be empty.

std::string Uri::str() const;
std::ostream& operator<<(std::ostream& out, const Uri& u);

Return the URI as a string.

bool Uri::try_parse(std::string_view s);

Attempts to parse the given string as a URI. On success, this changes the current object to hold the new URI and returns true; on failure, it returns false and leaves the object unchanged.

static std::string Uri::encode(std::string_view s, std::string_view exempt = {});
static std::string Uri::decode(std::string_view s);

These apply percent encoding to a string. Safe bytes, left unencoded, are the ASCII alphanumerics plus [-._~]; all other bytes are encoded unless they appear in the exempt string.

template <std::ranges::range R>
    static std::string Uri::make_query(const R& range, char delimiter = '&',
        int flags = 0);
static std::vector<std::pair<std::string, std::string>>
    Uri::parse_query(std::string_view query, char delimiter = 0);

Construct or deconstruct a query string. The range argument to make_query() is expected to contain pairs whose first and second fields are string views or convertible to them; the delimiter character is inserted between key/value pairs; an equals sign is inserted between keys and values, except that it will be left out if the value is empty and the lone_keys flag is set.

The parse_query() function breaks down a query string into a vector of key/value pairs; if no delimiter is explicitly supplied, whichever of '&' or ';' appears first in the string will be used. Key and value strings are percent encoded by make_query() and decoded by parse_query().

std::strong_ordering operator<=>(const Uri& u, const Uri& v) noexcept;
bool operator==(const Uri& u, const Uri& v) noexcept;
bool operator!=(const Uri& u, const Uri& v) noexcept;
bool operator<(const Uri& u, const Uri& v) noexcept;
bool operator>(const Uri& u, const Uri& v) noexcept;
bool operator<=(const Uri& u, const Uri& v) noexcept;
bool operator>=(const Uri& u, const Uri& v) noexcept;

Comparison operators. These perform a simple string comparison on the URI string.

namespace Literals {
    inline Uri operator""_uri(const char* p, size_t n);
}

URI literal operator. This calls the string-based constructor, and will throw the same exceptions.