/* Parse various URIs
* Copyright (C) 2001 David Helder
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <glib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gnet.h>
static int failed = 0;
#define TEST(N, S, C) do { \
if (C) { /*g_print ("%d %s: PASS\n", (N), (S)); */ } \
else { g_print ("%d %s: FAIL\n", (N), (S)); failed = 1; } \
} while (0)
struct URITest
{
gchar* str;
gchar* pretty;
struct
{
gchar* scheme;
gchar* userinfo;
gchar* hostname;
gint port;
gchar* path;
gchar* query;
gchar* fragment;
} uri;
};
struct URITest tests[] =
{
/* VALID URIS. PARSING AND PRINTING OF THESE SHOULD NOT CHANGE */
/* scheme/path */
{ "scheme:", NULL,
{"scheme", NULL, NULL, 0, NULL, NULL, NULL}},
{ "scheme:path", NULL,
{"scheme", NULL, NULL, 0, "path", NULL, NULL}},
{ "path", NULL,
{NULL, NULL, NULL, 0, "path", NULL, NULL}},
{ "/path", NULL,
{NULL, NULL, NULL, 0, "/path", NULL, NULL}},
/* hostname/port */
{ "scheme://hostname/path", NULL,
{"scheme", NULL, "hostname", 0, "/path", NULL, NULL}},
{ "scheme://hostname:123/path", NULL,
{"scheme", NULL, "hostname", 123, "/path", NULL, NULL}},
/* ipv6 hostname/port */
{ "scheme://[01:23:45:67:89:ab:cd:ef]/path", NULL,
{"scheme", NULL, "01:23:45:67:89:ab:cd:ef", 0, "/path", NULL, NULL}},
{ "scheme://[01:23:45:67:89:ab:cd:ef]:123/path", NULL,
{"scheme", NULL, "01:23:45:67:89:ab:cd:ef", 123, "/path", NULL, NULL}},
/* query/fragment */
{ "path?query", NULL,
{NULL, NULL, NULL, 0, "path", "query", NULL}},
{ "path?query#fragment", NULL,
{NULL, NULL, NULL, 0, "path", "query", "fragment"}},
{ "scheme:path?query#fragment", NULL,
{"scheme", NULL, NULL, 0, "path", "query", "fragment"}},
/* full */
{ "scheme://hostname:123/path?query#fragment", NULL,
{"scheme", NULL, "hostname", 123, "/path", "query", "fragment"}},
/* user/pass */
{ "scheme://userinfo@hostname", NULL,
{"scheme", "userinfo", "hostname", 0, NULL, NULL, NULL }},
{ "scheme://userinfo@hostname:123/path?query#fragment", NULL,
{"scheme", "userinfo", "hostname", 123, "/path", "query", "fragment"}},
{ "scheme://user:pass@hostname", NULL,
{"scheme", "user:pass", "hostname", 0, NULL, NULL, NULL}},
{ "scheme://user:pass@hostname:123/path?query#fragment", NULL,
{"scheme", "user:pass", "hostname", 123, "/path", "query", "fragment"}},
/* FUNNY URIS. PARSING AND PRINTING OF THESE MAY CHANGE */
{ "scheme://hostname:123path?query#fragment",
"scheme://hostname:123/path?query#fragment", /* PRETTY */
{"scheme", NULL, "hostname", 123, "path", "query", "fragment"}},
{ "scheme:hostname:123/path?query#fragment", NULL,
{"scheme", NULL, NULL, 0, "hostname:123/path", "query", "fragment"}},
{ "scheme://:pass@hostname:123/path?query#fragment", NULL,
{"scheme", ":pass", "hostname", 123, "/path", "query", "fragment"}},
/* IPv6 hostname without brackets */
{ "scheme://01:23:45:67:89:ab:cd:ef:123/path",
"scheme://01:23/:45:67:89:ab:cd:ef:123/path", /* PRETTY */
{"scheme", NULL, "01", 23, ":45:67:89:ab:cd:ef:123/path", NULL, NULL}},
/* Brackets that don't close - hostname will be everything */
{ "scheme://[01:23:45:67:89:ab:cd:ef:123/path",
"scheme://[01:23:45:67:89:ab:cd:ef:123/path]",
{"scheme", NULL, "01:23:45:67:89:ab:cd:ef:123/path", 0, NULL, NULL, NULL}},
/* Skip initial white space */
{ " \f\n\r\t\vscheme:", "scheme:",
{"scheme", NULL, NULL, 0, NULL, NULL, NULL}},
{ " \f\n\r\t\vpath", "path",
{NULL, NULL, NULL, 0, "path", NULL, NULL}},
{ NULL, NULL, {NULL, NULL, NULL, 0, NULL, NULL, NULL} }
};
struct EscapeTest
{
gchar* escaped;
gchar* unescaped;
gchar* escaped2;
};
struct EscapeTest escape_tests[] =
{
{ "http://userinfo@www.example.com:80/path?query#fragment",
"http://userinfo@www.example.com:80/path?query#fragment" , NULL},
{ "http://userinfo@www.example.com:80/~path?query#fragment",
"http://userinfo@www.example.com:80/~path?query#fragment" , NULL},
{ "http://%5euser%5einfo%5e@www.example.com:80/~%5epa%5eth%5e?%5equ%5eery%5e#%5efra%5egment%5e",
"http://^user^info^@www.example.com:80/~^pa^th^?^qu^ery^#^fra^gment^" , NULL},
{ "http://%5e%5e%5euser%5e%5e%5einfo%5e%5e%5e@www.example.com:80/~%5e%5e%5epa%5e%5e%5eth%5e%5e%5e?%5e%5e%5equ%5e%5e%5eery%5e%5e%5e#%5e%5e%5efra%5e%5e%5egment%5e%5e%5e",
"http://^^^user^^^info^^^@www.example.com:80/~^^^pa^^^th^^^?^^^qu^^^ery^^^#^^^fra^^^gment^^^" , NULL},
{ "http://user%40info@www.example.com:80/path?query#fragment",
"http://user@info@www.example.com:80/path?query#fragment" , NULL},
{ "http://user%40info@www.example.com:80/path?query#fragment",
"http://user@info@www.example.com:80/path?query#fragment" , NULL},
{ "http://www.example.com/pa%th", "http://www.example.com/pa%th",
"http://www.example.com/pa%25th"},
{ "http://www.example.com/%e9%e9.html",
"http://www.example.com/\xe9\xe9.html", NULL },
{ NULL, NULL , NULL}
};
#define SAFESTRCMP(A,B) (((A)&&(B))?(strcmp((A),(B))):((A)||(B)))
int
main (int argc, char* argv[])
{
int i;
gnet_init ();
/* Empty string is an error */
if (gnet_uri_new("") != NULL)
{
g_print ("empty string is error: FAIL\n");
failed = 1;
}
/* String of whitespace is an error */
if (gnet_uri_new(" \n\t\r") != NULL)
{
g_print ("whitespace string is error: FAIL\n");
failed = 1;
}
for (i = 0; tests[i].str; ++i)
{
GURI* uri;
gchar* pretty;
gchar* escape;
gchar* unescape;
uri = gnet_uri_new (tests[i].str);
TEST (i, "gnet_uri_new", uri != NULL);
if (!uri) continue;
pretty = gnet_uri_get_string (uri);
TEST (i, "gnet_uri_get_string", pretty);
if (!pretty) continue;
if (tests[i].pretty)
TEST (i, "pretty1", !strcmp (pretty, tests[i].pretty));
else
TEST (i, "pretty2", !strcmp (pretty, tests[i].str));
TEST (i, "scheme", !SAFESTRCMP(uri->scheme, tests[i].uri.scheme));
TEST (i, "userinfo", !SAFESTRCMP(uri->userinfo, tests[i].uri.userinfo));
TEST (i, "hostname", !SAFESTRCMP(uri->hostname, tests[i].uri.hostname));
TEST (i, "port", uri->port == tests[i].uri.port);
TEST (i, "path", !SAFESTRCMP(uri->path, tests[i].uri.path));
TEST (i, "query", !SAFESTRCMP(uri->query, tests[i].uri.query));
TEST (i, "fragment", !SAFESTRCMP(uri->fragment, tests[i].uri.fragment));
gnet_uri_escape (uri);
escape = gnet_uri_get_string (uri);
TEST (i, "gnet_uri_escape", escape != NULL);
/* g_print ("%s -e-> %s\n", pretty, escape); */
gnet_uri_unescape (uri);
unescape = gnet_uri_get_string (uri);
TEST (i, "gnet_uri_unescape", unescape != NULL);
/* g_print ("%s -u-> %s\n", escape, unescape); */
TEST (i, "url = unescape(escape(url))", !strcmp(pretty, unescape));
g_free (escape);
g_free (unescape);
g_free (pretty);
gnet_uri_delete (uri);
}
for (i = 0; escape_tests[i].escaped; ++i)
{
GURI* uri;
gchar* escape;
gchar* unescape;
uri = gnet_uri_new (escape_tests[i].escaped);
TEST (i, "gnet_uri_new", uri != NULL);
if (!uri) continue;
gnet_uri_unescape (uri);
unescape = gnet_uri_get_string (uri);
TEST (i, "gnet_uri_unescape", unescape != NULL);
TEST (i, "unescape is correct",
!strcmp(escape_tests[i].unescaped, unescape));
g_free (unescape);
gnet_uri_escape (uri);
escape = gnet_uri_get_string (uri);
TEST (i, "gnet_uri_escape", escape != NULL);
if (escape_tests[i].escaped2)
TEST (i, "escape is correct", !strcmp(escape_tests[i].escaped2, escape));
else
TEST (i, "escape is correct", !strcmp(escape_tests[i].escaped, escape));
g_free (escape);
}
if (failed)
exit (1);
exit (0);
}
syntax highlighted by Code2HTML, v. 0.9.1