tests/get: use GProxyResolverDefault
[platform/upstream/libsoup.git] / tests / uri-parsing.c
1 #include <config.h>
2
3 #include <ctype.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8
9 #include "libsoup/soup-uri.h"
10
11 #include "test-utils.h"
12
13 static struct {
14         const char *uri_string, *result;
15         const SoupURI bits;
16 } abs_tests[] = {
17         { "foo:", "foo:",
18           { "foo", NULL, NULL, NULL, 0, "", NULL, NULL } },
19         { "file:/dev/null", "file:/dev/null",
20           { "file", NULL, NULL, NULL, 0, "/dev/null", NULL, NULL } },
21         { "file:///dev/null", "file:///dev/null",
22           { "file", NULL, NULL, "", 0, "/dev/null", NULL, NULL } },
23         { "ftp://user@host/path", "ftp://user@host/path",
24           { "ftp", "user", NULL, "host", 21, "/path", NULL, NULL } },
25         { "ftp://user@host:9999/path", "ftp://user@host:9999/path",
26           { "ftp", "user", NULL, "host", 9999, "/path", NULL, NULL } },
27         { "ftp://user:password@host/path", "ftp://user@host/path",
28           { "ftp", "user", "password", "host", 21, "/path", NULL, NULL } },
29         { "ftp://user:password@host:9999/path", "ftp://user@host:9999/path",
30           { "ftp", "user", "password", "host", 9999, "/path", NULL, NULL } },
31         { "ftp://user:password@host", "ftp://user@host",
32           { "ftp", "user", "password", "host", 21, "", NULL, NULL } },
33         { "http://us%65r@host", "http://user@host/",
34           { "http", "user", NULL, "host", 80, "/", NULL, NULL } },
35         { "http://us%40r@host", "http://us%40r@host/",
36           { "http", "us\x40r", NULL, "host", 80, "/", NULL, NULL } },
37         { "http://us%3ar@host", "http://us%3Ar@host/",
38           { "http", "us\x3ar", NULL, "host", 80, "/", NULL, NULL } },
39         { "http://us%2fr@host", "http://us%2Fr@host/",
40           { "http", "us\x2fr", NULL, "host", 80, "/", NULL, NULL } },
41         { "http://us%3fr@host", "http://us%3Fr@host/",
42           { "http", "us\x3fr", NULL, "host", 80, "/", NULL, NULL } },
43         { "http://host?query", "http://host/?query",
44           { "http", NULL, NULL, "host", 80, "/", "query", NULL } },
45         { "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue&param=value",
46           "http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue&param=value",
47           { "http", NULL, NULL, "host", 80, "/path", "query=http%3A%2F%2Fhost%2Fpath%3Fchildparam%3Dchildvalue&param=value", NULL } },
48         { "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",
49           "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",
50           { "http", NULL, NULL, "control-chars", 80, "/%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", NULL, NULL } },
51         { "http://space/%20",
52           "http://space/%20",
53           { "http", NULL, NULL, "space", 80, "/%20", NULL, NULL } },
54         { "http://delims/%3C%3E%23%25%22",
55           "http://delims/%3C%3E%23%25%22",
56           { "http", NULL, NULL, "delims", 80, "/%3C%3E%23%25%22", NULL, NULL } },
57         { "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60",
58           "http://unwise-chars/%7B%7D%7C%5C%5E%5B%5D%60",
59           { "http", NULL, NULL, "unwise-chars", 80, "/%7B%7D%7C%5C%5E%5B%5D%60", NULL, NULL } },
60
61         /* From RFC 2732 */
62         { "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html",
63           "http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/index.html",
64           { "http", NULL, NULL, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", 80, "/index.html", NULL, NULL } },
65         { "http://[1080:0:0:0:8:800:200C:417A]/index.html",
66           "http://[1080:0:0:0:8:800:200C:417A]/index.html",
67           { "http", NULL, NULL, "1080:0:0:0:8:800:200C:417A", 80, "/index.html", NULL, NULL } },
68         { "http://[3ffe:2a00:100:7031::1]",
69           "http://[3ffe:2a00:100:7031::1]/",
70           { "http", NULL, NULL, "3ffe:2a00:100:7031::1", 80, "/", NULL, NULL } },
71         { "http://[1080::8:800:200C:417A]/foo",
72           "http://[1080::8:800:200C:417A]/foo",
73           { "http", NULL, NULL, "1080::8:800:200C:417A", 80, "/foo", NULL, NULL } },
74         { "http://[::192.9.5.5]/ipng",
75           "http://[::192.9.5.5]/ipng",
76           { "http", NULL, NULL, "::192.9.5.5", 80, "/ipng", NULL, NULL } },
77         { "http://[::FFFF:129.144.52.38]:80/index.html",
78           "http://[::FFFF:129.144.52.38]/index.html",
79           { "http", NULL, NULL, "::FFFF:129.144.52.38", 80, "/index.html", NULL, NULL } },
80         { "http://[2010:836B:4179::836B:4179]",
81           "http://[2010:836B:4179::836B:4179]/",
82           { "http", NULL, NULL, "2010:836B:4179::836B:4179", 80, "/", NULL, NULL } },
83
84         /* Try to recover certain kinds of invalid URIs */
85         { "http://host/path with spaces",
86           "http://host/path%20with%20spaces",
87           { "http", NULL, NULL, "host", 80, "/path%20with%20spaces", NULL, NULL } },
88         { "  http://host/path", "http://host/path",
89           { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } },
90         { "http://host/path  ", "http://host/path",
91           { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } },
92         { "http://host  ", "http://host/",
93           { "http", NULL, NULL, "host", 80, "/", NULL, NULL } },
94         { "http://host:999  ", "http://host:999/",
95           { "http", NULL, NULL, "host", 999, "/", NULL, NULL } },
96         { "http://host/pa\nth", "http://host/path",
97           { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } },
98         { "http:\r\n//host/path", "http://host/path",
99           { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } },
100         { "http://\thost/path", "http://host/path",
101           { "http", NULL, NULL, "host", 80, "/path", NULL, NULL } },
102
103         /* Bug 594405; 0-length is different from not-present */
104         { "http://host/path?", "http://host/path?",
105           { "http", NULL, NULL, "host", 80, "/path", "", NULL } },
106         { "http://host/path#", "http://host/path#",
107           { "http", NULL, NULL, "host", 80, "/path", NULL, "" } },
108
109         /* Bug 590524; ignore badly-%-encoding */
110         { "http://host/path%", "http://host/path%",
111           { "http", NULL, NULL, "host", 80, "/path%", NULL, NULL } },
112         { "http://h%ost/path", "http://h%25ost/path",
113           { "http", NULL, NULL, "h%ost", 80, "/path", NULL, NULL } },
114         { "http://host/path%%", "http://host/path%%",
115           { "http", NULL, NULL, "host", 80, "/path%%", NULL, NULL } },
116         { "http://host/path%%%", "http://host/path%%%",
117           { "http", NULL, NULL, "host", 80, "/path%%%", NULL, NULL } },
118         { "http://host/path%/x/", "http://host/path%/x/",
119           { "http", NULL, NULL, "host", 80, "/path%/x/", NULL, NULL } },
120         { "http://host/path%0x/", "http://host/path%0x/",
121           { "http", NULL, NULL, "host", 80, "/path%0x/", NULL, NULL } },
122         { "http://host/path%ax", "http://host/path%ax",
123           { "http", NULL, NULL, "host", 80, "/path%ax", NULL, NULL } },
124
125         /* Bug 662806; %-encode non-ASCII characters */
126         { "http://host/p\xc3\xa4th/", "http://host/p%C3%A4th/",
127           { "http", NULL, NULL, "host", 80, "/p%C3%A4th/", NULL, NULL } },
128
129         { "HTTP:////////////////", "http:////////////////",
130           { "http", NULL, NULL, "", 80, "//////////////", NULL, NULL } },
131 };
132 static int num_abs_tests = G_N_ELEMENTS(abs_tests);
133
134 /* From RFC 3986. */
135 static const char *base = "http://a/b/c/d;p?q";
136 static struct {
137         const char *uri_string, *result;
138         const SoupURI bits;
139 } rel_tests[] = {
140         { "g:h", "g:h",
141           { "g", NULL, NULL, NULL, 0, "h", NULL, NULL } },
142         { "g", "http://a/b/c/g",
143           { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, NULL } },
144         { "./g", "http://a/b/c/g",
145           { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, NULL } },
146         { "g/", "http://a/b/c/g/",
147           { "http", NULL, NULL, "a", 80, "/b/c/g/", NULL, NULL } },
148         { "/g", "http://a/g",
149           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
150         { "//g", "http://g/",
151           { "http", NULL, NULL, "g", 80, "/", NULL, NULL } },
152         { "?y", "http://a/b/c/d;p?y",
153           { "http", NULL, NULL, "a", 80, "/b/c/d;p", "y", NULL } },
154         { "g?y", "http://a/b/c/g?y",
155           { "http", NULL, NULL, "a", 80, "/b/c/g", "y", NULL } },
156         { "#s", "http://a/b/c/d;p?q#s",
157           { "http", NULL, NULL, "a", 80, "/b/c/d;p", "q", "s" } },
158         { "g#s", "http://a/b/c/g#s",
159           { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s" } },
160         { "g?y#s", "http://a/b/c/g?y#s",
161           { "http", NULL, NULL, "a", 80, "/b/c/g", "y", "s" } },
162         { ";x", "http://a/b/c/;x",
163           { "http", NULL, NULL, "a", 80, "/b/c/;x", NULL, NULL } },
164         { "g;x", "http://a/b/c/g;x",
165           { "http", NULL, NULL, "a", 80, "/b/c/g;x", NULL, NULL } },
166         { "g;x?y#s", "http://a/b/c/g;x?y#s",
167           { "http", NULL, NULL, "a", 80, "/b/c/g;x", "y", "s" } },
168         { ".", "http://a/b/c/",
169           { "http", NULL, NULL, "a", 80, "/b/c/", NULL, NULL } },
170         { "./", "http://a/b/c/",
171           { "http", NULL, NULL, "a", 80, "/b/c/", NULL, NULL } },
172         { "..", "http://a/b/",
173           { "http", NULL, NULL, "a", 80, "/b/", NULL, NULL } },
174         { "../", "http://a/b/",
175           { "http", NULL, NULL, "a", 80, "/b/", NULL, NULL } },
176         { "../g", "http://a/b/g",
177           { "http", NULL, NULL, "a", 80, "/b/g", NULL, NULL } },
178         { "../..", "http://a/",
179           { "http", NULL, NULL, "a", 80, "/", NULL, NULL } },
180         { "../../", "http://a/",
181           { "http", NULL, NULL, "a", 80, "/", NULL, NULL } },
182         { "../../g", "http://a/g",
183           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
184         { "", "http://a/b/c/d;p?q",
185           { "http", NULL, NULL, "a", 80, "/b/c/d;p", "q", NULL } },
186         { "../../../g", "http://a/g",
187           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
188         { "../../../../g", "http://a/g",
189           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
190         { "/./g", "http://a/g",
191           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
192         { "/../g", "http://a/g",
193           { "http", NULL, NULL, "a", 80, "/g", NULL, NULL } },
194         { "g.", "http://a/b/c/g.",
195           { "http", NULL, NULL, "a", 80, "/b/c/g.", NULL, NULL } },
196         { ".g", "http://a/b/c/.g",
197           { "http", NULL, NULL, "a", 80, "/b/c/.g", NULL, NULL } },
198         { "g..", "http://a/b/c/g..",
199           { "http", NULL, NULL, "a", 80, "/b/c/g..", NULL, NULL } },
200         { "..g", "http://a/b/c/..g",
201           { "http", NULL, NULL, "a", 80, "/b/c/..g", NULL, NULL } },
202         { "./../g", "http://a/b/g",
203           { "http", NULL, NULL, "a", 80, "/b/g", NULL, NULL } },
204         { "./g/.", "http://a/b/c/g/",
205           { "http", NULL, NULL, "a", 80, "/b/c/g/", NULL, NULL } },
206         { "g/./h", "http://a/b/c/g/h",
207           { "http", NULL, NULL, "a", 80, "/b/c/g/h", NULL, NULL } },
208         { "g/../h", "http://a/b/c/h",
209           { "http", NULL, NULL, "a", 80, "/b/c/h", NULL, NULL } },
210         { "g;x=1/./y", "http://a/b/c/g;x=1/y",
211           { "http", NULL, NULL, "a", 80, "/b/c/g;x=1/y", NULL, NULL } },
212         { "g;x=1/../y", "http://a/b/c/y",
213           { "http", NULL, NULL, "a", 80, "/b/c/y", NULL, NULL } },
214         { "g?y/./x", "http://a/b/c/g?y/./x",
215           { "http", NULL, NULL, "a", 80, "/b/c/g", "y/./x", NULL } },
216         { "g?y/../x", "http://a/b/c/g?y/../x",
217           { "http", NULL, NULL, "a", 80, "/b/c/g", "y/../x", NULL } },
218         { "g#s/./x", "http://a/b/c/g#s/./x",
219           { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s/./x" } },
220         { "g#s/../x", "http://a/b/c/g#s/../x",
221           { "http", NULL, NULL, "a", 80, "/b/c/g", NULL, "s/../x" } },
222
223         /* RFC 3986 notes that some old parsers will parse this as
224          * a relative URL ("http://a/b/c/g"), but it should be
225          * interpreted as absolute. libsoup should parse it
226          * correctly as being absolute, but then reject it since it's
227          * an http URL with no host.
228          */
229         { "http:g", NULL, { NULL } }
230 };
231 static int num_rel_tests = G_N_ELEMENTS(rel_tests);
232
233 static struct {
234         const char *one, *two;
235 } eq_tests[] = {
236         { "example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7Bfoo%7D" },
237         { "http://example.com", "http://example.com/" },
238         /* From RFC 2616 */
239         { "http://abc.com:80/~smith/home.html", "http://abc.com:80/~smith/home.html" },
240         { "http://abc.com:80/~smith/home.html", "http://ABC.com/%7Esmith/home.html" },
241         { "http://abc.com:80/~smith/home.html", "http://ABC.com:/%7esmith/home.html" },
242 };
243 static int num_eq_tests = G_N_ELEMENTS(eq_tests);
244
245 #define test_cmpstr(a, b) _test_cmpstr (#a, #b, a, b)
246
247 static gboolean
248 _test_cmpstr (const char *got_desc,
249               const char *exp_desc,
250               const char *got,
251               const char *expected)
252 {
253         if (got == expected)
254                 return TRUE;
255
256         if (got == NULL) {
257                 debug_printf (1, "ERR\n  %s = NULL, expected %s = \"%s\"\n",
258                               got_desc, exp_desc, expected);
259                 return FALSE;
260         }
261
262         if (expected == NULL) {
263                 debug_printf (1, "ERR\n  %s = \"%s\", expected %s = NULL\n",
264                               got_desc, got, exp_desc);
265                 return FALSE;
266         }
267
268         if (strcmp (got, expected) != 0) {
269                 debug_printf (1, "ERR\n  %s = \"%s\", expected %s = \"%s\"\n",
270                               got_desc, got, exp_desc, expected);
271                 return FALSE;
272         }
273
274         return TRUE;
275 }
276
277 static gboolean
278 do_uri (SoupURI *base_uri, const char *base_str,
279         const char *in_uri, const char *out_uri,
280         const SoupURI *bits)
281 {
282         SoupURI *uri;
283         char *uri_string;
284
285         if (base_uri) {
286                 debug_printf (1, "<%s> + <%s> = <%s>? ", base_str, in_uri,
287                               out_uri ? out_uri : "ERR");
288                 uri = soup_uri_new_with_base (base_uri, in_uri);
289         } else {
290                 debug_printf (1, "<%s> => <%s>? ", in_uri,
291                               out_uri ? out_uri : "ERR");
292                 uri = soup_uri_new (in_uri);
293         }
294
295         if (!uri) {
296                 if (out_uri) {
297                         debug_printf (1, "ERR\n  Could not parse %s\n", in_uri);
298                         return FALSE;
299                 } else {
300                         debug_printf (1, "OK\n");
301                         return TRUE;
302                 }
303         }
304
305         if (bits != NULL) {
306                 gboolean failed = FALSE;
307
308                 if (!test_cmpstr (uri->scheme, bits->scheme))
309                         failed = TRUE;
310
311                 if (!test_cmpstr (uri->user, bits->user))
312                         failed = TRUE;
313
314                 if (!test_cmpstr (uri->password, bits->password))
315                         failed = TRUE;
316
317                 if (!test_cmpstr (uri->host, bits->host))
318                         failed = TRUE;
319
320                 if (uri->port != bits->port) {
321                         debug_printf (1, "ERR\n  port was %u, expected %u\n",
322                                       uri->port, bits->port);
323                         failed = TRUE;
324                 }
325
326                 if (!test_cmpstr (uri->path, bits->path))
327                         failed = TRUE;
328
329                 if (!test_cmpstr (uri->query, bits->query))
330                         failed = TRUE;
331
332                 if (!test_cmpstr (uri->fragment, bits->fragment))
333                         failed = TRUE;
334
335                 if (failed)
336                         return FALSE;
337         }
338
339         uri_string = soup_uri_to_string (uri, FALSE);
340         soup_uri_free (uri);
341
342         if (!out_uri) {
343                 debug_printf (1, "ERR\n  Got %s\n", uri_string);
344                 return FALSE;
345         }
346
347         if (strcmp (uri_string, out_uri) != 0) {
348                 debug_printf (1, "NO\n  Unparses to <%s>\n", uri_string);
349                 g_free (uri_string);
350                 return FALSE;
351         }
352         g_free (uri_string);
353
354         debug_printf (1, "OK\n");
355         return TRUE;
356 }
357
358 static void
359 do_soup_uri_null_tests (void)
360 {
361         SoupURI *uri, *uri2;
362         char *uri_string;
363
364         debug_printf (1, "\nsoup_uri_new (NULL)\n");
365         uri = soup_uri_new (NULL);
366         if (SOUP_URI_IS_VALID (uri) || SOUP_URI_VALID_FOR_HTTP (uri)) {
367                 debug_printf (1, "  ERROR: soup_uri_new(NULL) returns valid URI?\n");
368                 errors++;
369         }
370
371         /* This implicitly also verifies that none of these methods g_warn */
372         if (soup_uri_get_scheme (uri) ||
373             soup_uri_get_user (uri) ||
374             soup_uri_get_password (uri) ||
375             soup_uri_get_host (uri) ||
376             soup_uri_get_port (uri) ||
377             soup_uri_get_path (uri) ||
378             soup_uri_get_query (uri) ||
379             soup_uri_get_fragment (uri)) {
380                 debug_printf (1, "  ERROR: soup_uri_new(NULL) returns non-empty URI?\n");
381                 errors++;
382         }
383
384         expect_warning = TRUE;
385         uri2 = soup_uri_new_with_base (uri, "/path");
386         if (uri2 || expect_warning) {
387                 debug_printf (1, "  ERROR: soup_uri_new_with_base didn't fail on NULL URI?\n");
388                 errors++;
389                 expect_warning = FALSE;
390         }
391
392         expect_warning = TRUE;
393         uri_string = soup_uri_to_string (uri, FALSE);
394         if (expect_warning) {
395                 debug_printf (1, "  ERROR: soup_uri_to_string didn't fail on NULL URI?\n");
396                 errors++;
397                 expect_warning = FALSE;
398         } else if (*uri_string) {
399                 debug_printf (1, "  ERROR: soup_uri_to_string on NULL URI returned '%s'\n",
400                               uri_string);
401                 errors++;
402         }
403         g_free (uri_string);
404
405         soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
406         if (SOUP_URI_IS_VALID (uri) || SOUP_URI_VALID_FOR_HTTP (uri)) {
407                 debug_printf (1, "  ERROR: setting scheme on NULL URI makes it valid?\n");
408                 errors++;
409         }
410
411         expect_warning = TRUE;
412         uri_string = soup_uri_to_string (uri, FALSE);
413         if (expect_warning) {
414                 debug_printf (1, "  ERROR: soup_uri_to_string didn't fail on scheme-only URI?\n");
415                 errors++;
416                 expect_warning = FALSE;
417         } else if (strcmp (uri_string, "http:") != 0) {
418                 debug_printf (1, "  ERROR: soup_uri_to_string returned '%s' instead of 'http:'\n",
419                               uri_string);
420                 errors++;
421         }
422         g_free (uri_string);
423
424         soup_uri_set_host (uri, "localhost");
425         if (SOUP_URI_IS_VALID (uri)) {
426                 debug_printf (1, "  ERROR: setting scheme+host on NULL URI makes it valid?\n");
427                 errors++;
428         }
429         if (SOUP_URI_VALID_FOR_HTTP (uri)) {
430                 debug_printf (1, "  ERROR: setting scheme+host on NULL URI makes it valid for http?\n");
431                 errors++;
432         }
433
434         expect_warning = TRUE;
435         uri_string = soup_uri_to_string (uri, FALSE);
436         if (expect_warning) {
437                 debug_printf (1, "  ERROR: soup_uri_to_string didn't fail on scheme+host URI?\n");
438                 errors++;
439                 expect_warning = FALSE;
440         } else if (strcmp (uri_string, "http://localhost/") != 0) {
441                 debug_printf (1, "  ERROR: soup_uri_to_string with NULL path returned '%s' instead of 'http://localhost/'\n",
442                               uri_string);
443                 errors++;
444         }
445         g_free (uri_string);
446
447         expect_warning = TRUE;
448         uri2 = soup_uri_new_with_base (uri, "/path");
449         if (expect_warning) {
450                 debug_printf (1, "  ERROR: soup_uri_new_with_base didn't warn on NULL+scheme URI?\n");
451                 errors++;
452                 expect_warning = FALSE;
453         } else if (!uri2) {
454                 debug_printf (1, "  ERROR: soup_uri_new_with_base didn't fix path on NULL+scheme URI\n");
455                 errors++;
456         }
457
458         if (uri2) {
459                 uri_string = soup_uri_to_string (uri2, FALSE);
460                 if (!uri_string) {
461                         debug_printf (1, "  ERROR: soup_uri_to_string failed on uri2?\n");
462                         errors++;
463                 } else if (strcmp (uri_string, "http://localhost/path") != 0) {
464                         debug_printf (1, "  ERROR: soup_uri_to_string returned '%s' instead of 'http://localhost/path'\n",
465                                       uri_string);
466                         errors++;
467                 }
468                 g_free (uri_string);
469                 soup_uri_free (uri2);
470         }
471
472         expect_warning = TRUE;
473         soup_uri_set_path (uri, NULL);
474         if (expect_warning) {
475                 debug_printf (1, "  ERROR: setting path to NULL doesn't warn\n");
476                 errors++;
477                 expect_warning = FALSE;
478         }
479         if (!uri->path || *uri->path) {
480                 debug_printf (1, "  ERROR: setting path to NULL != \"\"\n");
481                 errors++;
482                 soup_uri_set_path (uri, "");
483         }
484
485         uri_string = soup_uri_to_string (uri, FALSE);
486         if (!uri_string) {
487                 debug_printf (1, "  ERROR: soup_uri_to_string failed on complete URI?\n");
488                 errors++;
489         } else if (strcmp (uri_string, "http://localhost/") != 0) {
490                 debug_printf (1, "  ERROR: soup_uri_to_string with empty path returned '%s' instead of 'http://localhost/'\n",
491                               uri_string);
492                 errors++;
493         }
494         g_free (uri_string);
495
496         if (!SOUP_URI_IS_VALID (uri)) {
497                 debug_printf (1, "  ERROR: setting scheme+path on NULL URI doesn't make it valid?\n");
498                 errors++;
499         }
500         if (!SOUP_URI_VALID_FOR_HTTP (uri)) {
501                 debug_printf (1, "  ERROR: setting scheme+host+path on NULL URI doesn't make it valid for http?\n");
502                 errors++;
503         }
504
505         soup_uri_free (uri);
506 }
507
508 int
509 main (int argc, char **argv)
510 {
511         SoupURI *base_uri, *uri1, *uri2;
512         char *uri_string;
513         int i;
514
515         test_init (argc, argv, NULL);
516
517         debug_printf (1, "Absolute URI parsing\n");
518         for (i = 0; i < num_abs_tests; i++) {
519                 if (!do_uri (NULL, NULL, abs_tests[i].uri_string,
520                              abs_tests[i].result, &abs_tests[i].bits))
521                         errors++;
522         }
523
524         debug_printf (1, "\nRelative URI parsing\n");
525         base_uri = soup_uri_new (base);
526         if (!base_uri) {
527                 fprintf (stderr, "Could not parse %s!\n", base);
528                 exit (1);
529         }
530
531         uri_string = soup_uri_to_string (base_uri, FALSE);
532         if (strcmp (uri_string, base) != 0) {
533                 fprintf (stderr, "URI <%s> unparses to <%s>\n",
534                          base, uri_string);
535                 errors++;
536         }
537         g_free (uri_string);
538
539         for (i = 0; i < num_rel_tests; i++) {
540                 if (!do_uri (base_uri, base, rel_tests[i].uri_string,
541                              rel_tests[i].result, &rel_tests[i].bits))
542                         errors++;
543         }
544         soup_uri_free (base_uri);
545
546         debug_printf (1, "\nURI equality testing\n");
547         for (i = 0; i < num_eq_tests; i++) {
548                 uri1 = soup_uri_new (eq_tests[i].one);
549                 uri2 = soup_uri_new (eq_tests[i].two);
550                 debug_printf (1, "<%s> == <%s>? ", eq_tests[i].one, eq_tests[i].two);
551                 if (soup_uri_equal (uri1, uri2))
552                         debug_printf (1, "OK\n");
553                 else {
554                         debug_printf (1, "NO\n");
555                         debug_printf (1, "%s : %s : %s\n%s : %s : %s\n",
556                                       uri1->scheme, uri1->host, uri1->path,
557                                       uri2->scheme, uri2->host, uri2->path);
558                         errors++;
559                 }
560                 soup_uri_free (uri1);
561                 soup_uri_free (uri2);
562         }
563
564         do_soup_uri_null_tests ();
565
566         test_cleanup ();
567         return errors != 0;
568 }