1/* GLIB - Library of useful routines for C programming
2 * Copyright © 2020 Red Hat, Inc.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21#pragma once
22
23#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
24#error "Only <glib.h> can be included directly."
25#endif
26
27#include <glib/gtypes.h>
28
29G_BEGIN_DECLS
30
31G_GNUC_BEGIN_IGNORE_DEPRECATIONS
32
33typedef struct _GUri GUri;
34
35GLIB_AVAILABLE_IN_2_66
36GUri * g_uri_ref (GUri *uri);
37GLIB_AVAILABLE_IN_2_66
38void g_uri_unref (GUri *uri);
39
40/**
41 * GUriFlags:
42 * @G_URI_FLAGS_NONE: No flags set.
43 * @G_URI_FLAGS_PARSE_RELAXED: Parse the URI more relaxedly than the
44 * [RFC 3986](https://tools.ietf.org/html/rfc3986) grammar specifies,
45 * fixing up or ignoring common mistakes in URIs coming from external
46 * sources. This is also needed for some obscure URI schemes where `;`
47 * separates the host from the path. Don’t use this flag unless you need to.
48 * @G_URI_FLAGS_HAS_PASSWORD: The userinfo field may contain a password,
49 * which will be separated from the username by `:`.
50 * @G_URI_FLAGS_HAS_AUTH_PARAMS: The userinfo may contain additional
51 * authentication-related parameters, which will be separated from
52 * the username and/or password by `;`.
53 * @G_URI_FLAGS_NON_DNS: The host component should not be assumed to be a
54 * DNS hostname or IP address (for example, for `smb` URIs with NetBIOS
55 * hostnames).
56 * @G_URI_FLAGS_ENCODED: When parsing a URI, this indicates that `%`-encoded
57 * characters in the userinfo, path, query, and fragment fields
58 * should not be decoded. (And likewise the host field if
59 * %G_URI_FLAGS_NON_DNS is also set.) When building a URI, it indicates
60 * that you have already `%`-encoded the components, and so #GUri
61 * should not do any encoding itself.
62 * @G_URI_FLAGS_ENCODED_QUERY: Same as %G_URI_FLAGS_ENCODED, for the query
63 * field only.
64 * @G_URI_FLAGS_ENCODED_PATH: Same as %G_URI_FLAGS_ENCODED, for the path only.
65 * @G_URI_FLAGS_ENCODED_FRAGMENT: Same as %G_URI_FLAGS_ENCODED, for the
66 * fragment only.
67 * @G_URI_FLAGS_SCHEME_NORMALIZE: A scheme-based normalization will be applied.
68 * For example, when parsing an HTTP URI changing omitted path to `/` and
69 * omitted port to `80`; and when building a URI, changing empty path to `/`
70 * and default port `80`). This only supports a subset of known schemes. (Since: 2.68)
71 *
72 * Flags that describe a URI.
73 *
74 * When parsing a URI, if you need to choose different flags based on
75 * the type of URI, you can use g_uri_peek_scheme() on the URI string
76 * to check the scheme first, and use that to decide what flags to
77 * parse it with.
78 *
79 * Since: 2.66
80 */
81GLIB_AVAILABLE_TYPE_IN_2_66
82typedef enum {
83 G_URI_FLAGS_NONE = 0,
84 G_URI_FLAGS_PARSE_RELAXED = 1 << 0,
85 G_URI_FLAGS_HAS_PASSWORD = 1 << 1,
86 G_URI_FLAGS_HAS_AUTH_PARAMS = 1 << 2,
87 G_URI_FLAGS_ENCODED = 1 << 3,
88 G_URI_FLAGS_NON_DNS = 1 << 4,
89 G_URI_FLAGS_ENCODED_QUERY = 1 << 5,
90 G_URI_FLAGS_ENCODED_PATH = 1 << 6,
91 G_URI_FLAGS_ENCODED_FRAGMENT = 1 << 7,
92 G_URI_FLAGS_SCHEME_NORMALIZE GLIB_AVAILABLE_ENUMERATOR_IN_2_68 = 1 << 8,
93} GUriFlags;
94
95GLIB_AVAILABLE_IN_2_66
96gboolean g_uri_split (const gchar *uri_ref,
97 GUriFlags flags,
98 gchar **scheme,
99 gchar **userinfo,
100 gchar **host,
101 gint *port,
102 gchar **path,
103 gchar **query,
104 gchar **fragment,
105 GError **error);
106GLIB_AVAILABLE_IN_2_66
107gboolean g_uri_split_with_user (const gchar *uri_ref,
108 GUriFlags flags,
109 gchar **scheme,
110 gchar **user,
111 gchar **password,
112 gchar **auth_params,
113 gchar **host,
114 gint *port,
115 gchar **path,
116 gchar **query,
117 gchar **fragment,
118 GError **error);
119GLIB_AVAILABLE_IN_2_66
120gboolean g_uri_split_network (const gchar *uri_string,
121 GUriFlags flags,
122 gchar **scheme,
123 gchar **host,
124 gint *port,
125 GError **error);
126
127GLIB_AVAILABLE_IN_2_66
128gboolean g_uri_is_valid (const gchar *uri_string,
129 GUriFlags flags,
130 GError **error);
131
132GLIB_AVAILABLE_IN_2_66
133gchar * g_uri_join (GUriFlags flags,
134 const gchar *scheme,
135 const gchar *userinfo,
136 const gchar *host,
137 gint port,
138 const gchar *path,
139 const gchar *query,
140 const gchar *fragment);
141GLIB_AVAILABLE_IN_2_66
142gchar * g_uri_join_with_user (GUriFlags flags,
143 const gchar *scheme,
144 const gchar *user,
145 const gchar *password,
146 const gchar *auth_params,
147 const gchar *host,
148 gint port,
149 const gchar *path,
150 const gchar *query,
151 const gchar *fragment);
152
153GLIB_AVAILABLE_IN_2_66
154GUri * g_uri_parse (const gchar *uri_string,
155 GUriFlags flags,
156 GError **error);
157GLIB_AVAILABLE_IN_2_66
158GUri * g_uri_parse_relative (GUri *base_uri,
159 const gchar *uri_ref,
160 GUriFlags flags,
161 GError **error);
162
163GLIB_AVAILABLE_IN_2_66
164gchar * g_uri_resolve_relative (const gchar *base_uri_string,
165 const gchar *uri_ref,
166 GUriFlags flags,
167 GError **error);
168
169GLIB_AVAILABLE_IN_2_66
170GUri * g_uri_build (GUriFlags flags,
171 const gchar *scheme,
172 const gchar *userinfo,
173 const gchar *host,
174 gint port,
175 const gchar *path,
176 const gchar *query,
177 const gchar *fragment);
178GLIB_AVAILABLE_IN_2_66
179GUri * g_uri_build_with_user (GUriFlags flags,
180 const gchar *scheme,
181 const gchar *user,
182 const gchar *password,
183 const gchar *auth_params,
184 const gchar *host,
185 gint port,
186 const gchar *path,
187 const gchar *query,
188 const gchar *fragment);
189
190/**
191 * GUriHideFlags:
192 * @G_URI_HIDE_NONE: No flags set.
193 * @G_URI_HIDE_USERINFO: Hide the userinfo.
194 * @G_URI_HIDE_PASSWORD: Hide the password.
195 * @G_URI_HIDE_AUTH_PARAMS: Hide the auth_params.
196 * @G_URI_HIDE_QUERY: Hide the query.
197 * @G_URI_HIDE_FRAGMENT: Hide the fragment.
198 *
199 * Flags describing what parts of the URI to hide in
200 * g_uri_to_string_partial(). Note that %G_URI_HIDE_PASSWORD and
201 * %G_URI_HIDE_AUTH_PARAMS will only work if the #GUri was parsed with
202 * the corresponding flags.
203 *
204 * Since: 2.66
205 */
206GLIB_AVAILABLE_TYPE_IN_2_66
207typedef enum {
208 G_URI_HIDE_NONE = 0,
209 G_URI_HIDE_USERINFO = 1 << 0,
210 G_URI_HIDE_PASSWORD = 1 << 1,
211 G_URI_HIDE_AUTH_PARAMS = 1 << 2,
212 G_URI_HIDE_QUERY = 1 << 3,
213 G_URI_HIDE_FRAGMENT = 1 << 4,
214} GUriHideFlags;
215
216GLIB_AVAILABLE_IN_2_66
217char * g_uri_to_string (GUri *uri);
218GLIB_AVAILABLE_IN_2_66
219char * g_uri_to_string_partial (GUri *uri,
220 GUriHideFlags flags);
221
222GLIB_AVAILABLE_IN_2_66
223const gchar *g_uri_get_scheme (GUri *uri);
224GLIB_AVAILABLE_IN_2_66
225const gchar *g_uri_get_userinfo (GUri *uri);
226GLIB_AVAILABLE_IN_2_66
227const gchar *g_uri_get_user (GUri *uri);
228GLIB_AVAILABLE_IN_2_66
229const gchar *g_uri_get_password (GUri *uri);
230GLIB_AVAILABLE_IN_2_66
231const gchar *g_uri_get_auth_params (GUri *uri);
232GLIB_AVAILABLE_IN_2_66
233const gchar *g_uri_get_host (GUri *uri);
234GLIB_AVAILABLE_IN_2_66
235gint g_uri_get_port (GUri *uri);
236GLIB_AVAILABLE_IN_2_66
237const gchar *g_uri_get_path (GUri *uri);
238GLIB_AVAILABLE_IN_2_66
239const gchar *g_uri_get_query (GUri *uri);
240GLIB_AVAILABLE_IN_2_66
241const gchar *g_uri_get_fragment (GUri *uri);
242GLIB_AVAILABLE_IN_2_66
243GUriFlags g_uri_get_flags (GUri *uri);
244
245/**
246 * GUriParamsFlags:
247 * @G_URI_PARAMS_NONE: No flags set.
248 * @G_URI_PARAMS_CASE_INSENSITIVE: Parameter names are case insensitive.
249 * @G_URI_PARAMS_WWW_FORM: Replace `+` with space character. Only useful for
250 * URLs on the web, using the `https` or `http` schemas.
251 * @G_URI_PARAMS_PARSE_RELAXED: See %G_URI_FLAGS_PARSE_RELAXED.
252 *
253 * Flags modifying the way parameters are handled by g_uri_parse_params() and
254 * #GUriParamsIter.
255 *
256 * Since: 2.66
257 */
258GLIB_AVAILABLE_TYPE_IN_2_66
259typedef enum {
260 G_URI_PARAMS_NONE = 0,
261 G_URI_PARAMS_CASE_INSENSITIVE = 1 << 0,
262 G_URI_PARAMS_WWW_FORM = 1 << 1,
263 G_URI_PARAMS_PARSE_RELAXED = 1 << 2,
264} GUriParamsFlags;
265
266GLIB_AVAILABLE_IN_2_66
267GHashTable *g_uri_parse_params (const gchar *params,
268 gssize length,
269 const gchar *separators,
270 GUriParamsFlags flags,
271 GError **error);
272
273typedef struct _GUriParamsIter GUriParamsIter;
274
275struct _GUriParamsIter
276{
277 /*< private >*/
278 gint dummy0;
279 gpointer dummy1;
280 gpointer dummy2;
281 guint8 dummy3[256];
282};
283
284GLIB_AVAILABLE_IN_2_66
285void g_uri_params_iter_init (GUriParamsIter *iter,
286 const gchar *params,
287 gssize length,
288 const gchar *separators,
289 GUriParamsFlags flags);
290
291GLIB_AVAILABLE_IN_2_66
292gboolean g_uri_params_iter_next (GUriParamsIter *iter,
293 gchar **attribute,
294 gchar **value,
295 GError **error);
296
297/**
298 * G_URI_ERROR:
299 *
300 * Error domain for URI methods. Errors in this domain will be from
301 * the #GUriError enumeration. See #GError for information on error
302 * domains.
303 *
304 * Since: 2.66
305 */
306#define G_URI_ERROR (g_uri_error_quark ()) GLIB_AVAILABLE_MACRO_IN_2_66
307GLIB_AVAILABLE_IN_2_66
308GQuark g_uri_error_quark (void);
309
310/**
311 * GUriError:
312 * @G_URI_ERROR_FAILED: Generic error if no more specific error is available.
313 * See the error message for details.
314 * @G_URI_ERROR_BAD_SCHEME: The scheme of a URI could not be parsed.
315 * @G_URI_ERROR_BAD_USER: The user/userinfo of a URI could not be parsed.
316 * @G_URI_ERROR_BAD_PASSWORD: The password of a URI could not be parsed.
317 * @G_URI_ERROR_BAD_AUTH_PARAMS: The authentication parameters of a URI could not be parsed.
318 * @G_URI_ERROR_BAD_HOST: The host of a URI could not be parsed.
319 * @G_URI_ERROR_BAD_PORT: The port of a URI could not be parsed.
320 * @G_URI_ERROR_BAD_PATH: The path of a URI could not be parsed.
321 * @G_URI_ERROR_BAD_QUERY: The query of a URI could not be parsed.
322 * @G_URI_ERROR_BAD_FRAGMENT: The fragment of a URI could not be parsed.
323 *
324 * Error codes returned by #GUri methods.
325 *
326 * Since: 2.66
327 */
328typedef enum {
329 G_URI_ERROR_FAILED,
330 G_URI_ERROR_BAD_SCHEME,
331 G_URI_ERROR_BAD_USER,
332 G_URI_ERROR_BAD_PASSWORD,
333 G_URI_ERROR_BAD_AUTH_PARAMS,
334 G_URI_ERROR_BAD_HOST,
335 G_URI_ERROR_BAD_PORT,
336 G_URI_ERROR_BAD_PATH,
337 G_URI_ERROR_BAD_QUERY,
338 G_URI_ERROR_BAD_FRAGMENT,
339} GUriError;
340
341/**
342 * G_URI_RESERVED_CHARS_GENERIC_DELIMITERS:
343 *
344 * Generic delimiters characters as defined in
345 * [RFC 3986](https://tools.ietf.org/html/rfc3986). Includes `:/?#[]@`.
346 *
347 * Since: 2.16
348 **/
349#define G_URI_RESERVED_CHARS_GENERIC_DELIMITERS ":/?#[]@"
350
351/**
352 * G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS:
353 *
354 * Subcomponent delimiter characters as defined in
355 * [RFC 3986](https://tools.ietf.org/html/rfc3986). Includes `!$&'()*+,;=`.
356 *
357 * Since: 2.16
358 **/
359#define G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS "!$&'()*+,;="
360
361/**
362 * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT:
363 *
364 * Allowed characters in path elements. Includes `!$&'()*+,;=:@`.
365 *
366 * Since: 2.16
367 **/
368#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":@"
369
370/**
371 * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH:
372 *
373 * Allowed characters in a path. Includes `!$&'()*+,;=:@/`.
374 *
375 * Since: 2.16
376 **/
377#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT "/"
378
379/**
380 * G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO:
381 *
382 * Allowed characters in userinfo as defined in
383 * [RFC 3986](https://tools.ietf.org/html/rfc3986). Includes `!$&'()*+,;=:`.
384 *
385 * Since: 2.16
386 **/
387#define G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":"
388
389GLIB_AVAILABLE_IN_ALL
390char * g_uri_unescape_string (const char *escaped_string,
391 const char *illegal_characters);
392GLIB_AVAILABLE_IN_ALL
393char * g_uri_unescape_segment (const char *escaped_string,
394 const char *escaped_string_end,
395 const char *illegal_characters);
396
397GLIB_AVAILABLE_IN_ALL
398char * g_uri_parse_scheme (const char *uri);
399GLIB_AVAILABLE_IN_2_66
400const char *g_uri_peek_scheme (const char *uri);
401
402GLIB_AVAILABLE_IN_ALL
403char * g_uri_escape_string (const char *unescaped,
404 const char *reserved_chars_allowed,
405 gboolean allow_utf8);
406
407GLIB_AVAILABLE_IN_2_66
408GBytes * g_uri_unescape_bytes (const char *escaped_string,
409 gssize length,
410 const char *illegal_characters,
411 GError **error);
412
413GLIB_AVAILABLE_IN_2_66
414char * g_uri_escape_bytes (const guint8 *unescaped,
415 gsize length,
416 const char *reserved_chars_allowed);
417
418G_GNUC_END_IGNORE_DEPRECATIONS
419
420G_END_DECLS
421