qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches
uri.h
Go to the documentation of this file.
1
28
29#include <charconv>
30#include <qb/io/config.h>
33#include <regex>
34#include <string>
35#include <string_view>
36#include <vector>
37
38#ifndef QB_IO_URI_H_
39#define QB_IO_URI_H_
40
41namespace qb::io {
42
48inline bool
49is_alnum(int c) {
50 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
51}
52
58inline bool
60 return is_alnum((char) c) || c == '-' || c == '.' || c == '_' || c == '~';
61}
62
68inline bool
70 return c == ':' || c == '/' || c == '?' || c == '#' || c == '[' || c == ']' ||
71 c == '@';
72}
73
79inline bool
81 switch (c) {
82 case '!':
83 case '$':
84 case '&':
85 case '\'':
86 case '(':
87 case ')':
88 case '*':
89 case '+':
90 case ',':
91 case ';':
92 case '=':
93 return true;
94 default:
95 return false;
96 }
97}
98
104inline bool
106 return is_gen_delim(c) || is_sub_delim(c);
107}
108
114inline bool
116 return is_alnum((char) c) || c == '+' || c == '-' || c == '.';
117}
118
124inline bool
126 return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == ':';
127}
128
134inline bool
136 return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == '@' || c == ':' ||
137 c == '[' || c == ']';
138}
139
145inline bool
147 return is_unreserved(c) || is_sub_delim(c) || c == '%' || c == '/' || c == ':' ||
148 c == '@';
149}
150
156inline bool
158 return is_path_character(c) || c == '?';
159}
160
166inline bool
168 // this is intentional, they have the same set of legal characters
169 return is_query_character(c);
170}
171
181class uri {
182 int _af = AF_INET;
183 std::string _source;
184 std::string_view _scheme;
185 std::string_view _user_info;
186 std::string_view _host;
187 std::string_view _port;
188 std::string_view _path;
189 std::string_view _raw_queries;
190 std::string_view _fragment;
192 _queries;
193
194 constexpr static const char no_path[] = "/";
195
196 bool parse_queries(std::size_t pos) noexcept;
197 // bool parse_v6(std::size_t pos) noexcept; /**< Parse an IPv6
198 // address */ bool parse_v4() noexcept; /**< Parse
199 // an IPv4 address */
200
205 bool parse() noexcept;
206
212 bool from(std::string const &rhs) noexcept;
213
219 bool from(std::string &&rhs) noexcept;
220
226 void parse_query_parameters(const char* begin, const char* end);
227
228public:
232 uri() = default;
233
238 uri(uri &&rhs) noexcept;
239
244 uri(uri const &rhs);
245
251 uri(std::string const &str, int af = AF_INET);
252
258 uri(std::string &&str, int af = AF_INET) noexcept;
259
264 static const char tbl[256];
265
276 template <typename _IT>
277 static std::string
278 decode(_IT begin, _IT end) noexcept {
279 std::string out;
280 char c, v1, v2{};
281
282 while (begin != end) {
283 c = *(begin++);
284 if (c == '%') {
285 if ((v1 = tbl[(unsigned char) *(begin++)]) < 0 ||
286 (v2 = tbl[(unsigned char) *(begin++)]) < 0) {
287 break;
288 }
289 c = (v1 << 4) | v2;
290 }
291 out += (c);
292 }
293
294 return out;
295 }
296
300 constexpr static const char hex[] = "0123456789ABCDEF";
301
312 template <typename _IT>
313 static std::string
314 encode(_IT begin, _IT end) noexcept {
315 std::string encoded;
316
317 encoded.reserve(static_cast<ptrdiff_t>(end - begin) * 3);
318 for (auto iter = begin; iter != end; ++iter) {
319 // for utf8 encoded string, char ASCII can be greater than 127.
320 int ch = static_cast<unsigned char>(*iter);
321 // ch should be same under both utf8 and utf16.
322 if (!is_unreserved(ch) && !is_reserved(ch)) {
323 encoded.push_back('%');
324 encoded.push_back(hex[(ch >> 4) & 0xF]);
325 encoded.push_back(hex[ch & 0xF]);
326 } else {
327 // ASCII don't need to be encoded, which should be same on both utf8 and
328 // utf16.
329 encoded.push_back((char) ch);
330 }
331 }
332
333 return encoded;
334 }
335
341 static std::string decode(std::string_view input) noexcept;
342
348 static std::string encode(std::string_view input) noexcept;
349
356 static std::string decode(const char *input, std::size_t size) noexcept;
357
364 static std::string encode(const char *input, std::size_t size) noexcept;
365
372 static uri parse(std::string const &str, int af = AF_INET) noexcept;
373
379 uri &operator=(uri const &rhs);
380
386 uri &operator=(uri &&rhs) noexcept;
387
393 uri &operator=(std::string const &str);
394
400 uri &operator=(std::string &&str) noexcept;
401
406 [[nodiscard]] inline auto
407 af() const {
408 return _af;
409 }
410
415 [[nodiscard]] inline const auto &
416 source() const {
417 return _source;
418 }
419
424 [[nodiscard]] inline auto
425 scheme() const {
426 return _scheme;
427 }
428
433 [[nodiscard]] inline auto
434 user_info() const {
435 return _user_info;
436 }
437
442 [[nodiscard]] inline auto
443 host() const {
444 return _host;
445 }
446
451 [[nodiscard]] inline auto
452 port() const {
453 return _port;
454 }
455
460 [[nodiscard]] uint16_t
461 u_port() const {
462 int p = 0;
463
464 std::from_chars(port().data(), port().data() + port().size(), p);
465 return static_cast<uint16_t>(p);
466 }
467
472 [[nodiscard]] inline auto
473 path() const {
474 return _path;
475 }
476
481 [[nodiscard]] inline const auto &
483 return _raw_queries;
484 }
485
490 [[nodiscard]] inline const auto &
491 queries() const {
492 return _queries;
493 }
494
499 [[nodiscard]] inline auto &
501 return _queries;
502 }
503
513 template <typename T>
514 [[nodiscard]] std::string const &
515 query(T &&name, std::size_t const index = 0,
516 std::string const &not_found = "") const {
517 const auto &it = this->_queries.find(std::forward<T>(name));
518 if (it != this->_queries.cend() && index < it->second.size())
519 return it->second[index];
520
521 return not_found;
522 }
523
528 [[nodiscard]] inline auto
529 fragment() const {
530 return _fragment;
531 }
532
538 static bool is_valid_scheme(std::string_view scheme) noexcept;
539
545 static bool is_valid_host(std::string_view host) noexcept;
546
552 static bool normalize_path(std::string &path) noexcept;
553};
554} // namespace qb::io
555
556#endif // QB_IO_URI_H_
Platform, compiler, and C++ feature detection macros for the QB Framework.
auto find(T &&key)
Find a key-value pair by key, with the key converted to lowercase.
Definition unordered_map.h:335
uri & operator=(uri const &rhs)
Copy assignment operator.
auto scheme() const
Returns the scheme of this URI.
Definition uri.h:425
static bool is_valid_scheme(std::string_view scheme) noexcept
Validates if a string is a valid URI scheme.
uri(uri const &rhs)
Copy constructor.
auto af() const
Returns the address family of this URI.
Definition uri.h:407
uri(uri &&rhs) noexcept
Move constructor.
static std::string decode(const char *input, std::size_t size) noexcept
Decodes a URI-encoded memory block.
auto & queries()
Returns the parsed query parameters of this URI (non-const version)
Definition uri.h:500
static std::string encode(const char *input, std::size_t size) noexcept
Encodes a memory block in URI format.
static constexpr const char hex[]
Hexadecimal characters for encoding.
Definition uri.h:300
auto user_info() const
Returns the user information of this URI.
Definition uri.h:434
uri(std::string &&str, int af=AF_INET) noexcept
Constructor from a string (move version)
uri & operator=(uri &&rhs) noexcept
Move assignment operator.
auto fragment() const
Returns the fragment of this URI.
Definition uri.h:529
uri()=default
Default constructor.
uri & operator=(std::string const &str)
String assignment operator.
static const char tbl[256]
Conversion table for hexadecimal characters Used for decoding XX sequences to characters.
Definition uri.h:264
uri(std::string const &str, int af=AF_INET)
Constructor from a string.
static std::string decode(std::string_view input) noexcept
Decodes a URI-encoded string view.
std::string const & query(T &&name, std::size_t const index=0, std::string const &not_found="") const
Returns the value of a specific query parameter.
Definition uri.h:515
static std::string decode(_IT begin, _IT end) noexcept
Decodes a sequence of URI-encoded characters.
Definition uri.h:278
uri & operator=(std::string &&str) noexcept
String move assignment operator.
auto path() const
Returns the path of this URI.
Definition uri.h:473
static bool normalize_path(std::string &path) noexcept
Normalizes a path by resolving '.
uint16_t u_port() const
Returns the port number of this URI as a numeric value.
Definition uri.h:461
static std::string encode(_IT begin, _IT end) noexcept
Encodes a sequence of characters in URI format.
Definition uri.h:314
const auto & encoded_queries() const
Returns the raw query string of this URI.
Definition uri.h:482
auto port() const
Returns the port number of this URI.
Definition uri.h:452
static bool is_valid_host(std::string_view host) noexcept
Validates if a string is a valid URI host.
static uri parse(std::string const &str, int af=AF_INET) noexcept
Creates and parses a URI from a string.
const auto & source() const
Returns the source string of this URI.
Definition uri.h:416
auto host() const
Returns the host name or IP address of this URI.
Definition uri.h:443
const auto & queries() const
Returns the parsed query parameters of this URI.
Definition uri.h:491
static std::string encode(std::string_view input) noexcept
Encodes a string view in URI format.
Configuration and platform-specific definitions for the QB IO library.
Optimized unordered map implementations.
icase_basic_map< qb::unordered_map< std::string, Value >, _Trait > icase_unordered_map
Case-insensitive unordered map using qb::unordered_map.
Definition unordered_map.h:422
bool is_user_info_character(int c)
Checks if a character is valid for URI user information.
Definition uri.h:125
bool is_authority_character(int c)
Checks if a character is valid for the authority part of a URI.
Definition uri.h:135
bool is_fragment_character(int c)
Checks if a character is valid for the fragment part of a URI.
Definition uri.h:167
bool is_alnum(int c)
Checks if a character is alphanumeric.
Definition uri.h:49
bool is_sub_delim(int c)
Checks if a character is a subdelimiter according to RFC 3986.
Definition uri.h:80
bool is_scheme_character(int c)
Checks if a character is valid for a URI scheme.
Definition uri.h:115
bool is_unreserved(int c)
Checks if a character is unreserved according to RFC 3986.
Definition uri.h:59
bool is_reserved(int c)
Checks if a character is reserved according to RFC 3986.
Definition uri.h:105
bool is_gen_delim(int c)
Checks if a character is a general delimiter according to RFC 3986.
Definition uri.h:69
bool is_query_character(int c)
Checks if a character is valid for the query part of a URI.
Definition uri.h:157
bool is_path_character(int c)
Checks if a character is valid for the path part of a URI.
Definition uri.h:146