diff options
-rw-r--r-- | libsoup/soup-uri-utils.c | 30 | ||||
-rw-r--r-- | tests/uri-parsing-test.c | 26 |
2 files changed, 51 insertions, 5 deletions
diff --git a/libsoup/soup-uri-utils.c b/libsoup/soup-uri-utils.c index 96807628..0aac9784 100644 --- a/libsoup/soup-uri-utils.c +++ b/libsoup/soup-uri-utils.c @@ -124,16 +124,36 @@ soup_uri_equal (GUri *uri1, GUri *uri2) return TRUE; } +/** + * soup_uri_get_path_and_query: + * @uri: a #GUri + * + * Extracts the `path` and `query` parts from @uri. + * + * Returns: string of combined path and query + **/ char * soup_uri_get_path_and_query (GUri *uri) { + char *path_and_query; + gsize len; + g_return_val_if_fail (uri != NULL, NULL); - return g_uri_join_with_user (SOUP_HTTP_URI_FLAGS, - NULL, NULL, NULL, NULL, NULL, -1, - g_uri_get_path (uri), - g_uri_get_query (uri), - NULL); + /* An empty string is passed instead of NULL for host to prevent critical assertion if path begins with "//" + as per https://tools.ietf.org/html/rfc3986#section-3 */ + path_and_query = g_uri_join_with_user (SOUP_HTTP_URI_FLAGS, + NULL, NULL, NULL, NULL, "", -1, + g_uri_get_path (uri), + g_uri_get_query (uri), + NULL); + + /* The empty host results in starting with `//` which we strip off */ + len = strlen (path_and_query); + memmove (path_and_query, path_and_query + 2, len - 2); + path_and_query[len - 2] = '\0'; + + return path_and_query; } /** diff --git a/tests/uri-parsing-test.c b/tests/uri-parsing-test.c index 8d96ce63..48e3964e 100644 --- a/tests/uri-parsing-test.c +++ b/tests/uri-parsing-test.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ #include "test-utils.h" +#include "soup-uri-utils-private.h" static struct { const char *one, *two; @@ -155,6 +156,30 @@ do_data_uri_tests (void) } } +static struct { + const char *input; + const char *output; +} path_and_query_tests[] = { + { "https://simple/one?two", "/one?two" }, + { "https://double_path//one?two", "//one?two" }, + { "https://empty", "/" }, +}; + +static void +do_path_and_query_tests (void) +{ + for (int i = 0; i < G_N_ELEMENTS (path_and_query_tests); i++) { + GUri *uri = g_uri_parse (path_and_query_tests[i].input, SOUP_HTTP_URI_FLAGS, NULL); + g_assert_nonnull (uri); + + char *path_and_query = soup_uri_get_path_and_query (uri); + g_assert_cmpstr (path_and_query, ==, path_and_query_tests[i].output); + + g_free (path_and_query); + g_uri_unref (uri); + } +} + int main (int argc, char **argv) { @@ -165,6 +190,7 @@ main (int argc, char **argv) g_test_add_func ("/uri/equality", do_equality_tests); g_test_add_func ("/uri/copy", do_copy_tests); g_test_add_func ("/data", do_data_uri_tests); + g_test_add_func ("/path_and_query", do_path_and_query_tests); ret = g_test_run (); |