mod_servlet
C++Servlets
 All Classes Files Functions Variables Typedefs Macros Pages
uri.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2016 Alexei Novakov
3 https://github.com/novalexei
4 
5 Distributed under the Boost Software License, Version 1.0.
6 http://boost.org/LICENSE_1_0.txt
7 */
8 #ifndef MOD_SERVLET_URI_H
9 #define MOD_SERVLET_URI_H
10 
16 #include <string>
17 #include <iostream>
18 #include <iterator>
19 #include <vector>
20 #include <functional>
21 #include <experimental/string_view>
22 
23 #include <servlet/lib/exception.h>
24 
25 namespace servlet
26 {
27 
28 using std::experimental::string_view;
29 
33 struct uri_syntax_error : public std::runtime_error
34 {
35  using std::runtime_error::runtime_error;
36 };
40 struct uri_builder_error : public std::runtime_error
41 {
42  using std::runtime_error::runtime_error;
43 };
44 
258 class URI
259 {
260 public:
264  typedef std::string string_type;
265 
269  typedef std::experimental::string_view string_view;
270 
274  typedef string_view::const_iterator const_iterator;
275 
279  URI() : _uri{}, _uri_view{_uri}, _scheme{_uri}, _user_info{_uri}, _host{_uri},
280  _port{_uri}, _path{_uri}, _query{_uri}, _fragment{_uri} {}
281 
331  explicit URI(const string_type& uri_str) : _uri{uri_str} { _initialize(); }
332 
345  explicit URI(string_type&& uri_str) : _uri{std::move(uri_str)} { _initialize(); }
346 
359  explicit URI(string_view uri_str) : _uri{uri_str.to_string()} { _initialize(); }
360 
373  explicit URI(const char* uri_str) : _uri{uri_str} { _initialize(); }
374 
390  template <class InputIter>
391  URI(InputIter first, InputIter last) : _uri{string_type(first, last)} { _initialize(); }
392 
447  URI(string_view scheme, string_view userInfo, string_view host, uint16_t port,
449 
466  URI{scheme, "", host, port, path, query, ""} {}
467 
472  URI(const URI &other) : _uri{other._uri}, _uri_view{_uri}, _normalized{other._normalized} { _move_parts(other); }
473 
478  URI(URI &&other) noexcept : _uri{std::move(other._uri)}, _uri_view{_uri} { _move_parts(other); }
479 
483  ~URI() noexcept {}
484 
489  URI &operator=(const URI& other);
490 
495  URI &operator=(URI&& other);
496 
510  URI &operator=(const string_type& uri_str) { _uri = uri_str; _initialize(); return *this; }
511 
525  URI &operator=(string_type&& uri_str) { _uri = std::move(uri_str); _initialize(); return *this; }
526 
540  URI &operator=(string_view uri_str) { _uri = uri_str.to_string(), _initialize(); return *this; }
541 
555  URI &operator=(const char* uri_str) { _uri = uri_str; _initialize(); return *this; }
556 
561  void swap(URI &other) noexcept;
562 
567  const_iterator begin() const noexcept { return _uri_view.begin(); }
568 
573  const_iterator end() const noexcept { return _uri_view.end(); }
574 
580  string_view scheme() const noexcept { return _scheme; }
581 
594 
600  string_view user_info() const noexcept { return _user_info; }
601 
614 
620  string_view host() const noexcept { return _host; }
621 
633  void set_host(string_view host);
634 
640  string_view port_view() const noexcept { return _port; }
641 
647  uint16_t port() const noexcept { return _port_i; }
648 
661  void set_port(string_view port);
662 
674  void set_port(uint16_t port);
675 
681  string_view path() const noexcept { return _path; }
682 
697  void set_path(string_view path);
698 
704  string_view query() const noexcept { return _query; }
705 
718 
731  void add_to_query(string_view name, string_view value);
732 
744  void parse_query(std::function<void(std::string&&, std::string&&)> consumer)
745  { parse_query(_query, consumer); }
746 
768  static void parse_query(string_view query, std::function<void(std::string&&, std::string&&)> consumer);
769 
775  string_view fragment() const noexcept { return _fragment; }
776 
789 
795  bool has_authority() const noexcept;
796 
810  string_view authority() const noexcept;
811 
817  string_view uri_view() const noexcept { return _uri_view; }
818 
823  const std::string& string() const noexcept { return _uri; }
824 
832  std::string&& string_move() { return std::move(_uri); }
833 
846  std::string to_ASCII_string() const;
847 
855  bool empty() const noexcept { return _uri.empty(); }
856 
864  bool is_absolute() const noexcept { return !_scheme.empty(); }
865 
876  bool is_opaque() const noexcept; // { return (is_absolute() && !has_authority()); }
877 
901  void normalize_path();
902 
922  void normalize();
923 
933  URI create_normalized() const;
934 
945 
969  URI relativize(const URI &uri) const;
970 
1022  URI resolve(const URI &uri) const;
1023 
1041  int compare(const URI &other) const noexcept;
1042 
1052  static uint16_t get_default_port(string_view scheme);
1053 
1059  static std::string decode(string_view str);
1060 
1061 private:
1062  void _initialize();
1063  void _initialize(string_view scheme, string_view user_info, string_view host, string_view port,
1065 
1066  void _parse(string_view::const_iterator &it, string_view::const_iterator last);
1067  bool _set_host_and_port(string_view::const_iterator first,
1069  string_view::const_iterator last_colon);
1070 
1071  void _move_parts(const URI& other);
1072  void _resize_parts(std::size_t offset, int_fast16_t resize_bytes);
1073  void _decode_encoded_unreserved_chars();
1074 
1075  string_type _uri;
1076  string_view _uri_view;
1077  string_view _scheme;
1078  string_view _user_info;
1079  string_view _host;
1080  string_view _port;
1081  uint16_t _port_i = 0;
1082  string_view _path;
1083  string_view _query;
1084  string_view _fragment;
1085  bool _normalized = false;
1086 
1087  static const std::vector<std::pair<std::string, uint16_t>> DEFAULT_PORTS;
1088 };
1089 
1096 template<typename CharT, typename Traits>
1097 inline std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& out, const URI& uri)
1098 {
1099  return out << uri.uri_view();
1100 }
1101 
1113 inline bool operator==(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() == uri2.uri_view(); }
1114 
1123 inline bool operator==(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() == uri2; }
1124 
1132 inline bool operator==(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 == uri2.string(); }
1133 
1141 inline bool operator==(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() == uri2; }
1142 
1150 inline bool operator==(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 == uri2.uri_view(); }
1151 
1162 inline bool operator!=(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() != uri2.uri_view(); }
1163 
1171 inline bool operator!=(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() != uri2; }
1172 
1180 inline bool operator!=(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 != uri2.string(); }
1181 
1189 inline bool operator!=(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() != uri2; }
1190 
1198 inline bool operator!=(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 != uri2.uri_view(); }
1199 
1210 inline bool operator<(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() < uri2.uri_view(); }
1211 
1219 inline bool operator<(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() < uri2; }
1220 
1228 inline bool operator<(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 < uri2.string(); }
1229 
1237 inline bool operator<(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() < uri2; }
1238 
1246 inline bool operator<(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 < uri2.uri_view(); }
1247 
1258 inline bool operator>(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() > uri2.uri_view(); }
1259 
1267 inline bool operator>(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() > uri2; }
1268 
1276 inline bool operator>(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 > uri2.string(); }
1277 
1285 inline bool operator>(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() > uri2; }
1286 
1294 inline bool operator>(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 > uri2.uri_view(); }
1295 
1306 inline bool operator<=(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() <= uri2.uri_view(); }
1307 
1315 inline bool operator<=(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() <= uri2; }
1316 
1324 inline bool operator<=(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 <= uri2.string(); }
1325 
1333 inline bool operator<=(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() <= uri2; }
1334 
1342 inline bool operator<=(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 <= uri2.uri_view(); }
1343 
1354 inline bool operator>=(const URI& uri1, const URI& uri2) noexcept { return uri1.uri_view() >= uri2.uri_view(); }
1355 
1363 inline bool operator>=(const URI& uri1, const URI::string_type& uri2) noexcept { return uri1.string() >= uri2; }
1364 
1372 inline bool operator>=(const URI::string_type& uri1, const URI& uri2) noexcept { return uri1 >= uri2.string(); }
1373 
1381 inline bool operator>=(const URI& uri1, const URI::string_view& uri2) noexcept { return uri1.uri_view() >= uri2; }
1382 
1390 inline bool operator>=(const URI::string_view& uri1, const URI& uri2) noexcept { return uri1 >= uri2.uri_view(); }
1391 
1397 inline void swap(URI &lhs, URI &rhs) noexcept { lhs.swap(rhs); }
1398 
1399 } // end of servlet namespace
1400 
1401 #endif // MOD_SERVLET_URI_H
URI & operator=(const string_type &uri_str)
String assignment operator.
Definition: uri.h:510
string_view path() const noexcept
Returns the path view component of this URI.
Definition: uri.h:681
bool empty() const noexcept
Tells whether or not this URI is empty.
Definition: uri.h:855
URI(string_type &&uri_str)
Constructs a URI by parsing the given string.
Definition: uri.h:345
void set_port(string_view port)
Sets port component to this URI.
void normalize()
Normalizes this URI.
~URI() noexcept
Destructor.
Definition: uri.h:483
void swap(URI &other) noexcept
Swaps one uri object with another.
URI(InputIter first, InputIter last)
Constructs a URI by parsing the given string.
Definition: uri.h:391
int compare(const URI &other) const noexcept
Compares this URI against another.
void set_query(string_view query)
Sets query component to this URI.
string_view query() const noexcept
Returns the query view component of this URI.
Definition: uri.h:704
std::experimental::string_view string_view
The URI string_view.
Definition: uri.h:269
URI create_with_normalized_path() const
Create copy of this URI with normalized path.
URI & operator=(const URI &other)
Copy assignment operator.
static uint16_t get_default_port(string_view scheme)
Returns default port for given scheme or 0 if the default port could not be found.
URI create_normalized() const
Create normalized copy of this URI.
URI(URI &&other) noexcept
Move constructor.
Definition: uri.h:478
URI(const string_type &uri_str)
Constructs a URI by parsing the given string.
Definition: uri.h:331
URI relativize(const URI &uri) const
Relativizes the given URI against this URI.
void set_fragment(string_view fragment)
Sets fragment component to this URI.
string_view scheme() const noexcept
Returns the scheme component of this URI.
Definition: uri.h:580
Exception used in the mod_servlet.
URI()
Default constructor.
Definition: uri.h:279
string_view fragment() const noexcept
Returns the fragment view component of this URI.
Definition: uri.h:775
string_view user_info() const noexcept
Returns the userInfo component of this URI.
Definition: uri.h:600
URI(string_view scheme, string_view host, uint16_t port, string_view path, string_view query)
Constructs a hierarchical URI from the given components.
Definition: uri.h:465
const_iterator end() const noexcept
Returns an iterator at the last+1 element in the underlying URI view.
Definition: uri.h:573
URI(const URI &other)
Copy constructor.
Definition: uri.h:472
URI(const char *uri_str)
Constructs a URI by parsing the given string.
Definition: uri.h:373
std::string to_ASCII_string() const
Returns the content of this URI as a US-ASCII string.
uint16_t port() const noexcept
Returns the port component of this URI.
Definition: uri.h:647
URI resolve(const URI &uri) const
Resolves the given URI against this URI.
URI & operator=(string_type &&uri_str)
Move string assignment operator.
Definition: uri.h:525
URI & operator=(const char *uri_str)
C-string assignment operator.
Definition: uri.h:555
bool is_opaque() const noexcept
Tells whether or not this URI is opaque.
void set_scheme(string_view scheme)
Sets scheme component to this URI.
string_view port_view() const noexcept
Returns the port view component of this URI.
Definition: uri.h:640
string_view authority() const noexcept
Returns the raw authority component of this URI.
const_iterator begin() const noexcept
Returns an iterator at the first element in the underlying URI view.
Definition: uri.h:567
std::string string_type
The URI string_type.
Definition: uri.h:264
const std::string & string() const noexcept
Returns the URI as a std::string object.
Definition: uri.h:823
bool is_absolute() const noexcept
Tells whether or not this URI is absolute.
Definition: uri.h:864
URI(string_view uri_str)
Constructs a URI by parsing the given string.
Definition: uri.h:359
void add_to_query(string_view name, string_view value)
Adds name-value pair to the current query component of this URI.
string_view uri_view() const noexcept
Returns the string view representation of this URI.
Definition: uri.h:817
Represents a Uniform Resource Identifier (URI) reference.
Definition: uri.h:258
bool has_authority() const noexcept
Tests whether this URI has a valid authority.
Exception thrown while parsing URI if syntax error encountered.
Definition: uri.h:33
void normalize_path()
Normalizes this URI's path.
string_view host() const noexcept
Returns the host component of this URI.
Definition: uri.h:620
void set_user_info(string_view user_info)
Sets user_info component to this URI.
URI & operator=(string_view uri_str)
String view assignment operator.
Definition: uri.h:540
static std::string decode(string_view str)
Decode all the persent encoded characters in the string.
std::string && string_move()
Returns the URI as a std::string&& object.
Definition: uri.h:832
void set_host(string_view host)
Sets host component to this URI.
Exception thrown when it is impossible to build URI from parts.
Definition: uri.h:40
void set_path(string_view path)
Sets path component to this URI.
string_view::const_iterator const_iterator
The URI const_iterator type.
Definition: uri.h:274
void parse_query(std::function< void(std::string &&, std::string &&)> consumer)
Parses this URI's query into name-value pairs and feeds them to a given consumer. ...
Definition: uri.h:744