1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * SPDX-License-Identifier: LGPL-2.1-or-later
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.1 of the License, or (at your option) any later version.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
36 char *expected_result;
37 gint expected_error; /* If failed */
41 file_to_uri_tests[] = {
42 { "/etc", NULL, "file:///etc", 0 },
43 { "/etc", "", "file:///etc", 0 },
44 { "/etc", "otherhost", "file://otherhost/etc", 0 },
46 { "/etc", "localhost", "file:///etc", 0 },
47 { "c:\\windows", NULL, "file:///c:/windows", 0 },
48 { "c:\\windows", "localhost", "file:///c:/windows", 0 },
49 { "c:\\windows", "otherhost", "file://otherhost/c:/windows", 0 },
50 { "\\\\server\\share\\dir", NULL, "file:////server/share/dir", 0 },
51 { "\\\\server\\share\\dir", "localhost", "file:////server/share/dir", 0 },
53 { "/etc", "localhost", "file://localhost/etc", 0 },
54 { "c:\\windows", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH}, /* it's important to get this error on Unix */
55 { "c:\\windows", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
56 { "c:\\windows", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
58 { "etc", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
59 #ifndef G_PLATFORM_WIN32
60 { "/etc/\xE5\xE4\xF6", NULL, "file:///etc/%E5%E4%F6", 0 },
61 { "/etc/\xC3\xB6\xC3\xA4\xC3\xA5", NULL, "file:///etc/%C3%B6%C3%A4%C3%A5", 0 },
63 { "/etc", "\xC3\xB6\xC3\xA4\xC3\xA5", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
64 { "/etc", "\xE5\xE4\xF6", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
65 { "/etc/file with #%", NULL, "file:///etc/file%20with%20%23%25", 0 },
66 { "", NULL, NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
67 { "", "", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
68 { "", "localhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
69 { "", "otherhost", NULL, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH},
70 { "/0123456789", NULL, "file:///0123456789", 0 },
71 { "/ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL, "file:///ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 },
72 { "/abcdefghijklmnopqrstuvwxyz", NULL, "file:///abcdefghijklmnopqrstuvwxyz", 0 },
73 { "/-_.!~*'()", NULL, "file:///-_.!~*'()", 0 },
75 /* As '\\' is a path separator on Win32, it gets turned into '/' in the URI */
76 { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B/%5D%5E%60%7B%7C%7D%7F", 0 },
78 /* On Unix, '\\' is a normal character in the file name */
79 { "/\"#%<>[\\]^`{|}\x7F", NULL, "file:///%22%23%25%3C%3E%5B%5C%5D%5E%60%7B%7C%7D%7F", 0 },
81 { "/;@+$,", NULL, "file:///%3B@+$,", 0 },
82 /* This and some of the following are of course as such illegal file names on Windows,
83 * and would not occur in real life.
85 { "/:", NULL, "file:///:", 0 },
86 { "/?&=", NULL, "file:///%3F&=", 0 },
87 { "/", "0123456789-", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
88 { "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", 0 },
89 { "/", "abcdefghijklmnopqrstuvwxyz", "file://abcdefghijklmnopqrstuvwxyz/", 0 },
90 { "/", "_.!~*'()", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
91 { "/", "\"#%<>[\\]^`{|}\x7F", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
92 { "/", ";?&=+$,", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
93 { "/", "/", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
94 { "/", "@:", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
95 { "/", "\x80\xFF", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
96 { "/", "\xC3\x80\xC3\xBF", NULL, G_CONVERT_ERROR_ILLEGAL_SEQUENCE},
103 char *expected_filename;
104 char *expected_hostname;
105 gint expected_error; /* If failed */
109 file_from_uri_tests[] = {
110 { "file:///etc", "/etc", NULL, 0 },
111 { "FILE:///etc", "/etc", NULL, 0 },
112 { "file:/etc", "/etc", NULL, 0 },
114 /* On Win32 we don't return "localhost" hostames, just in case
115 * it isn't recognized anyway.
117 { "file://localhost/etc", "/etc", NULL, 0 },
118 { "file://localhost/etc/%23%25%20file", "/etc/#% file", NULL, 0 },
119 { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", NULL, 0 },
120 { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", NULL, 0 },
122 { "file://localhost/etc", "/etc", "localhost", 0 },
123 { "file://localhost/etc/%23%25%20file", "/etc/#% file", "localhost", 0 },
124 { "file://localhost/\xE5\xE4\xF6", "/\xe5\xe4\xf6", "localhost", 0 },
125 { "file://localhost/%E5%E4%F6", "/\xe5\xe4\xf6", "localhost", 0 },
127 { "file://otherhost/etc", "/etc", "otherhost", 0 },
128 { "file://otherhost/etc/%23%25%20file", "/etc/#% file", "otherhost", 0 },
129 { "file://%C3%B6%C3%A4%C3%A5/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
130 { "file:////etc/%C3%B6%C3%C3%C3%A5", "//etc/\xc3\xb6\xc3\xc3\xc3\xa5", NULL, 0 },
131 { "file://\xE5\xE4\xF6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
132 { "file://%E5%E4%F6/etc", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
133 { "file:///some/file?query", "/some/file", NULL, 0 },
134 { "file:///some/file#bad", "/some/file", NULL, 0 },
135 { "file://some", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
136 { "", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
137 { "file:test", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
138 { "http://www.yahoo.com/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
139 { "file:////etc", "//etc", NULL, 0 },
140 { "file://///etc", "///etc", NULL, 0 },
142 /* URIs with backslashes come from some nonstandard application, but accept them anyhow */
143 { "file:///c:\\foo", "c:\\foo", NULL, 0 },
144 { "file:///c:/foo\\bar", "c:\\foo\\bar", NULL, 0 },
145 /* Accept also the old Netscape drive-letter-and-vertical bar convention */
146 { "file:///c|/foo", "c:\\foo", NULL, 0 },
147 { "file:////server/share/dir", "\\\\server\\share\\dir", NULL, 0 },
148 { "file://localhost//server/share/foo", "\\\\server\\share\\foo", NULL, 0 },
149 { "file://otherhost//server/share/foo", "\\\\server\\share\\foo", "otherhost", 0 },
151 { "file:///c:\\foo", "/c:\\foo", NULL, 0 },
152 { "file:///c:/foo", "/c:/foo", NULL, 0 },
153 { "file:////c:/foo", "//c:/foo", NULL, 0 },
155 { "file://0123456789/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
156 { "file://ABCDEFGHIJKLMNOPQRSTUVWXYZ/", "/", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0 },
157 { "file://abcdefghijklmnopqrstuvwxyz/", "/", "abcdefghijklmnopqrstuvwxyz", 0 },
158 { "file://-_.!~*'()/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
159 { "file://\"<>[\\]^`{|}\x7F/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
160 { "file://;?&=+$,/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
161 { "file://%C3%80%C3%BF/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
162 { "file://@/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
163 { "file://:/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
164 { "file://#/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
165 { "file://%23/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
166 { "file://%2F/", NULL, NULL, G_CONVERT_ERROR_BAD_URI},
170 run_file_to_uri_tests (void)
176 for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++)
179 res = g_filename_to_uri (file_to_uri_tests[i].filename,
180 file_to_uri_tests[i].hostname,
184 g_assert_cmpstr (res, ==, file_to_uri_tests[i].expected_result);
186 g_assert_error (error, G_CONVERT_ERROR, file_to_uri_tests[i].expected_error);
189 g_clear_error (&error);
194 run_file_from_uri_tests (void)
201 for (i = 0; i < G_N_ELEMENTS (file_from_uri_tests); i++)
204 res = g_filename_from_uri (file_from_uri_tests[i].uri,
209 if (file_from_uri_tests[i].expected_filename)
212 p = file_from_uri_tests[i].expected_filename =
213 g_strdup (file_from_uri_tests[i].expected_filename);
214 while ((slash = strchr (p, '/')) != NULL)
222 g_assert_cmpstr (res, ==, file_from_uri_tests[i].expected_filename);
224 g_assert_error (error, G_CONVERT_ERROR, file_from_uri_tests[i].expected_error);
225 g_assert_cmpstr (hostname, ==, file_from_uri_tests[i].expected_hostname);
229 g_clear_error (&error);
234 safe_strcmp_filename (const gchar *a, const gchar *b)
237 return g_strcmp0 (a, b);
240 return g_strcmp0 (a, b);
245 if ((G_IS_DIR_SEPARATOR (*a) && G_IS_DIR_SEPARATOR (*b)) ||
257 safe_strcmp_hostname (const gchar *a, const gchar *b)
264 return strcmp (a, b);
266 if (strcmp (a, "localhost") == 0 && !*b)
269 return strcmp (a, b);
274 run_file_roundtrip_tests (void)
277 gchar *uri, *hostname, *res;
280 for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++)
282 if (file_to_uri_tests[i].expected_error != 0)
286 uri = g_filename_to_uri (file_to_uri_tests[i].filename,
287 file_to_uri_tests[i].hostname,
289 g_assert_no_error (error);
292 res = g_filename_from_uri (uri, &hostname, &error);
293 g_assert_no_error (error);
295 g_assert_cmpint (safe_strcmp_filename (file_to_uri_tests[i].filename, res), ==, 0);
296 g_assert_cmpint (safe_strcmp_hostname (file_to_uri_tests[i].hostname, hostname), ==, 0);
304 run_uri_list_tests (void)
306 /* straight from the RFC */
308 "# urn:isbn:0-201-08372-8\r\n"
309 "http://www.huh.org/books/foo.html\r\n"
310 "http://www.huh.org/books/foo.pdf \r\n"
311 " ftp://ftp.foo.org/books/foo.txt\r\n";
312 gchar *expected_uris[] = {
313 "http://www.huh.org/books/foo.html",
314 "http://www.huh.org/books/foo.pdf",
315 "ftp://ftp.foo.org/books/foo.txt"
321 uris = g_uri_list_extract_uris (list);
322 g_assert_cmpint (g_strv_length (uris), ==, 3);
324 for (j = 0; j < 3; j++)
325 g_assert_cmpstr (uris[j], ==, expected_uris[j]);
329 uris = g_uri_list_extract_uris ("# just hot air\r\n# more hot air");
330 g_assert_cmpint (g_strv_length (uris), ==, 0);
335 test_uri_unescape_string (void)
340 const gchar *escaped; /* (nullable) */
341 const gchar *illegal_characters; /* (nullable) */
343 const gchar *expected_unescaped; /* (nullable) */
347 { "%2Babc %4F", NULL, "+abc O" },
348 { "%2Babc %4F", "+", NULL },
349 { "%00abc %4F", "+/", NULL },
350 { "/cursors/none.png", "/", "/cursors/none.png" },
351 { "/cursors%2fbad-subdir/none.png", "/", NULL },
352 { "%0", NULL, NULL },
353 { "%ra", NULL, NULL },
354 { "%2r", NULL, NULL },
355 { "Timm B\303\244der", NULL, "Timm B\303\244der" },
356 { NULL, NULL, NULL }, /* actually a valid test, not a delimiter */
360 for (i = 0; i < G_N_ELEMENTS (tests); i++)
364 g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].escaped);
366 s = g_uri_unescape_string (tests[i].escaped, tests[i].illegal_characters);
367 g_assert_cmpstr (s, ==, tests[i].expected_unescaped);
373 test_uri_unescape_bytes (gconstpointer test_data)
375 GError *error = NULL;
376 gboolean use_nul_terminated = GPOINTER_TO_INT (test_data);
380 const gchar *escaped; /* (nullable) */
381 const gchar *illegal;
383 gssize expected_unescaped_len; /* -1 => error expected */
384 const guint8 *expected_unescaped; /* (nullable) */
388 { "%00%00", NULL, 2, (const guint8 *) "\x00\x00" },
389 { "/cursors/none.png", "/", 17, (const guint8 *) "/cursors/none.png" },
390 { "/cursors%2fbad-subdir/none.png", "/", -1, NULL },
391 { "%%", NULL, -1, NULL },
392 { "%", NULL, -1, NULL },
396 for (i = 0; i < G_N_ELEMENTS (tests); i++)
398 gssize escaped_len = 0;
399 gchar *escaped = NULL;
400 GBytes *bytes = NULL;
402 g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, tests[i].escaped);
404 /* The tests get run twice: once with the length unspecified, using a
405 * nul-terminated string; and once with the length specified and a copy of
406 * the string with the trailing nul explicitly removed (to help catch
407 * buffer overflows). */
408 if (use_nul_terminated)
411 escaped = g_strdup (tests[i].escaped);
415 escaped_len = strlen (tests[i].escaped); /* no trailing nul */
416 escaped = g_memdup2 (tests[i].escaped, escaped_len);
419 bytes = g_uri_unescape_bytes (escaped, escaped_len, tests[i].illegal, &error);
421 if (tests[i].expected_unescaped_len < 0)
423 g_assert_null (bytes);
424 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED);
425 g_clear_error (&error);
429 g_assert_no_error (error);
430 g_assert_cmpmem (g_bytes_get_data (bytes, NULL),
431 g_bytes_get_size (bytes),
432 tests[i].expected_unescaped,
433 tests[i].expected_unescaped_len);
436 g_clear_pointer (&bytes, g_bytes_unref);
442 test_uri_unescape_segment (void)
444 const gchar *escaped_segment = "%2Babc %4F---";
447 s = g_uri_unescape_segment (escaped_segment, escaped_segment + 10, NULL);
448 g_assert_cmpstr (s, ==, "+abc O");
451 s = g_uri_unescape_segment ("%2Babc%00cde", NULL, NULL);
456 test_uri_escape_string (void)
461 const gchar *unescaped;
462 const gchar *reserved_chars_allowed;
465 const gchar *expected_escaped;
469 { "abcdefgABCDEFG._~", NULL, FALSE, "abcdefgABCDEFG._~" },
470 { ":+ \\?#", NULL, FALSE, "%3A%2B%20%5C%3F%23" },
471 { "a+b:c", "+", FALSE, "a+b%3Ac" },
472 { "a+b:c\303\234", "+", TRUE, "a+b%3Ac\303\234" },
473 /* Incomplete UTF-8 sequence: */
474 { "\xfc\x3b\xd2", NULL, TRUE, "%FC%3B%D2" },
475 /* Invalid sequence: */
476 { "\xc3\xb1\xc3\x28", NULL, TRUE, "ñ%C3%28" },
480 for (i = 0; i < G_N_ELEMENTS (tests); i++)
483 gchar *escaped = g_strescape (tests[i].unescaped, NULL);
485 g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, escaped);
487 s = g_uri_escape_string (tests[i].unescaped,
488 tests[i].reserved_chars_allowed,
489 tests[i].allow_utf8);
490 g_assert_cmpstr (s, ==, tests[i].expected_escaped);
497 test_uri_escape_bytes (void)
501 s = g_uri_escape_bytes ((guchar*)"\0\0", 2, NULL);
502 g_assert_cmpstr (s, ==, "%00%00");
507 test_uri_scheme (void)
509 const gchar *s1, *s2;
512 s = g_uri_parse_scheme ("ftp://ftp.gtk.org");
513 g_assert_cmpstr (s, ==, "ftp");
516 s = g_uri_parse_scheme ("good-scheme.but+weird:gtk.org");
517 g_assert_cmpstr (s, ==, "good-scheme.but+weird");
520 s = g_uri_parse_scheme ("1bad:");
522 s = g_uri_parse_scheme ("bad");
524 s = g_uri_parse_scheme ("99http://host/path");
526 s = g_uri_parse_scheme (".http://host/path");
528 s = g_uri_parse_scheme ("+http://host/path");
531 s1 = g_uri_peek_scheme ("ftp://ftp.gtk.org");
532 g_assert_cmpstr (s1, ==, "ftp");
533 s2 = g_uri_peek_scheme ("FTP://ftp.gtk.org");
534 g_assert_cmpstr (s2, ==, "ftp");
535 g_assert_true (s1 == s2);
536 s1 = g_uri_peek_scheme ("1bad:");
538 s1 = g_uri_peek_scheme ("bad");
544 const gchar *userinfo;
549 const gchar *fragment;
557 gboolean expected_success;
558 gint expected_error_code; /* unused if @expected_success is true */
559 const UriParts expected_parts; /* unused if @expected_success is false */
562 static const UriAbsoluteTest absolute_tests[] = {
563 { "foo:", G_URI_FLAGS_NONE, TRUE, 0,
564 { "foo", NULL, NULL, -1, "", NULL, NULL }
566 { "file:/dev/null", G_URI_FLAGS_NONE, TRUE, 0,
567 { "file", NULL, NULL, -1, "/dev/null", NULL, NULL }
569 { "file:///dev/null", G_URI_FLAGS_NONE, TRUE, 0,
570 { "file", NULL, "", -1, "/dev/null", NULL, NULL }
572 { "ftp://user@host/path", G_URI_FLAGS_NONE, TRUE, 0,
573 { "ftp", "user", "host", -1, "/path", NULL, NULL }
575 { "ftp://user@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0,
576 { "ftp", "user", "host", 9999, "/path", NULL, NULL }
578 { "ftp://user:password@host/path", G_URI_FLAGS_NONE, TRUE, 0,
579 { "ftp", "user:password", "host", -1, "/path", NULL, NULL }
581 { "ftp://user:password@host:9999/path", G_URI_FLAGS_NONE, TRUE, 0,
582 { "ftp", "user:password", "host", 9999, "/path", NULL, NULL }
584 { "ftp://user:password@host", G_URI_FLAGS_NONE, TRUE, 0,
585 { "ftp", "user:password", "host", -1, "", NULL, NULL }
587 { "http://us%65r@host", G_URI_FLAGS_NONE, TRUE, 0,
588 { "http", "user", "host", -1, "", NULL, NULL }
590 { "http://us%40r@host", G_URI_FLAGS_NONE, TRUE, 0,
591 { "http", "us@r", "host", -1, "", NULL, NULL }
593 { "http://us%3ar@host", G_URI_FLAGS_NONE, TRUE, 0,
594 { "http", "us:r", "host", -1, "", NULL, NULL }
596 { "http://us%2fr@host", G_URI_FLAGS_NONE, TRUE, 0,
597 { "http", "us/r", "host", -1, "", NULL, NULL }
599 { "http://us%3fr@host", G_URI_FLAGS_NONE, TRUE, 0,
600 { "http", "us?r", "host", -1, "", NULL, NULL }
602 { "http://host?query", G_URI_FLAGS_NONE, TRUE, 0,
603 { "http", NULL, "host", -1, "", "query", NULL }
605 { "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue¶m=value", G_URI_FLAGS_NONE, TRUE, 0,
606 { "http", NULL, "host", -1, "/path", "query=http://host/path?childparam=childvalue¶m=value", NULL }
608 { "http://control-chars/%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F", G_URI_FLAGS_NONE, TRUE, 0,
609 { "http", NULL, "control-chars", -1, "/\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F", NULL, NULL }
611 { "http://space/%20", G_URI_FLAGS_NONE, TRUE, 0,
612 { "http", NULL, "space", -1, "/ ", NULL, NULL }
614 { "http://delims/%3C%3E%23%25%22", G_URI_FLAGS_NONE, TRUE, 0,
615 { "http", NULL, "delims", -1, "/<>#%\"", NULL, NULL }
617 { "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60", G_URI_FLAGS_NONE, TRUE, 0,
618 { "http", NULL, "unwise-chars", -1, "/{}|\\^[]`", NULL, NULL }
622 { "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0,
623 { "http", NULL, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80, "/index.html", NULL, NULL }
625 { "http://[1080:0:0:0:8:800:200C:417A]/index.html", G_URI_FLAGS_NONE, TRUE, 0,
626 { "http", NULL, "1080:0:0:0:8:800:200C:417A", -1, "/index.html", NULL, NULL }
628 { "http://[3ffe:2a00:100:7031::1]", G_URI_FLAGS_NONE, TRUE, 0,
629 { "http", NULL, "3ffe:2a00:100:7031::1", -1, "", NULL, NULL }
631 { "http://[1080::8:800:200C:417A]/foo", G_URI_FLAGS_NONE, TRUE, 0,
632 { "http", NULL, "1080::8:800:200C:417A", -1, "/foo", NULL, NULL }
634 { "http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE, TRUE, 0,
635 { "http", NULL, "::192.9.5.5", -1, "/ipng", NULL, NULL }
637 { "http://[::FFFF:129.144.52.38]:80/index.html", G_URI_FLAGS_NONE, TRUE, 0,
638 { "http", NULL, "::FFFF:129.144.52.38", 80, "/index.html", NULL, NULL }
640 { "http://[2010:836B:4179::836B:4179]", G_URI_FLAGS_NONE, TRUE, 0,
641 { "http", NULL, "2010:836B:4179::836B:4179", -1, "", NULL, NULL }
644 /* some problematic URIs that are handled differently in libsoup */
645 { "http://host/path with spaces", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
646 { "http", NULL, "host", -1, "/path with spaces", NULL, NULL }
648 { " http://host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
649 { "http", NULL, "host", -1, "/path", NULL, NULL }
651 { "http://host/path ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
652 { "http", NULL, "host", -1, "/path", NULL, NULL }
654 { "http://host ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
655 { "http", NULL, "host", -1, "", NULL, NULL }
657 { "http://host:999 ", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
658 { "http", NULL, "host", 999, "", NULL, NULL }
660 { "http://host/pa\nth", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
661 { "http", NULL, "host", -1, "/path", NULL, NULL }
663 { "http:\r\n//host/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
664 { "http", NULL, "host", -1, "/path", NULL, NULL }
666 { "http://\thost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
667 { "http", NULL, "host", -1, "/path", NULL, NULL }
670 /* Bug 594405; 0-length is different from not-present */
671 { "http://host/path?", G_URI_FLAGS_NONE, TRUE, 0,
672 { "http", NULL, "host", -1, "/path", "", NULL }
674 { "http://host/path#", G_URI_FLAGS_NONE, TRUE, 0,
675 { "http", NULL, "host", -1, "/path", NULL, "" },
678 /* Bug 590524; ignore bad %-encoding */
679 { "http://host/path%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
680 { "http", NULL, "host", -1, "/path%", NULL, NULL }
682 { "http://h%ost/path", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
683 { "http", NULL, "h%ost", -1, "/path", NULL, NULL }
685 { "http://host/path%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
686 { "http", NULL, "host", -1, "/path%%", NULL, NULL }
688 { "http://host/path%%%", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
689 { "http", NULL, "host", -1, "/path%%%", NULL, NULL }
691 { "http://host/path%/x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
692 { "http", NULL, "host", -1, "/path%/x/", NULL, NULL }
694 { "http://host/path%0x/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
695 { "http", NULL, "host", -1, "/path%0x/", NULL, NULL }
697 { "http://host/path%ax", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
698 { "http", NULL, "host", -1, "/path%ax", NULL, NULL }
701 /* GUri doesn't %-encode non-ASCII characters */
702 { "http://host/p\xc3\xa4th/", G_URI_FLAGS_NONE, TRUE, 0,
703 { "http", NULL, "host", -1, "/p\xc3\xa4th/", NULL, NULL }
706 { "HTTP:////////////////", G_URI_FLAGS_NONE, TRUE, 0,
707 { "http", NULL, "", -1, "//////////////", NULL, NULL }
710 { "http://@host", G_URI_FLAGS_NONE, TRUE, 0,
711 { "http", "", "host", -1, "", NULL, NULL }
713 { "http://:@host", G_URI_FLAGS_NONE, TRUE, 0,
714 { "http", ":", "host", -1, "", NULL, NULL }
716 { "scheme://foo%3Abar._webdav._tcp.local", G_URI_FLAGS_NONE, TRUE, 0,
717 { "scheme", NULL, "foo:bar._webdav._tcp.local", -1, "", NULL, NULL}
721 { "http://example.com/..", G_URI_FLAGS_NONE, TRUE, 0,
722 { "http", NULL, "example.com", -1, "/", NULL, NULL }
726 { "foo0://host/path", G_URI_FLAGS_NONE, TRUE, 0,
727 { "foo0", NULL, "host", -1, "/path", NULL, NULL } },
728 { "f0.o://host/path", G_URI_FLAGS_NONE, TRUE, 0,
729 { "f0.o", NULL, "host", -1, "/path", NULL, NULL } },
730 { "http++://host/path", G_URI_FLAGS_NONE, TRUE, 0,
731 { "http++", NULL, "host", -1, "/path", NULL, NULL } },
732 { "http-ish://host/path", G_URI_FLAGS_NONE, TRUE, 0,
733 { "http-ish", NULL, "host", -1, "/path", NULL, NULL } },
735 /* IPv6 scope ID parsing (both correct and incorrect) */
736 { "http://[fe80::dead:beef%]/", G_URI_FLAGS_PARSE_RELAXED, FALSE, G_URI_ERROR_BAD_HOST,
737 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
738 { "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
739 { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
740 { "http://[fe80::dead:beef%em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
741 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
742 { "http://[fe80::dead:beef%25em1]/", G_URI_FLAGS_NONE, TRUE, 0,
743 { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
744 { "http://[fe80::dead:beef%25em1%20]/", G_URI_FLAGS_NONE, TRUE, 0,
745 { "http", NULL, "fe80::dead:beef%em1 ", -1, "/", NULL, NULL } },
746 { "http://[fe80::dead:beef%25em%31]/", G_URI_FLAGS_NONE, TRUE, 0,
747 { "http", NULL, "fe80::dead:beef%em1", -1, "/", NULL, NULL } },
748 { "http://[fe80::dead:beef%10]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
749 { "http", NULL, "fe80::dead:beef%10", -1, "/", NULL, NULL } },
750 { "http://[fe80::dead:beef%10]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
751 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
752 { "http://[fe80::dead:beef%25]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
753 { "http", NULL, "fe80::dead:beef%25", -1, "/", NULL, NULL } },
754 { "http://[fe80::dead:beef%25]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
755 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
756 { "http://[192.168.0.1%25em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
757 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
758 { "http://[fe80::dead:beef%2em1]/", G_URI_FLAGS_PARSE_RELAXED, TRUE, 0,
759 { "http", NULL, "fe80::dead:beef%2em1", -1, "/", NULL, NULL } },
760 { "http://[fe80::dead:beef%2em1]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
761 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
762 { "http://[fe80::dead:beef%25em1%00]/", G_URI_FLAGS_PARSE_RELAXED, FALSE, G_URI_ERROR_BAD_HOST,
763 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
764 { "http://[fe80::dead:beef%25em1%00]/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
765 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
767 /* Invalid IDN hostname */
768 { "http://xn--mixed-\xc3\xbcp/", G_URI_FLAGS_NONE, FALSE, G_URI_ERROR_BAD_HOST,
769 { NULL, NULL, NULL, -1, NULL, NULL, NULL } },
773 test_uri_parsing_absolute (void)
777 for (i = 0; i < G_N_ELEMENTS (absolute_tests); i++)
779 const UriAbsoluteTest *test = &absolute_tests[i];
780 GError *error = NULL;
783 g_test_message ("Test %" G_GSIZE_FORMAT ": %s", i, test->orig);
785 uri = g_uri_parse (test->orig, test->flags, &error);
786 if (test->expected_success)
788 g_assert_no_error (error);
790 g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->expected_parts.scheme);
791 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->expected_parts.userinfo);
792 g_assert_cmpstr (g_uri_get_host (uri), ==, test->expected_parts.host);
793 g_assert_cmpint (g_uri_get_port (uri), ==, test->expected_parts.port);
794 g_assert_cmpstr (g_uri_get_path (uri), ==, test->expected_parts.path);
795 g_assert_cmpstr (g_uri_get_query (uri), ==, test->expected_parts.query);
796 g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->expected_parts.fragment);
800 g_assert_error (error, G_URI_ERROR, test->expected_error_code);
804 g_clear_pointer (&uri, g_uri_unref);
805 g_clear_error (&error);
810 const gchar *orig, *resolved;
814 /* This all comes from RFC 3986 */
815 static const char *relative_test_base = "http://a/b/c/d;p?q";
816 static const UriRelativeTest relative_tests[] = {
818 { "g", NULL, NULL, -1, "h", NULL, NULL } },
819 { "g", "http://a/b/c/g",
820 { "http", NULL, "a", -1, "/b/c/g", NULL, NULL } },
821 { "./g", "http://a/b/c/g",
822 { "http", NULL, "a", -1, "/b/c/g", NULL, NULL } },
823 { "g/", "http://a/b/c/g/",
824 { "http", NULL, "a", -1, "/b/c/g/", NULL, NULL } },
825 { "/g", "http://a/g",
826 { "http", NULL, "a", -1, "/g", NULL, NULL } },
828 { "http", NULL, "g", -1, "", NULL, NULL } },
829 { "?y", "http://a/b/c/d;p?y",
830 { "http", NULL, "a", -1, "/b/c/d;p", "y", NULL } },
831 { "g?y", "http://a/b/c/g?y",
832 { "http", NULL, "a", -1, "/b/c/g", "y", NULL } },
833 { "#s", "http://a/b/c/d;p?q#s",
834 { "http", NULL, "a", -1, "/b/c/d;p", "q", "s" } },
835 { "g#s", "http://a/b/c/g#s",
836 { "http", NULL, "a", -1, "/b/c/g", NULL, "s" } },
837 { "g?y#s", "http://a/b/c/g?y#s",
838 { "http", NULL, "a", -1, "/b/c/g", "y", "s" } },
839 { ";x", "http://a/b/c/;x",
840 { "http", NULL, "a", -1, "/b/c/;x", NULL, NULL } },
841 { "g;x", "http://a/b/c/g;x",
842 { "http", NULL, "a", -1, "/b/c/g;x", NULL, NULL } },
843 { "g;x?y#s", "http://a/b/c/g;x?y#s",
844 { "http", NULL, "a", -1, "/b/c/g;x", "y", "s" } },
845 { ".", "http://a/b/c/",
846 { "http", NULL, "a", -1, "/b/c/", NULL, NULL } },
847 { "./", "http://a/b/c/",
848 { "http", NULL, "a", -1, "/b/c/", NULL, NULL } },
849 { "..", "http://a/b/",
850 { "http", NULL, "a", -1, "/b/", NULL, NULL } },
851 { "../", "http://a/b/",
852 { "http", NULL, "a", -1, "/b/", NULL, NULL } },
853 { "../g", "http://a/b/g",
854 { "http", NULL, "a", -1, "/b/g", NULL, NULL } },
855 { "../..", "http://a/",
856 { "http", NULL, "a", -1, "/", NULL, NULL } },
857 { "../../", "http://a/",
858 { "http", NULL, "a", -1, "/", NULL, NULL } },
859 { "../../g", "http://a/g",
860 { "http", NULL, "a", -1, "/g", NULL, NULL } },
861 { "", "http://a/b/c/d;p?q",
862 { "http", NULL, "a", -1, "/b/c/d;p", "q", NULL } },
863 { "../../../g", "http://a/g",
864 { "http", NULL, "a", -1, "/g", NULL, NULL } },
865 { "../../../../g", "http://a/g",
866 { "http", NULL, "a", -1, "/g", NULL, NULL } },
867 { "/./g", "http://a/g",
868 { "http", NULL, "a", -1, "/g", NULL, NULL } },
869 { "/../g", "http://a/g",
870 { "http", NULL, "a", -1, "/g", NULL, NULL } },
871 { "g.", "http://a/b/c/g.",
872 { "http", NULL, "a", -1, "/b/c/g.", NULL, NULL } },
873 { ".g", "http://a/b/c/.g",
874 { "http", NULL, "a", -1, "/b/c/.g", NULL, NULL } },
875 { "g..", "http://a/b/c/g..",
876 { "http", NULL, "a", -1, "/b/c/g..", NULL, NULL } },
877 { "..g", "http://a/b/c/..g",
878 { "http", NULL, "a", -1, "/b/c/..g", NULL, NULL } },
879 { "./../g", "http://a/b/g",
880 { "http", NULL, "a", -1, "/b/g", NULL, NULL } },
881 { "./g/.", "http://a/b/c/g/",
882 { "http", NULL, "a", -1, "/b/c/g/", NULL, NULL } },
883 { "g/./h", "http://a/b/c/g/h",
884 { "http", NULL, "a", -1, "/b/c/g/h", NULL, NULL } },
885 { "g/../h", "http://a/b/c/h",
886 { "http", NULL, "a", -1, "/b/c/h", NULL, NULL } },
887 { "g;x=1/./y", "http://a/b/c/g;x=1/y",
888 { "http", NULL, "a", -1, "/b/c/g;x=1/y", NULL, NULL } },
889 { "g;x=1/../y", "http://a/b/c/y",
890 { "http", NULL, "a", -1, "/b/c/y", NULL, NULL } },
891 { "g?y/./x", "http://a/b/c/g?y/./x",
892 { "http", NULL, "a", -1, "/b/c/g", "y/./x", NULL } },
893 { "g?y/../x", "http://a/b/c/g?y/../x",
894 { "http", NULL, "a", -1, "/b/c/g", "y/../x", NULL } },
895 { "g#s/./x", "http://a/b/c/g#s/./x",
896 { "http", NULL, "a", -1, "/b/c/g", NULL, "s/./x" } },
897 { "g#s/../x", "http://a/b/c/g#s/../x",
898 { "http", NULL, "a", -1, "/b/c/g", NULL, "s/../x" } },
899 { "http:g", "http:g",
900 { "http", NULL, NULL, -1, "g", NULL, NULL } },
901 { "http://a/../..", "http://a/",
902 { "http", NULL, "a", -1, "/", NULL, NULL } },
903 { "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment",
904 "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment",
905 { "scheme", "User:Pass", "HOST.com", 1234, "/path/to}/item-obj", "query=something", "fragment" } },
906 /* Test corner cases of remove_dot_segments */
907 { "http:..", "http:",
908 { "http", NULL, NULL, -1, "", NULL, NULL } },
909 { "http:../", "http:",
910 { "http", NULL, NULL, -1, "", NULL, NULL } },
912 { "http", NULL, NULL, -1, "", NULL, NULL } },
913 { "http:./", "http:",
914 { "http", NULL, NULL, -1, "", NULL, NULL } },
915 { "http:a/..", "http:/",
916 { "http", NULL, NULL, -1, "/", NULL, NULL } },
917 { "http:a/../", "http:/",
918 { "http", NULL, NULL, -1, "/", NULL, NULL } },
920 static int num_relative_tests = G_N_ELEMENTS (relative_tests);
923 test_uri_parsing_relative (void)
927 GError *error = NULL;
930 base = g_uri_parse (relative_test_base, G_URI_FLAGS_NONE, &error);
931 g_assert_no_error (error);
933 for (i = 0; i < num_relative_tests; i++)
935 const UriRelativeTest *test = &relative_tests[i];
938 uri = g_uri_parse_relative (base, test->orig, G_URI_FLAGS_NONE, &error);
939 g_assert_no_error (error);
941 g_assert_cmpstr (g_uri_get_scheme (uri), ==, test->parts.scheme);
942 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, test->parts.userinfo);
943 g_assert_cmpstr (g_uri_get_host (uri), ==, test->parts.host);
944 g_assert_cmpint (g_uri_get_port (uri), ==, test->parts.port);
945 g_assert_cmpstr (g_uri_get_path (uri), ==, test->parts.path);
946 g_assert_cmpstr (g_uri_get_query (uri), ==, test->parts.query);
947 g_assert_cmpstr (g_uri_get_fragment (uri), ==, test->parts.fragment);
949 tostring = g_uri_to_string (uri);
950 g_assert_cmpstr (tostring, ==, test->resolved);
955 resolved = g_uri_resolve_relative (relative_test_base, test->orig, G_URI_FLAGS_NONE, &error);
956 g_assert_no_error (error);
957 g_assert_cmpstr (resolved, ==, test->resolved);
960 uri = g_uri_parse_relative (base, "%%", G_URI_FLAGS_NONE, &error);
962 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PATH);
963 g_clear_error (&error);
967 resolved = g_uri_resolve_relative (NULL, "http://a", G_URI_FLAGS_NONE, &error);
968 g_assert_no_error (error);
969 g_assert_cmpstr (resolved, ==, "http://a");
972 resolved = g_uri_resolve_relative ("http://a", "b", G_URI_FLAGS_NONE, &error);
973 g_assert_no_error (error);
974 g_assert_cmpstr (resolved, ==, "http://a/b");
977 resolved = g_uri_resolve_relative (NULL, "a", G_URI_FLAGS_NONE, &error);
978 g_assert_null (resolved);
979 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED);
980 g_clear_error (&error);
982 resolved = g_uri_resolve_relative ("../b", "a", G_URI_FLAGS_NONE, &error);
983 g_assert_null (resolved);
984 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED);
985 g_clear_error (&error);
987 resolved = g_uri_resolve_relative ("%%", "a", G_URI_FLAGS_PARSE_RELAXED, &error);
988 g_assert_null (resolved);
989 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_FAILED);
990 g_clear_error (&error);
994 test_uri_to_string (void)
999 uri = g_uri_build (G_URI_FLAGS_NONE, "scheme", "userinfo", "host", 1234,
1000 "/path", "query", "fragment");
1002 tostring = g_uri_to_string (uri);
1003 g_assert_cmpstr (tostring, ==, "scheme://userinfo@host:1234/path?query#fragment");
1007 uri = g_uri_build (G_URI_FLAGS_NONE, "scheme", NULL, "fe80::dead:beef%em1", -1, "", NULL, NULL);
1008 tostring = g_uri_to_string (uri);
1009 g_assert_cmpstr (tostring, ==, "scheme://[fe80::dead:beef%25em1]");
1013 uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user", "pass", "auth", "host", 1234,
1014 "/path", "query", "fragment");
1015 tostring = g_uri_to_string (uri);
1016 g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path?query#fragment");
1018 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_USERINFO);
1019 g_assert_cmpstr (tostring, ==, "scheme://host:1234/path?query#fragment");
1021 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_QUERY);
1022 g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path#fragment");
1024 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_FRAGMENT);
1025 g_assert_cmpstr (tostring, ==, "scheme://user:pass;auth@host:1234/path?query");
1029 uri = g_uri_build_with_user (G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS,
1030 "scheme", "us:er", "pass", "auth", "host", 1234,
1031 "/path", "query", "fragment");
1032 tostring = g_uri_to_string (uri);
1033 g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass;auth@host:1234/path?query#fragment");
1035 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD);
1036 g_assert_cmpstr (tostring, ==, "scheme://us%3Aer;auth@host:1234/path?query#fragment");
1038 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_AUTH_PARAMS);
1039 g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass@host:1234/path?query#fragment");
1041 tostring = g_uri_to_string_partial (uri, G_URI_HIDE_QUERY);
1042 g_assert_cmpstr (tostring, ==, "scheme://us%3Aer:pass;auth@host:1234/path#fragment");
1048 test_uri_build (void)
1052 uri = g_uri_build (G_URI_FLAGS_NON_DNS, "scheme", "userinfo", "host", 1234,
1053 "/path", "query", "fragment");
1055 /* check ref/unref */
1059 g_assert_cmpint (g_uri_get_flags (uri), ==, G_URI_FLAGS_NON_DNS);
1060 g_assert_cmpstr (g_uri_get_scheme (uri), ==, "scheme");
1061 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "userinfo");
1062 g_assert_cmpstr (g_uri_get_host (uri), ==, "host");
1063 g_assert_cmpint (g_uri_get_port (uri), ==, 1234);
1064 g_assert_cmpstr (g_uri_get_path (uri), ==, "/path");
1065 g_assert_cmpstr (g_uri_get_query (uri), ==, "query");
1066 g_assert_cmpstr (g_uri_get_fragment (uri), ==, "fragment");
1067 g_assert_cmpstr (g_uri_get_user (uri), ==, NULL);
1068 g_assert_cmpstr (g_uri_get_password (uri), ==, NULL);
1071 uri = g_uri_build_with_user (G_URI_FLAGS_NON_DNS, "scheme", "user", "password",
1072 "authparams", "host", 1234,
1073 "/path", "query", "fragment");
1075 g_assert_cmpint (g_uri_get_flags (uri), ==, G_URI_FLAGS_NON_DNS | G_URI_FLAGS_HAS_PASSWORD);
1076 g_assert_cmpstr (g_uri_get_scheme (uri), ==, "scheme");
1077 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user:password;authparams");
1078 g_assert_cmpstr (g_uri_get_host (uri), ==, "host");
1079 g_assert_cmpint (g_uri_get_port (uri), ==, 1234);
1080 g_assert_cmpstr (g_uri_get_path (uri), ==, "/path");
1081 g_assert_cmpstr (g_uri_get_query (uri), ==, "query");
1082 g_assert_cmpstr (g_uri_get_fragment (uri), ==, "fragment");
1083 g_assert_cmpstr (g_uri_get_user (uri), ==, "user");
1084 g_assert_cmpstr (g_uri_get_password (uri), ==, "password");
1085 g_assert_cmpstr (g_uri_get_auth_params (uri), ==, "authparams");
1088 uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "password\002",
1089 "authparams\003", "host", 1234,
1090 "/path", "query", "fragment");
1091 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user\001:password\002;authparams\003");
1094 uri = g_uri_build_with_user (G_URI_FLAGS_ENCODED, "scheme", "user%01", "password%02",
1095 "authparams%03", "host", 1234,
1096 "/path", "query", "fragment");
1097 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user%01:password%02;authparams%03");
1100 uri = g_uri_build_with_user (G_URI_FLAGS_ENCODED, "scheme", NULL, NULL,
1102 "/path", "query", "fragment");
1103 g_assert_null (g_uri_get_userinfo (uri));
1106 uri = g_uri_build_with_user (G_URI_FLAGS_NONE, "scheme", "user", NULL, NULL,
1108 "/path", "query", "fragment");
1109 g_assert_cmpstr (g_uri_get_userinfo (uri), ==, "user");
1114 test_uri_split (void)
1116 gchar *scheme = NULL;
1117 gchar *userinfo = NULL;
1120 gchar *authparams = NULL;
1123 gchar *query = NULL;
1124 gchar *fragment = NULL;
1125 GError *error = NULL;
1128 g_uri_split ("scheme://user%3Apass%3Bauth@host:1234/path?query#fragment",
1138 g_assert_no_error (error);
1139 g_assert_cmpstr (scheme, ==, "scheme");
1140 g_assert_cmpstr (userinfo, ==, "user:pass;auth");
1141 g_assert_cmpstr (host, ==, "host");
1142 g_assert_cmpint (port, ==, 1234);
1143 g_assert_cmpstr (path, ==, "/path");
1144 g_assert_cmpstr (query, ==, "query");
1145 g_assert_cmpstr (fragment, ==, "fragment");
1153 g_uri_split ("scheme://user%3Apass%3Bauth@h%01st:1234/path?query#fragment",
1154 G_URI_FLAGS_ENCODED,
1163 g_assert_no_error (error);
1164 g_assert_cmpstr (host, ==, "h\001st");
1167 g_uri_split ("scheme://@@@host:1234/path?query#fragment",
1168 G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED,
1177 g_assert_no_error (error);
1178 g_assert_cmpstr (userinfo, ==, "@@");
1182 g_uri_split ("http://f;oo/",
1183 G_URI_FLAGS_NONE | G_URI_FLAGS_PARSE_RELAXED,
1192 g_assert_no_error (error);
1193 g_assert_cmpstr (path, ==, ";oo/");
1196 g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver",
1206 g_assert_no_error (error);
1207 g_assert_cmpstr (host, ==, "h\001st");
1208 g_assert_cmpstr (query, ==, "saisons=Été+hiver");
1212 g_uri_split ("http://h%01st/path?saisons=%C3%89t%C3%A9%2Bhiver",
1213 G_URI_FLAGS_ENCODED_QUERY,
1222 g_assert_no_error (error);
1223 g_assert_cmpstr (host, ==, "h\001st");
1224 g_assert_cmpstr (query, ==, "saisons=%C3%89t%C3%A9%2Bhiver");
1228 g_uri_split ("http://h%01st/%C3%89t%C3%A9%2Bhiver",
1229 G_URI_FLAGS_ENCODED_PATH,
1238 g_assert_no_error (error);
1239 g_assert_cmpstr (path, ==, "/%C3%89t%C3%A9%2Bhiver");
1242 g_uri_split ("file:///path/to/some%20file",
1252 g_assert_no_error (error);
1253 g_assert_cmpstr (path, ==, "/path/to/some file");
1256 g_uri_split ("http://h%01st/path#%C3%89t%C3%A9%2Bhiver",
1257 G_URI_FLAGS_ENCODED_FRAGMENT,
1266 g_assert_no_error (error);
1267 g_assert_cmpstr (fragment, ==, "%C3%89t%C3%A9%2Bhiver");
1270 g_uri_split_with_user ("scheme://user:pass;auth@host:1234/path?query#fragment",
1271 G_URI_FLAGS_HAS_AUTH_PARAMS|G_URI_FLAGS_HAS_PASSWORD,
1282 g_assert_no_error (error);
1283 g_assert_cmpstr (user, ==, "user");
1284 g_assert_cmpstr (pass, ==, "pass");
1285 g_assert_cmpstr (authparams, ==, "auth");
1288 g_free (authparams);
1290 g_uri_split_network ("scheme://user:pass;auth@host:1234/path?query#fragment",
1296 g_assert_no_error (error);
1298 g_uri_split_network ("scheme://user:pass;auth@host:1234/path?query#fragment",
1304 g_assert_no_error (error);
1305 g_assert_cmpstr (scheme, ==, "scheme");
1306 g_assert_cmpstr (host, ==, "host");
1307 g_assert_cmpint (port, ==, 1234);
1311 g_uri_split_network ("%00",
1312 G_URI_FLAGS_NONE, NULL, NULL, NULL, &error);
1313 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PATH);
1314 g_clear_error (&error);
1316 g_uri_split_network ("/a",
1322 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME);
1323 g_clear_error (&error);
1325 g_uri_split_network ("schme:#",
1331 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1332 g_clear_error (&error);
1334 g_uri_split_network ("scheme://[]/a",
1335 G_URI_FLAGS_NONE, NULL, NULL, NULL, &error);
1336 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1337 g_clear_error (&error);
1339 g_uri_split_network ("scheme://user%00:pass;auth@host",
1340 G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS,
1341 NULL, NULL, NULL, &error);
1342 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_USER);
1343 g_clear_error (&error);
1345 g_uri_split_network ("scheme://user:pass%00;auth@host",
1346 G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS,
1347 NULL, NULL, NULL, &error);
1348 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD);
1349 g_clear_error (&error);
1351 g_uri_split_network ("scheme://user:pass;auth@host:1234/path?quer%00y#fragment",
1353 NULL, NULL, NULL, &error);
1354 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_QUERY);
1355 g_clear_error (&error);
1357 g_uri_split_network ("scheme://use%00r:pass;auth@host:1234/path",
1359 NULL, NULL, NULL, &error);
1360 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_USER);
1361 g_clear_error (&error);
1363 g_uri_split ("scheme://user:pass;auth@host:1234/path?query#fragm%00ent",
1373 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_FRAGMENT);
1374 g_clear_error (&error);
1376 g_uri_split_with_user ("scheme://user:pa%x0s;auth@host:1234/path?query#fragment",
1377 G_URI_FLAGS_HAS_PASSWORD,
1388 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD);
1389 g_clear_error (&error);
1391 g_uri_split_with_user ("scheme://user:pass;auth%00@host",
1392 G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS,
1403 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_AUTH_PARAMS);
1404 g_clear_error (&error);
1406 g_uri_split_network ("scheme://user:pass%00;auth@host",
1407 G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS,
1408 NULL, NULL, NULL, &error);
1409 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PASSWORD);
1410 g_clear_error (&error);
1412 /* Path not started correctly */
1413 g_uri_split("scheme://hostname:123path?query#fragment",
1423 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
1424 g_clear_error (&error);
1426 /* Brackets that don't close */
1427 g_uri_split("scheme://[01:23:45:67:89:ab:cd:ef:123/path",
1437 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1438 g_clear_error (&error);
1440 /* IPv6 hostname without brackets */
1441 g_uri_split("scheme://01:23:45:67:89:ab:cd:ef:123/path",
1451 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
1452 g_clear_error (&error);
1456 test_uri_is_valid (void)
1458 GError *error = NULL;
1460 g_assert_true (g_uri_is_valid ("http://[::192.9.5.5]/ipng", G_URI_FLAGS_NONE, NULL));
1461 g_assert_true (g_uri_is_valid ("http://127.127.127.127/", G_URI_FLAGS_NONE, NULL));
1462 g_assert_true (g_uri_is_valid ("http://127.127.127.b/", G_URI_FLAGS_NONE, NULL));
1463 g_assert_true (g_uri_is_valid ("http://\xc3\x89XAMPLE.COM/", G_URI_FLAGS_NONE, NULL));
1465 g_assert_true (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_PARSE_RELAXED, NULL));
1466 g_assert_false (g_uri_is_valid (" \r http\t://f oo \t\n ", G_URI_FLAGS_NONE, &error));
1467 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME);
1468 g_clear_error (&error);
1470 g_assert_false (g_uri_is_valid ("http://[::192.9.5.5/ipng", G_URI_FLAGS_NONE, &error));
1471 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1472 g_clear_error (&error);
1474 g_assert_true (g_uri_is_valid ("http://[fe80::dead:beef%25wef]/", G_URI_FLAGS_NONE, NULL));
1475 g_assert_false (g_uri_is_valid ("http://[fe80::dead:beef%wef%]/", G_URI_FLAGS_NONE, &error));
1476 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1477 g_clear_error (&error);
1479 g_assert_false (g_uri_is_valid ("http://%00/", G_URI_FLAGS_NON_DNS, &error));
1480 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1481 g_clear_error (&error);
1483 g_assert_true (g_uri_is_valid ("http://foo/", G_URI_FLAGS_NON_DNS, &error));
1485 g_assert_false (g_uri_is_valid ("http://%00/", G_URI_FLAGS_NONE, &error));
1486 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1487 g_clear_error (&error);
1489 g_assert_false (g_uri_is_valid ("http://%30.%30.%30.%30/", G_URI_FLAGS_NONE, &error));
1490 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST);
1491 g_clear_error (&error);
1493 g_assert_false (g_uri_is_valid ("http://host:port", G_URI_FLAGS_NONE, &error));
1494 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
1495 g_clear_error (&error);
1497 g_assert_false (g_uri_is_valid ("http://host:65536", G_URI_FLAGS_NONE, &error));
1498 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
1499 g_clear_error (&error);
1501 g_assert_false (g_uri_is_valid ("http://host:6553l", G_URI_FLAGS_NONE, &error));
1502 g_assert_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT);
1503 g_clear_error (&error);
1505 g_assert_true (g_uri_is_valid ("data:,Hello", G_URI_FLAGS_NONE, &error));
1507 g_assert_true (g_uri_is_valid ("B:\\foo.txt", G_URI_FLAGS_NONE, &error));
1508 g_assert_true (g_uri_is_valid ("B:/foo.txt", G_URI_FLAGS_NONE, &error));
1509 g_assert_true (g_uri_is_valid ("B://foo.txt", G_URI_FLAGS_NONE, &error));
1510 g_assert_true (g_uri_is_valid ("B:foo.txt", G_URI_FLAGS_NONE, &error));
1512 g_assert_true (g_uri_is_valid ("fd://0", G_URI_FLAGS_NONE, &error));
1513 g_assert_true (g_uri_is_valid ("AB:\\foo.txt", G_URI_FLAGS_NONE, &error));
1514 g_assert_true (g_uri_is_valid ("AB:/foo.txt", G_URI_FLAGS_NONE, &error));
1515 g_assert_true (g_uri_is_valid ("AB://foo.txt", G_URI_FLAGS_NONE, &error));
1516 g_assert_true (g_uri_is_valid ("AB:foo.txt", G_URI_FLAGS_NONE, &error));
1518 g_assert_true (g_uri_is_valid ("ABC:/foo.txt", G_URI_FLAGS_NONE, &error));
1519 g_assert_true (g_uri_is_valid ("ABC://foo.txt", G_URI_FLAGS_NONE, &error));
1520 g_assert_true (g_uri_is_valid ("ABC:foo.txt", G_URI_FLAGS_NONE, &error));
1522 g_assert_true (g_uri_is_valid ("ABCD:/foo.txt", G_URI_FLAGS_NONE, &error));
1523 g_assert_true (g_uri_is_valid ("ABCD://foo.txt", G_URI_FLAGS_NONE, &error));
1524 g_assert_true (g_uri_is_valid ("ABCD:foo.txt", G_URI_FLAGS_NONE, &error));
1532 GUriParamsFlags flags;
1534 /* key, value, key, value, …, limited to length 2*expected_n_params */
1535 gssize expected_n_iter; /* -1 => error expected */
1536 const gchar *expected_iter_key_values[6];
1537 gssize expected_n_params; /* -1 => error expected */
1538 const gchar *expected_param_key_values[6];
1541 { "p1=foo&p2=bar;p3=baz", "&;", G_URI_PARAMS_NONE,
1542 3, { "p1", "foo", "p2", "bar", "p3", "baz" },
1543 3, { "p1", "foo", "p2", "bar", "p3", "baz" }},
1544 { "p1=foo&p2=bar", "", G_URI_PARAMS_NONE,
1545 1, { "p1", "foo&p2=bar" },
1546 1, { "p1", "foo&p2=bar" }},
1547 { "p1=foo&&P1=bar", "&", G_URI_PARAMS_NONE,
1550 { "%00=foo", "&", G_URI_PARAMS_NONE,
1553 { "p1=%00", "&", G_URI_PARAMS_NONE,
1556 { "p1=foo&p1=bar", "&", G_URI_PARAMS_NONE,
1557 2, { "p1", "foo", "p1", "bar" },
1558 1, { "p1", "bar", NULL, }},
1559 { "p1=foo&P1=bar", "&", G_URI_PARAMS_CASE_INSENSITIVE,
1560 2, { "p1", "foo", "P1", "bar" },
1561 1, { "p1", "bar", NULL, }},
1562 { "=%", "&", G_URI_PARAMS_PARSE_RELAXED,
1563 1, { "", "%", NULL, },
1564 1, { "", "%", NULL, }},
1565 { "=", "&", G_URI_PARAMS_NONE,
1566 1, { "", "", NULL, },
1567 1, { "", "", NULL, }},
1568 { "foo", "&", G_URI_PARAMS_NONE,
1571 { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_WWW_FORM,
1572 2, { "foo", "bar & baz", "saisons", "Été+hiver", NULL, },
1573 2, { "foo", "bar & baz", "saisons", "Été+hiver", NULL, }},
1574 { "foo=bar+%26+baz&saisons=%C3%89t%C3%A9%2Bhiver", "&", G_URI_PARAMS_NONE,
1575 2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, },
1576 2, { "foo", "bar+&+baz", "saisons", "Été+hiver", NULL, }},
1577 { "token=exp=123~acl=/QualityLevels(*~hmac=0cb", "&", G_URI_PARAMS_NONE,
1578 1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, },
1579 1, { "token", "exp=123~acl=/QualityLevels(*~hmac=0cb", NULL, }},
1583 test_uri_iter_params (gconstpointer test_data)
1586 gboolean use_nul_terminated = GPOINTER_TO_INT (test_data);
1589 for (i = 0; i < G_N_ELEMENTS (params_tests); i++)
1591 GUriParamsIter iter;
1592 gchar *uri, *attr, *value;
1595 g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri);
1597 g_assert (params_tests[i].expected_n_params < 0 ||
1598 params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
1600 /* The tests get run twice: once with the length unspecified, using a
1601 * nul-terminated string; and once with the length specified and a copy of
1602 * the string with the trailing nul explicitly removed (to help catch
1603 * buffer overflows). */
1604 if (use_nul_terminated)
1607 uri = g_strdup (params_tests[i].uri);
1611 uri_len = strlen (params_tests[i].uri); /* no trailing nul */
1612 uri = g_memdup2 (params_tests[i].uri, uri_len);
1615 /* Run once without extracting the attr or value, just to check the numbers. */
1617 g_uri_params_iter_init (&iter, params_tests[i].uri, -1, params_tests[i].separators, params_tests[i].flags);
1618 while (g_uri_params_iter_next (&iter, NULL, NULL, &err))
1620 g_assert_cmpint (n, ==, params_tests[i].expected_n_iter);
1623 g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED);
1624 g_clear_error (&err);
1627 /* Run again and check the strings too. */
1629 g_uri_params_iter_init (&iter, params_tests[i].uri, -1, params_tests[i].separators, params_tests[i].flags);
1630 while (g_uri_params_iter_next (&iter, &attr, &value, &err))
1632 g_assert_cmpstr (attr, ==, params_tests[i].expected_iter_key_values[n * 2]);
1633 g_assert_cmpstr (value, ==, params_tests[i].expected_iter_key_values[n * 2 + 1]);
1638 g_assert_cmpint (n, ==, params_tests[i].expected_n_iter);
1641 g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED);
1642 g_clear_error (&err);
1650 test_uri_parse_params (gconstpointer test_data)
1653 gboolean use_nul_terminated = GPOINTER_TO_INT (test_data);
1656 for (i = 0; i < G_N_ELEMENTS (params_tests); i++)
1662 g_test_message ("URI %" G_GSIZE_FORMAT ": %s", i, params_tests[i].uri);
1664 g_assert (params_tests[i].expected_n_params < 0 ||
1665 params_tests[i].expected_n_params <= (gssize) G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
1667 /* The tests get run twice: once with the length unspecified, using a
1668 * nul-terminated string; and once with the length specified and a copy of
1669 * the string with the trailing nul explicitly removed (to help catch
1670 * buffer overflows). */
1671 if (use_nul_terminated)
1674 uri = g_strdup (params_tests[i].uri);
1678 uri_len = strlen (params_tests[i].uri); /* no trailing nul */
1679 uri = g_memdup2 (params_tests[i].uri, uri_len);
1682 params = g_uri_parse_params (uri, uri_len, params_tests[i].separators, params_tests[i].flags, &err);
1684 if (params_tests[i].expected_n_params < 0)
1686 g_assert_null (params);
1687 g_assert_error (err, G_URI_ERROR, G_URI_ERROR_FAILED);
1688 g_clear_error (&err);
1694 g_assert_no_error (err);
1695 g_assert_cmpint (g_hash_table_size (params), ==, params_tests[i].expected_n_params);
1697 for (j = 0; j < (gsize) params_tests[i].expected_n_params; j += 2)
1698 g_assert_cmpstr (g_hash_table_lookup (params, params_tests[i].expected_param_key_values[j]), ==,
1699 params_tests[i].expected_param_key_values[j + 1]);
1702 g_clear_pointer (¶ms, g_hash_table_unref);
1708 test_uri_join (void)
1712 uri = g_uri_join (G_URI_FLAGS_NONE, "foo", "some:user@info", "bar", -1, "", NULL, NULL);
1713 g_assert_cmpstr (uri, ==, "foo://some:user%40info@bar");
1716 uri = g_uri_join (G_URI_FLAGS_NONE, NULL, NULL, NULL, -1, "/foo", "abc", NULL);
1717 g_assert_cmpstr (uri, ==, "/foo?abc");
1720 uri = g_uri_join (G_URI_FLAGS_NONE, NULL, NULL, "hostname", -1, "/foo", "abc", NULL);
1721 g_assert_cmpstr (uri, ==, "//hostname/foo?abc");
1724 uri = g_uri_join_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "pass\002", "authparams\003",
1725 "host", 9876, "/path", "query", "fragment");
1726 g_assert_cmpstr (uri, ==, "scheme://user%01:pass%02;authparams%03@host:9876/path?query#fragment");
1729 uri = g_uri_join_with_user (G_URI_FLAGS_NONE, "scheme", "user\001", "pass\002", "authparams\003",
1730 "::192.9.5.5", 9876, "/path", "query", "fragment");
1731 g_assert_cmpstr (uri, ==, "scheme://user%01:pass%02;authparams%03@[::192.9.5.5]:9876/path?query#fragment");
1734 uri = g_uri_join_with_user (G_URI_FLAGS_ENCODED,
1735 "scheme", "user%01", "pass%02", "authparams%03",
1736 "::192.9.5.5", 9876, "/path", "query", "fragment");
1737 g_assert_cmpstr (uri, ==,
1738 "scheme://user%01:pass%02;authparams%03@[::192.9.5.5]:9876/path?query#fragment");
1741 uri = g_uri_join (G_URI_FLAGS_NONE, "scheme", NULL, "foo:bar._webdav._tcp.local", -1, "", NULL, NULL);
1742 g_assert_cmpstr (uri, ==, "scheme://foo%3Abar._webdav._tcp.local");
1747 test_uri_join_split_round_trip (void)
1749 GUriFlags flags = G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_HAS_AUTH_PARAMS;
1752 g_test_summary ("Test that joining different URI components survives a round trip");
1754 /* Each bit in @i indicates whether the corresponding URI field should be set
1756 for (i = 0; i < (1 << 8); i++)
1759 const gchar *scheme, *user, *password, *auth_params, *host, *path, *query, *fragment;
1761 gchar *scheme_out = NULL, *user_out = NULL, *password_out = NULL;
1762 gchar *auth_params_out = NULL, *host_out = NULL, *path_out = NULL;
1763 gchar *query_out = NULL, *fragment_out = NULL;
1765 gboolean split_success;
1766 GError *local_error = NULL;
1768 g_test_message ("Combination %u", i);
1770 scheme = (i & (1 << 8)) ? "scheme" : NULL;
1771 host = (i & (1 << 4)) ? "host" : NULL;
1772 user = (host != NULL && i & (1 << 7)) ? "user" : NULL; /* only supported if host is also set */
1773 password = (host != NULL && user != NULL && i & (1 << 6)) ? "password" : NULL; /* only supported if host and user are also set */
1774 auth_params = (host != NULL && user != NULL && i & (1 << 5)) ? "auth_params" : NULL; /* only supported if host and user are also set */
1775 port = (host != NULL && i & (1 << 3)) ? 123 : -1; /* only supported if host is also set */
1776 path = (i & (1 << 2)) ? "/path" : ""; /* the only mandatory component */
1777 query = (i & (1 << 1)) ? "query" : NULL;
1778 fragment = (i & (1 << 0)) ? "fragment" : NULL;
1780 uri = g_uri_join_with_user (flags, scheme, user, password, auth_params,
1781 host, port, path, query, fragment);
1782 g_assert_nonnull (uri);
1784 split_success = g_uri_split_with_user (uri, flags, &scheme_out, &user_out,
1785 &password_out, &auth_params_out,
1786 &host_out, &port_out, &path_out,
1787 &query_out, &fragment_out,
1789 g_assert_no_error (local_error);
1790 g_assert_true (split_success);
1792 g_assert_cmpstr (scheme, ==, scheme_out);
1793 g_assert_cmpstr (user, ==, user_out);
1794 g_assert_cmpstr (password, ==, password_out);
1795 g_assert_cmpstr (auth_params, ==, auth_params_out);
1796 g_assert_cmpstr (host, ==, host_out);
1797 g_assert_cmpint (port, ==, port_out);
1798 g_assert_cmpstr (path, ==, path_out);
1799 g_assert_cmpstr (query, ==, query_out);
1800 g_assert_cmpstr (fragment, ==, fragment_out);
1803 g_free (scheme_out);
1805 g_free (password_out);
1806 g_free (auth_params_out);
1810 g_free (fragment_out);
1821 const gchar *uri_string;
1824 } normalize_parse_tests[] =
1826 { NULL, "http://foo/path with spaces", G_URI_FLAGS_ENCODED,
1827 "http://foo/path%20with%20spaces", "/path%20with%20spaces", -1 },
1828 { NULL, "http://foo/path with spaces 2", G_URI_FLAGS_ENCODED_PATH,
1829 "http://foo/path%20with%20spaces%202", "/path%20with%20spaces%202", -1 },
1830 { NULL, "http://foo/%aa", G_URI_FLAGS_ENCODED,
1831 "http://foo/%AA", "/%AA", -1 },
1832 { NULL, "http://foo/p\xc3\xa4th/", G_URI_FLAGS_ENCODED | G_URI_FLAGS_PARSE_RELAXED,
1833 "http://foo/p%C3%A4th/", "/p%C3%A4th/", -1 },
1834 { NULL, "http://foo", G_URI_FLAGS_NONE,
1835 "http://foo", "", -1 },
1836 { NULL, "http://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1837 "http://foo/", "/", 80 },
1838 { NULL, "nothttp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1839 "nothttp://foo", "", -1 },
1840 { NULL, "http://foo:80", G_URI_FLAGS_NONE,
1841 "http://foo:80", "", 80 },
1842 { NULL, "http://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE,
1843 "http://foo/", "/", 80 },
1844 { NULL, "http://foo:8080", G_URI_FLAGS_SCHEME_NORMALIZE,
1845 "http://foo:8080/", "/", 8080 },
1846 { NULL, "https://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE,
1847 "https://foo/", "/", 443 },
1848 { NULL, "https://foo:943", G_URI_FLAGS_SCHEME_NORMALIZE,
1849 "https://foo:943/", "/", 943 },
1850 { NULL, "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1851 "ws://foo/", "/", 80 },
1852 { NULL, "wss://foo:443", G_URI_FLAGS_SCHEME_NORMALIZE,
1853 "wss://foo/", "/", 443 },
1854 { NULL, "ftp://foo", G_URI_FLAGS_NONE,
1855 "ftp://foo", "", -1 },
1856 { NULL, "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1857 "ftp://foo", "", 21 },
1858 { NULL, "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE,
1859 "ftp://foo", "", 21 },
1860 { NULL, "ftp://foo:2100", G_URI_FLAGS_SCHEME_NORMALIZE,
1861 "ftp://foo:2100", "", 2100 },
1862 { NULL, "nothttp://foo:80", G_URI_FLAGS_SCHEME_NORMALIZE,
1863 "nothttp://foo:80", "", 80 },
1864 { "http://foo", "//bar", G_URI_FLAGS_SCHEME_NORMALIZE,
1865 "http://bar/", "/", 80 },
1866 { "http://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE,
1867 "http://bar/", "/", 80 },
1868 { "nothttp://foo", "//bar:80", G_URI_FLAGS_SCHEME_NORMALIZE,
1869 "nothttp://bar:80", "", 80 },
1870 { "http://foo", "//bar", G_URI_FLAGS_NONE,
1871 "http://bar", "", -1 },
1872 { "ScHeMe://User:P%61ss@HOST.%63om:1234/path",
1873 "ScHeMe://User:P%61ss@HOST.%63om:1234/path/./from/../to%7d/item%2dobj?qu%65ry=something#fr%61gment",
1874 G_URI_FLAGS_SCHEME_NORMALIZE,
1875 "scheme://User:Pass@HOST.com:1234/path/to%7D/item-obj?query=something#fragment",
1876 "/path/to}/item-obj", 1234 },
1888 } normalize_split_tests[] =
1890 { "HTTP://foo", G_URI_FLAGS_ENCODED,
1892 { "HTTP://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1894 { "http://foo:80/", G_URI_FLAGS_SCHEME_NORMALIZE,
1896 { "http://foo:8080/bar", G_URI_FLAGS_SCHEME_NORMALIZE,
1897 "http", "/bar", 8080 },
1898 { "ws://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1900 { "https://foo", G_URI_FLAGS_ENCODED,
1902 { "https://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1903 "https", "/", 443 },
1904 { "https://foo:443/", G_URI_FLAGS_SCHEME_NORMALIZE,
1905 "https", "/", 443 },
1906 { "wss://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1908 { "ftp://foo", G_URI_FLAGS_ENCODED,
1910 { "ftp://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1912 { "ftp://foo:21", G_URI_FLAGS_SCHEME_NORMALIZE,
1914 { "scheme://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1916 { "socks://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1917 "socks", "", 1080 },
1918 { "socks4://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1919 "socks4", "", 1080 },
1920 { "socks4a://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1921 "socks4a", "", 1080 },
1922 { "socks5://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1923 "socks5", "", 1080 },
1924 { "socks5h://foo", G_URI_FLAGS_SCHEME_NORMALIZE,
1925 "socks5h", "", 1080 },
1932 const gchar *scheme;
1938 } normalize_join_tests[] =
1940 { G_URI_FLAGS_NONE, "http", "foo", -1, "",
1942 { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", -1, "",
1944 { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 80, "",
1946 { G_URI_FLAGS_SCHEME_NORMALIZE, "http", "foo", 8080, "",
1947 "http://foo:8080/" },
1948 { G_URI_FLAGS_NONE, "http", "foo", 80, "",
1950 { G_URI_FLAGS_SCHEME_NORMALIZE, "ws", "foo", 80, "",
1952 { G_URI_FLAGS_NONE, "https", "foo", -1, "",
1954 { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", -1, "",
1956 { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 443, "",
1958 { G_URI_FLAGS_SCHEME_NORMALIZE, "https", "foo", 943, "",
1959 "https://foo:943/" },
1960 { G_URI_FLAGS_NONE, "https", "foo", 443, "",
1961 "https://foo:443" },
1962 { G_URI_FLAGS_SCHEME_NORMALIZE, "wss", "foo", 443, "",
1964 { G_URI_FLAGS_NONE, "ftp", "foo", -1, "",
1966 { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", -1, "",
1968 { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 21, "",
1970 { G_URI_FLAGS_SCHEME_NORMALIZE, "ftp", "foo", 2020, "",
1972 { G_URI_FLAGS_NONE, "ftp", "foo", 21, "",
1974 { G_URI_FLAGS_SCHEME_NORMALIZE, "scheme", "foo", 80, "",
1975 "scheme://foo:80" },
1979 test_uri_normalize (void)
1986 for (i = 0; i < G_N_ELEMENTS (normalize_parse_tests); ++i)
1988 GUri *uri, *base = NULL;
1990 if (normalize_parse_tests[i].base)
1991 base = g_uri_parse (normalize_parse_tests[i].base, normalize_parse_tests[i].flags, NULL);
1993 uri = g_uri_parse_relative (base,
1994 normalize_parse_tests[i].uri,
1995 normalize_parse_tests[i].flags,
1997 uri_string = g_uri_to_string (uri);
1999 g_assert_nonnull (uri);
2000 g_assert_cmpstr (g_uri_get_path (uri), ==, normalize_parse_tests[i].path);
2001 g_assert_cmpint (g_uri_get_port (uri), ==, normalize_parse_tests[i].port);
2002 g_assert_cmpstr (uri_string, ==, normalize_parse_tests[i].uri_string);
2004 g_free (uri_string);
2010 for (i = 0; i < G_N_ELEMENTS (normalize_split_tests); ++i)
2014 /* Testing a codepath where scheme is NULL but internally we still normalize it. */
2015 g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags,
2016 NULL, NULL, NULL, &port, &path, NULL, NULL, NULL));
2017 g_assert_cmpstr (path, ==, normalize_split_tests[i].path);
2018 g_assert_cmpint (port, ==, normalize_split_tests[i].port);
2021 g_assert_true (g_uri_split (normalize_split_tests[i].uri, normalize_split_tests[i].flags,
2022 &scheme, NULL, NULL, &port, &path, NULL, NULL, NULL));
2023 g_assert_cmpstr (scheme, ==, normalize_split_tests[i].scheme);
2024 g_assert_cmpstr (path, ==, normalize_split_tests[i].path);
2025 g_assert_cmpint (port, ==, normalize_split_tests[i].port);
2030 for (i = 0; i < G_N_ELEMENTS (normalize_join_tests); ++i)
2032 uri_string = g_uri_join (normalize_join_tests[i].flags, normalize_join_tests[i].scheme, NULL,
2033 normalize_join_tests[i].host, normalize_join_tests[i].port,
2034 normalize_join_tests[i].path, NULL, NULL);
2035 g_assert_cmpstr (uri_string, ==, normalize_join_tests[i].uri);
2036 g_free (uri_string);
2044 g_test_init (&argc, &argv, NULL);
2046 g_test_add_func ("/uri/file-to-uri", run_file_to_uri_tests);
2047 g_test_add_func ("/uri/file-from-uri", run_file_from_uri_tests);
2048 g_test_add_func ("/uri/file-roundtrip", run_file_roundtrip_tests);
2049 g_test_add_func ("/uri/list", run_uri_list_tests);
2050 g_test_add_func ("/uri/unescape-string", test_uri_unescape_string);
2051 g_test_add_data_func ("/uri/unescape-bytes/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_unescape_bytes);
2052 g_test_add_data_func ("/uri/unescape-bytes/length", GINT_TO_POINTER (FALSE), test_uri_unescape_bytes);
2053 g_test_add_func ("/uri/unescape-segment", test_uri_unescape_segment);
2054 g_test_add_func ("/uri/escape-string", test_uri_escape_string);
2055 g_test_add_func ("/uri/escape-bytes", test_uri_escape_bytes);
2056 g_test_add_func ("/uri/scheme", test_uri_scheme);
2057 g_test_add_func ("/uri/parsing/absolute", test_uri_parsing_absolute);
2058 g_test_add_func ("/uri/parsing/relative", test_uri_parsing_relative);
2059 g_test_add_func ("/uri/build", test_uri_build);
2060 g_test_add_func ("/uri/split", test_uri_split);
2061 g_test_add_func ("/uri/is_valid", test_uri_is_valid);
2062 g_test_add_func ("/uri/to-string", test_uri_to_string);
2063 g_test_add_func ("/uri/join", test_uri_join);
2064 g_test_add_func ("/uri/join-split-round-trip", test_uri_join_split_round_trip);
2065 g_test_add_func ("/uri/normalize", test_uri_normalize);
2066 g_test_add_data_func ("/uri/iter-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_iter_params);
2067 g_test_add_data_func ("/uri/iter-params/length", GINT_TO_POINTER (FALSE), test_uri_iter_params);
2068 g_test_add_data_func ("/uri/parse-params/nul-terminated", GINT_TO_POINTER (TRUE), test_uri_parse_params);
2069 g_test_add_data_func ("/uri/parse-params/length", GINT_TO_POINTER (FALSE), test_uri_parse_params);
2071 return g_test_run ();