13#include "enum_flags.h"
14#include "string_ops.h"
28 using uri = std::string;
29 using uri_view = std::string_view;
47 authority_not_allowed_in_scheme,
48 authority_invalid_for_scheme,
49 authority_required_in_scheme,
52 user_info_not_allowed_in_scheme,
53 user_info_invalid_for_scheme,
54 user_info_required_in_scheme,
57 host_not_allowed_in_scheme,
58 host_invalid_for_scheme,
59 host_required_in_scheme,
62 port_not_allowed_in_scheme,
63 port_invalid_for_scheme,
64 port_required_in_scheme,
67 path_element_malformed,
70 query_not_allowed_in_scheme,
71 query_invalid_for_scheme,
72 query_required_in_scheme,
75 fragment_not_allowed_in_scheme,
76 fragment_invalid_for_scheme,
77 fragment_required_in_scheme,
79 invalid_percent_encoding,
81 no_scheme_specific_elements,
82 scheme_specific_element_malformed,
86 using uri_expected = expected<T, uri_error_code>;
87 using uri_error = expected<void, uri_error_code>;
96 lowercase_when_appropriate,
99 validate_known_scheme,
108 std::string scheme{};
109 std::string authority{};
110 std::string user_info{};
114 std::vector<std::string> path_elements;
118 std::vector<std::pair<std::string, std::string>> query_elements;
119 std::string fragment{};
125 bool canonical_form =
false;
127 bool empty()
const noexcept {
return scheme.empty(); }
150 uri_expected<std::string_view> extract_scheme(uri_view
uri)
noexcept;
156 template <
typename FUNC>
163 template <
typename FUNC>
172 enum class uri_compose_flags
176 lowercase_when_appropriate,
193 virtual uri_error validate(uri_view
uri)
const noexcept
196 if (!decomposed)
return decomposed.transform([](
auto) {});
198 return validate(decomposed.value());
201 virtual uri_error validate(
decomposed_uri const& decomposed)
const noexcept
203 if (decomposed.scheme != scheme())
return unexpected(uri_error_code::scheme_invalid);
205 return validate_authority(decomposed.authority)
206 .and_then([&] {
return validate_path(decomposed.path); })
207 .and_then([&] {
return validate_query(decomposed.query); })
208 .and_then([&] {
return validate_fragment(decomposed.fragment); });
211 virtual std::string_view scheme()
const noexcept = 0;
213 virtual uri_error validate_authority(std::string_view fragment)
const noexcept
215 return validate_user_info(fragment)
216 .and_then([&] {
return validate_host(fragment); })
217 .and_then([&] {
return validate_port(fragment); });
219 virtual uri_error validate_user_info(std::string_view element)
const noexcept {
return {}; }
220 virtual uri_error validate_host(std::string_view element)
const noexcept {
return {}; }
221 virtual uri_error validate_port(std::string_view element)
const noexcept {
return {}; }
222 virtual uri_error validate_path(std::string_view element)
const noexcept {
return {}; }
223 virtual uri_error validate_query(std::string_view element)
const noexcept {
return {}; }
224 virtual uri_error validate_fragment(std::string_view element)
const noexcept {
return {}; }
226 virtual std::string_view default_authority()
const noexcept {
return {}; }
227 virtual std::string_view default_user_info()
const noexcept {
return {}; }
228 virtual std::string_view default_host()
const noexcept {
return {}; }
229 virtual std::string_view default_port()
const noexcept {
return {}; }
230 virtual std::string_view default_path()
const noexcept {
return {}; }
231 virtual std::string_view default_query()
const noexcept {
return {}; }
232 virtual std::string_view default_fragment()
const noexcept {
return {}; }
237 virtual std::vector<std::pair<std::string, std::string>> split_query_elements(std::string_view query)
const noexcept;
239 virtual std::string normalize_authority(std::string_view element)
const noexcept {
return std::string{ element }; }
240 virtual std::string normalize_user_info(std::string_view element)
const noexcept {
return std::string{ element }; }
241 virtual std::string normalize_host(std::string_view element)
const noexcept {
return std::string{ element }; }
242 virtual std::string normalize_port(std::string_view element)
const noexcept {
return std::string{ element }; }
243 virtual std::string normalize_path(std::string_view element)
const noexcept {
return std::string{ element }; }
244 virtual std::string normalize_query(std::string_view element)
const noexcept {
return std::string{ element }; }
245 virtual std::string normalize_fragment(std::string_view element)
const noexcept {
return std::string{ element }; }
259 return uri_error_code::no_scheme_specific_elements;
278 virtual std::string_view
scheme() const noexcept
override {
return "file"; }
282 return uri.host.empty() ||
uri.host ==
"localhost";
287 if (
uri.path_elements.empty())
293 std::filesystem::path result;
294 for (
auto& pe :
uri.path_elements)
306 explicit uri_builder(
uri&
uri);
308 uri_builder(
const uri_builder&) =
delete;
309 uri_builder& operator= (
const uri_builder&) =
delete;
312 template <
class Source>
313 uri_builder& scheme(
const Source& scheme);
315 template <
class Source>
316 uri_builder& authority(
const Source& authority);
318 template <
class Source>
319 uri_builder& authority(
const Source& user_info,
const Source& host,
const Source& port);
321 template <
class Source>
322 uri_builder& user_info(
const Source& user_info);
324 template <
class Source>
325 uri_builder& host(
const Source& host);
327 template <
class Source>
328 uri_builder& port(
const Source& port);
330 template <
class Source>
331 uri_builder& path(
const Source& path);
333 template <
class Source>
334 uri_builder& query(
const Source& query);
336 template <
class Source>
337 uri_builder& fragment(
const Source& fragment);
351 struct is_error_code_enum<
ghassanpl::uri_error_code> : true_type {};
uri_expected< uri > normalize_uri(uri_view uri)
[Unimplemented] Converts a URI to a normalized form
uri_expected< std::string_view > extract_query(uri_view uri) noexcept
[Unimplemented]
uri_expected< uri > compose_uri(decomposed_uri const &decomposed, enum_flags< uri_compose_flags > flags=enum_flags< uri_compose_flags >::all())
[Unimplemented]
uri_expected< void > extract_query_elements(uri_view uri, FUNC &&func) noexcept
[Unimplemented]
uri_error_code
Error codes relating to URI decomposing, composing, and other operations.
uri_expected< uri > make_uri_safe_for_display(uri_view uri)
[Unimplemented] Removes data that should not be displayed to an untrusted user (user-info after the f...
uri_expected< std::string_view > extract_path(uri_view uri) noexcept
[Unimplemented]
uri_expected< std::string_view > extract_authority(uri_view uri) noexcept
[Unimplemented]
uri_decompose_flags
Flags that modify how a URI string is decomposed into ghassanpl::decomposed_uri.
uri_expected< void > extract_path_elements(uri_view uri, FUNC &&func) noexcept
[Unimplemented]
std::string uri
URIs are stored in a UTF-8 encoding where both non-ASCII code unit bytes as well as URI-reserved char...
uri_expected< std::string_view > extract_fragment(uri_view uri) noexcept
[Unimplemented]
known_uri_scheme const * query_uri_scheme(std::string_view scheme)
Looks up the scheme in the internal URI scheme database.
uri_expected< decomposed_uri > decompose_uri(uri_view uri, enum_flags< uri_decompose_flags > flags=enum_flags< uri_decompose_flags >::all())
This function will decompose URI into its composite elements, which includes percent-decoding all the...
@ use_well_known_port_numbers
if a port is not specified in the uri, the result will guess the port based on the scheme
Primary namespace for everything in this library.
Contains known URI scheme types and objects.
Holds the constituents of a URI.
uri_expected< struct url_blob > url_blob() const
[Unimplemented]
uri_expected< std::string > url_origin() const
[Unimplemented]
uri_expected< std::string > url_site() const
[Unimplemented]
uri_expected< struct url_host > url_host() const
[Unimplemented]
bool same_site(decomposed_uri const &other) const noexcept
[Unimplemented]
bool same_origin(decomposed_uri const &other) const noexcept
[Unimplemented]
std::vector< std::string > normalized_path() const noexcept
Returns the path normalized by applying any "." or ".." elements.
uri_expected< std::pair< std::string, std::string > > url_user_info() const
[Unimplemented]
A (constexpr) value struct that represents a set of bits mapped to an enum (implemented as a bitset).
static constexpr self_type all() noexcept
Returns a value with all bits set (including the ones not in the enum, if any).
The "file:" known scheme.
virtual std::string_view scheme() const noexcept override
https://datatracker.ietf.org/doc/html/rfc8089
An base class for classes that can validate (and potentially parse more info from) a known URI scheme...
virtual uri_error_code iterate_scheme_elements(uri_view uri, std::function< bool(std::string_view element_name, std::string_view element_value)> callback) const noexcept
Calls the callback function for each scheme-specific "element" of the uri.