Marc-André Lureau has landed GUri
support in GLib, and it’ll be available in GLib 2.65.1 (due out in the next few days).
GUri
is a new API for parsing and building URIs, roughly equivalent to SoupURI
already provided by libsoup — but since URIs are so pervasive, and used even if you’re not actually doing HTTP conversations, it makes sense to have a structured representation for them in GLib.
To parse a URI, use g_uri_parse()
or g_uri_split()
:
g_autoptr(GError) local_error = NULL;
const gchar *uri_str;
g_autoptr(GUri) uri = NULL;
g_autoptr(GHashTable) query_params = NULL;
uri_str = "https://discourse.gnome.org/search?q=search%20terms#ember372";
uri = g_uri_parse (uri_str,
G_URI_FLAGS_PARSE_STRICT |
G_URI_FLAGS_ENCODED_QUERY,
&local_error);
if (uri == NULL)
{
/* Handle the error */
g_error ("Invalid URI: %s", uri_str);
return;
}
g_assert_cmpstr (g_uri_get_scheme (uri), ==, "https");
g_assert_cmpstr (g_uri_get_host (uri), ==, "discourse.gnome.org");
g_assert_cmpstr (g_uri_get_path (uri), ==, "/search");
g_assert_cmpstr (g_uri_get_query (uri), ==, "q=search%20terms");
g_assert_cmpstr (g_uri_get_fragment (uri), ==, "ember372");
/* Parse the params further. Using g_uri_parse_params() requires that we pass G_URI_FLAGS_ENCODED_QUERY to g_uri_parse() above, otherwise the %-encoded values could be decoded to create more separators */
query_params = g_uri_parse_params (g_uri_get_query (uri), -1,
"&",
G_URI_PARAMS_NONE,
&local_error);
if (query_params == NULL)
{
/* Handle the error */
g_error ("Invalid query: %s", g_uri_get_query (uri));
return;
}
g_assert_cmpstr (g_hash_table_lookup (query_params, "q"), ==, "search terms");
Building a URI is a matter of calling g_uri_build()
or g_uri_join()
, which should be self-explanatory.
Please try it out! The API is unstable until GLib makes its 2.66.0 stable release (freezing on 2020-08-08), so now is the time to comment on things which don’t make sense or are hard to use.