#include <config.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "libsoup/soup-uri.h"
gboolean debug = FALSE;
static void
dprintf (const char *format, ...)
{
va_list args;
if (!debug)
return;
va_start (args, format);
vprintf (format, args);
va_end (args);
}
struct {
const char *uri_string, *result;
} abs_tests[] = {
{ "foo:", "foo:" },
{ "file:/dev/null", "file:/dev/null" },
{ "file:///dev/null", "file:///dev/null" },
{ "ftp://user@host/path", "ftp://user@host/path" },
{ "ftp://user@host:9999/path", "ftp://user@host:9999/path" },
{ "ftp://user:password@host/path", "ftp://user@host/path" },
{ "ftp://user:password@host:9999/path", "ftp://user@host:9999/path" },
{ "http://us%65r@host", "http://user@host" },
{ "http://us%40r@host", "http://us%40r@host" },
{ "http://us%3ar@host", "http://us%3ar@host" },
{ "http://us%2fr@host", "http://us%2fr@host" },
{ "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",
"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"},
{ "http://space/%20",
"http://space/%20" },
{ "http://delims/%3c%3e%23%25%22",
"http://delims/%3c%3e%23%25%22" },
{ "http://unwise-chars/%7b%7d%7c%5c%5e%5b%5d%60",
"http://unwise-chars/%7b%7d%7c%5c%5e%5b%5d%60" }
};
int num_abs_tests = G_N_ELEMENTS(abs_tests);
/* From RFC 2396. */
const char *base = "http://a/b/c/d;p?q";
struct {
const char *uri_string, *result;
} rel_tests[] = {
{ "g:h", "g:h" },
{ "g", "http://a/b/c/g" },
{ "./g", "http://a/b/c/g" },
{ "g/", "http://a/b/c/g/" },
{ "/g", "http://a/g" },
{ "//g", "http://g" },
{ "?y", "http://a/b/c/?y" },
{ "g?y", "http://a/b/c/g?y" },
{ "#s", "http://a/b/c/d;p?q#s" },
{ "g#s", "http://a/b/c/g#s" },
{ "g?y#s", "http://a/b/c/g?y#s" },
{ ";x", "http://a/b/c/;x" },
{ "g;x", "http://a/b/c/g;x" },
{ "g;x?y#s", "http://a/b/c/g;x?y#s" },
{ ".", "http://a/b/c/" },
{ "./", "http://a/b/c/" },
{ "..", "http://a/b/" },
{ "../", "http://a/b/" },
{ "../g", "http://a/b/g" },
{ "../..", "http://a/" },
{ "../../", "http://a/" },
{ "../../g", "http://a/g" },
{ "", "http://a/b/c/d;p?q" },
{ "../../../g", "http://a/../g" },
{ "../../../../g", "http://a/../../g" },
{ "/./g", "http://a/./g" },
{ "/../g", "http://a/../g" },
{ "g.", "http://a/b/c/g." },
{ ".g", "http://a/b/c/.g" },
{ "g..", "http://a/b/c/g.." },
{ "..g", "http://a/b/c/..g" },
{ "./../g", "http://a/b/g" },
{ "./g/.", "http://a/b/c/g/" },
{ "g/./h", "http://a/b/c/g/h" },
{ "g/../h", "http://a/b/c/h" },
{ "g;x=1/./y", "http://a/b/c/g;x=1/y" },
{ "g;x=1/../y", "http://a/b/c/y" },
{ "g?y/./x", "http://a/b/c/g?y/./x" },
{ "g?y/../x", "http://a/b/c/g?y/../x" },
{ "g#s/./x", "http://a/b/c/g#s/./x" },
{ "g#s/../x", "http://a/b/c/g#s/../x" },
/* RFC 2396 notes that some old parsers will parse this as
* a relative URL ("http://a/b/c/g"), but it should be
* interpreted as absolute. libsoup should parse it
* correctly as being absolute, but then reject it since it's
* an http URL with no host.
*/
{ "http:g", NULL }
};
int num_rel_tests = G_N_ELEMENTS(rel_tests);
static gboolean
do_uri (SoupUri *base_uri, const char *base_str,
const char *in_uri, const char *out_uri)
{
SoupUri *uri;
char *uri_string;
if (base_uri) {
dprintf ("<%s> + <%s> = <%s>? ", base_str, in_uri,
out_uri ? out_uri : "ERR");
uri = soup_uri_new_with_base (base_uri, in_uri);
} else {
dprintf ("<%s> => <%s>? ", in_uri,
out_uri ? out_uri : "ERR");
uri = soup_uri_new (in_uri);
}
if (!uri) {
if (out_uri) {
dprintf ("ERR\n Could not parse %s\n", in_uri);
return FALSE;
} else {
dprintf ("OK\n");
return TRUE;
}
}
uri_string = soup_uri_to_string (uri, FALSE);
soup_uri_free (uri);
if (!out_uri) {
dprintf ("ERR\n Got %s\n", uri_string);
return FALSE;
}
if (strcmp (uri_string, out_uri) != 0) {
dprintf ("NO\n Unparses to <%s>\n", uri_string);
g_free (uri_string);
return FALSE;
}
g_free (uri_string);
dprintf ("OK\n");
return TRUE;
}
int
main (int argc, char **argv)
{
SoupUri *base_uri;
char *uri_string;
int i, errs = 0, opt;
while ((opt = getopt (argc, argv, "d")) != -1) {
switch (opt) {
case 'd':
debug = TRUE;
break;
default:
fprintf (stderr, "Usage: %s [-d]\n", argv[0]);
return 1;
}
}
dprintf ("Absolute URI parsing\n");
for (i = 0; i < num_abs_tests; i++) {
if (!do_uri (NULL, NULL, abs_tests[i].uri_string,
abs_tests[i].result))
errs++;
}
dprintf ("\nRelative URI parsing\n");
base_uri = soup_uri_new (base);
if (!base_uri) {
fprintf (stderr, "Could not parse %s!\n", base);
exit (1);
}
uri_string = soup_uri_to_string (base_uri, FALSE);
if (strcmp (uri_string, base) != 0) {
fprintf (stderr, "URI <%s> unparses to <%s>\n",
base, uri_string);
errs++;
}
g_free (uri_string);
for (i = 0; i < num_rel_tests; i++) {
if (!do_uri (base_uri, base, rel_tests[i].uri_string,
rel_tests[i].result))
errs++;
}
soup_uri_free (base_uri);
dprintf ("\n");
if (errs) {
printf ("uri-parsing: %d error(s). Run with '-d' for details\n",
errs);
} else
printf ("uri-parsing: OK\n");
return errs;
}
syntax highlighted by Code2HTML, v. 0.9.1