URI parsing and building in GLib

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.