MySQL 9.3.0
Source Code Documentation
uri.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2015, 2025, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef URI_ROUTING_INCLUDED
27#define URI_ROUTING_INCLUDED
28
30
31#include <cstdint>
32#include <map>
33#include <stdexcept> // runtime_error
34#include <string>
35#include <tuple>
36#include <vector>
37
38namespace mysqlrouter {
39
40using URIAuthority = std::tuple<std::string, uint16_t, std::string,
41 std::string>; // host, port, username, password
42using URIPath = std::vector<std::string>;
43using URIQuery = std::map<std::string, std::string>;
44
45/** @class URIError
46 * @brief Exception when URI was not valid
47 *
48 */
49class URIError : public std::runtime_error {
50 public:
51 URIError(const char *msg, const std::string &uri, size_t position);
52 explicit URIError(const std::string &what_arg)
53 : std::runtime_error(what_arg) {}
54};
55
56/** @class URI
57 * @brief Parse and create URIs according to RFC3986
58 *
59 * This class will parse and make the elements of the URI
60 * available as members.
61 *
62 * Links:
63 * * (RFC 3986)[https://tools.ietf.org/html/rfc3986)
64 *
65 */
67 public:
68 /** @brief Delimiter used in the Query part */
69 static const char query_delimiter = '&';
70
71 /** @brief Default constructor
72 *
73 * Rootless URIs like "mailto:user@example.com" may be forbidden to make sure
74 * that simple "host:addr" doesn't get parsed as (scheme='host', path='addr')
75 *
76 * @param uri URI string to decode
77 * @param allow_path_rootless if parsing rootless URIs is allowed
78 * @param allow_schemeless define if schema is mandatory
79 * @param path_keep_last_slash parsing the URL keeps last slash
80 * @param query_single_parameter_when_cant_parse This parameter allows to
81 * handles query parameter that follows the RFC but is not accepted by default
82 * implementation of URL
83 * @param keep_empty_root parsing the URL keeps empty root
84 */
85 URI(const std::string &uri, bool allow_path_rootless = true,
86 bool allow_schemeless = false, bool path_keep_last_slash = false,
87 bool query_single_parameter_when_cant_parse = false,
88 bool keep_empty_root = false)
89 : scheme(),
90 host(),
91 port(0),
92 username(),
93 password(),
94 path(),
95 query(),
96 fragment(),
97 uri_(uri),
98 allow_path_rootless_(allow_path_rootless),
99 allow_schemeless_{allow_schemeless},
100 path_keep_last_slash_{path_keep_last_slash},
101 query_single_parameter_when_cant_parse_{
102 query_single_parameter_when_cant_parse},
103 keep_empty_root_{keep_empty_root} {
104 if (!uri.empty()) {
105 init_from_uri(uri);
106 }
107 }
108
109 bool operator==(const URI &u2) const;
110 bool operator!=(const URI &u2) const;
111
112 /** return string representation of the URI */
113 std::string str() const;
114
115 /** @brief overload */
116 URI() : URI("") {}
117
118 /** @brief Sets URI using the given URI string
119 *
120 * @param uri URI as string
121 */
122 void set_uri(const std::string &uri) { init_from_uri(uri); }
123
124 /** @brief Path part of the URI as string */
125 std::string get_path_as_string(bool needs_first_slash = true) const;
126
127 /** @brief Set the path part of the URI as string
128 *
129 * @param p path string to decode and store in URI object
130 */
131 void set_path_from_string(const std::string &p);
132
133 /** @brief Get the URIs path part */
134 std::string get_query_as_string() const;
135
136 /** @brief Set the URI query part by reparsing query string
137 *
138 * @param q query string to decode and store in URI object
139 */
140 void set_query_from_string(const std::string &q);
141
142 /** @brief Scheme of the URI */
143 std::string scheme;
144 /** @brief Host part found in the Authority */
145 std::string host;
146 /** @brief Port found in the Authority */
147 uint16_t port; // 0 means use default (no dynamically allocation needed here)
148 /** @brief Username part found in the Authority */
149 std::string username;
150 /** @brief Password part found in the Authority */
151 std::string password;
152 /** @brief Path part of the URI */
154 /** @brief Query part of the URI */
156 /** @brief Fragment part of the URI */
157 std::string fragment;
158
159 private:
160 friend ROUTER_UTILS_EXPORT std::ostream &operator<<(std::ostream &strm,
161 const URI &uri);
162 /** @brief Sets information using the given URI
163 *
164 * Takes a and parsers out all URI elements.
165 *
166 * Throws URIError on errors.
167 *
168 * @param uri URI to use
169 */
170 void init_from_uri(const std::string &uri);
171
172 /** @brief Copy of the original given URI */
173 std::string uri_;
174
175 /** @brief all URIs like mail:foo@example.org which don't have a authority */
177
178 /** @brief all URIs like foo@example.org which don't have a scheme */
182 bool query_is_signle_parameter_{false};
184};
185
186ROUTER_UTILS_EXPORT std::ostream &operator<<(std::ostream &strm,
187 const URI &uri);
188
190 public:
191 static std::string decode(const std::string &uri, bool decode_plus);
192 static URI parse(const std::string &uri, bool allow_path_rootless = true,
193 bool allow_schemeless = false,
194 bool path_keep_last_slash = false,
195 bool query_single_parameter_when_cant_parse = false,
196 bool keep_empty_root = false);
197 static URI parse_shorthand_uri(const std::string &uri,
198 bool allow_path_rootless = true,
199 const std::string &default_scheme = "mysql");
200};
201
202} // namespace mysqlrouter
203
204#endif // URI_ROUTING_INCLUDED
Exception when URI was not valid.
Definition: uri.h:49
URIError(const char *msg, const std::string &uri, size_t position)
Definition: uri.cc:59
URIError(const std::string &what_arg)
Definition: uri.h:52
Definition: uri.h:189
Parse and create URIs according to RFC3986.
Definition: uri.h:66
bool query_single_parameter_when_cant_parse_
Definition: uri.h:181
std::string username
Username part found in the Authority.
Definition: uri.h:149
std::string scheme
Scheme of the URI.
Definition: uri.h:143
std::string password
Password part found in the Authority.
Definition: uri.h:151
bool allow_schemeless_
all URIs like foo@example.org which don't have a scheme
Definition: uri.h:179
void set_uri(const std::string &uri)
Sets URI using the given URI string.
Definition: uri.h:122
bool keep_empty_root_
Definition: uri.h:183
bool allow_path_rootless_
all URIs like mail:foo@example.org which don't have a authority
Definition: uri.h:176
std::string uri_
Copy of the original given URI.
Definition: uri.h:173
uint16_t port
Port found in the Authority.
Definition: uri.h:147
URI(const std::string &uri, bool allow_path_rootless=true, bool allow_schemeless=false, bool path_keep_last_slash=false, bool query_single_parameter_when_cant_parse=false, bool keep_empty_root=false)
Default constructor.
Definition: uri.h:85
URIQuery query
Query part of the URI.
Definition: uri.h:155
URI()
overload
Definition: uri.h:116
std::string fragment
Fragment part of the URI.
Definition: uri.h:157
bool path_keep_last_slash_
Definition: uri.h:180
URIPath path
Path part of the URI.
Definition: uri.h:153
std::string host
Host part found in the Authority.
Definition: uri.h:145
const char * p
Definition: ctype-mb.cc:1227
bool operator!=(const my_thread_handle &a, const my_thread_handle &b)
Definition: my_thread.h:158
bool operator==(const my_thread_handle &a, const my_thread_handle &b)
Definition: my_thread.h:151
static char * query
Definition: myisam_ftdump.cc:47
static char * password
Definition: mysql_secure_installation.cc:58
const char * host
Definition: mysqladmin.cc:66
static char * path
Definition: mysqldump.cc:150
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1084
stdx::expected< std::pair< size_t, T >, std::error_code > decode(const net::const_buffer &buffer, capabilities::value_type caps)
decode a message from a buffer.
Definition: classic_protocol_codec_base.h:119
Definition: base64.h:43
std::vector< std::string > URIPath
Definition: uri.h:42
ROUTER_UTILS_EXPORT std::ostream & operator<<(std::ostream &strm, const URI &uri)
Definition: uri.cc:1207
std::tuple< std::string, uint16_t, std::string, std::string > URIAuthority
Definition: uri.h:41
std::map< std::string, std::string > URIQuery
Definition: uri.h:43
bool parse(MYSQL_THD thd, const string &query, bool is_prepared, Condition_handler *handler)
Definition: services.cc:81
Definition: gcs_xcom_synode.h:64
required uint64 port
Definition: replication_asynchronous_connection_failover.proto:33
#define ROUTER_UTILS_EXPORT
Definition: router_utils_export.h:15
synode_no q[FIFO_SIZE]
Definition: xcom_base.cc:4101