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.