You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by tr...@apache.org on 2002/10/07 22:40:59 UTC
cvs commit: apr-util/uri apr_uri.c
trawick 2002/10/07 13:40:59
Modified: . CHANGES
test testuri.c
uri apr_uri.c
Log:
Add IPv6 literal address support to apr_uri_parse(), apr_uri_unparse(),
and apr_uri_parse_hostinfo().
PR: 11887
Revision Changes Path
1.84 +3 -0 apr-util/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr-util/CHANGES,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- CHANGES 3 Oct 2002 05:39:27 -0000 1.83
+++ CHANGES 7 Oct 2002 20:40:59 -0000 1.84
@@ -1,5 +1,8 @@
Changes with APR-util 0.9.2
+ *) Add IPv6 literal address support to apr_uri_parse(), apr_uri_unparse(),
+ and apr_uri_parse_hostinfo(). PR 11887 [Jeff Trawick]
+
*) Add apr_brigade_writev() [Brian Pane]
*) Add support for Berkeley DB 4.1. [Justin Erenkrantz]
1.2 +101 -3 apr-util/test/testuri.c
Index: testuri.c
===================================================================
RCS file: /home/cvs/apr-util/test/testuri.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- testuri.c 7 Oct 2002 16:34:59 -0000 1.1
+++ testuri.c 7 Oct 2002 20:40:59 -0000 1.2
@@ -80,6 +80,18 @@
0, "http", "127.0.0.1:9999", NULL, NULL, "127.0.0.1", "9999", "/asdf.html", NULL, NULL, 9999
},
{
+ "http://127.0.0.1:9999a/asdf.html",
+ APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
+ },
+ {
+ "http://[::127.0.0.1]:9999/asdf.html",
+ 0, "http", "[::127.0.0.1]:9999", NULL, NULL, "::127.0.0.1", "9999", "/asdf.html", NULL, NULL, 9999
+ },
+ {
+ "http://[::127.0.0.1]:9999a/asdf.html",
+ APR_EGENERAL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0
+ },
+ {
"/error/include/top.html",
0, NULL, NULL, NULL, NULL, NULL, NULL, "/error/include/top.html", NULL, NULL, 0
},
@@ -104,8 +116,48 @@
0, "http", "sonyamt:garbage@127.0.0.1", "sonyamt", "garbage", "127.0.0.1", NULL, "/filespace/", NULL, NULL, 0
},
{
- "http://sonyamt@127.0.0.1/filespace/?arg1=store",
- 0, "http", "sonyamt@127.0.0.1", "sonyamt", NULL, "127.0.0.1", NULL, "/filespace/", "arg1=store", NULL, 0
+ "http://sonyamt:garbage@[fe80::1]/filespace/",
+ 0, "http", "sonyamt:garbage@[fe80::1]", "sonyamt", "garbage", "fe80::1", NULL, "/filespace/", NULL, NULL, 0
+ },
+ {
+ "http://sonyamt@[fe80::1]/filespace/?arg1=store",
+ 0, "http", "sonyamt@[fe80::1]", "sonyamt", NULL, "fe80::1", NULL, "/filespace/", "arg1=store", NULL, 0
+ }
+};
+
+struct uph_test {
+ const char *hostinfo;
+ apr_status_t rv;
+ const char *hostname;
+ const char *port_str;
+ apr_port_t port;
+};
+
+struct uph_test uph_tests[] =
+{
+ {
+ "www.ibm.com:443",
+ 0, "www.ibm.com", "443", 443
+ },
+ {
+ "[fe80::1]:443",
+ 0, "fe80::1", "443", 443
+ },
+ {
+ "127.0.0.1:443",
+ 0, "127.0.0.1", "443", 443
+ },
+ {
+ "127.0.0.1",
+ APR_EGENERAL, NULL, NULL, 0
+ },
+ {
+ "[fe80:80",
+ APR_EGENERAL, NULL, NULL, 0
+ },
+ {
+ "fe80::80]:443",
+ APR_EGENERAL, NULL, NULL, 0
}
};
@@ -164,7 +216,7 @@
t = &aup_tests[i];
rv = apr_uri_parse(p, t->uri, &info);
failed = (rv != t->rv) ? "bad rc" : NULL;
- if (!failed) {
+ if (!failed && t->rv == APR_SUCCESS) {
if (!same_str(info.scheme, t->scheme))
failed = "bad scheme";
if (!same_str(info.hostinfo, t->hostinfo))
@@ -192,6 +244,48 @@
t->uri, failed);
show_info(rv, t->rv, &info);
}
+ else if (t->rv == APR_SUCCESS) {
+ const char *s = apr_uri_unparse(p, &info,
+ APR_URI_UNP_REVEALPASSWORD);
+
+ if (strcmp(s, t->uri)) {
+ fprintf(stderr, "apr_uri_unparsed failed for testcase %d\n", i);
+ fprintf(stderr, " got %s, expected %s\n", s, t->uri);
+ }
+ }
+ }
+
+ return rc;
+}
+
+static int test_uph(apr_pool_t *p)
+{
+ int i;
+ apr_status_t rv;
+ apr_uri_t info;
+ struct uph_test *t;
+ const char *failed;
+ int rc = 0;
+
+ for (i = 0; i < sizeof(uph_tests) / sizeof(uph_tests[0]); i++) {
+ memset(&info, 0, sizeof(info));
+ t = &uph_tests[i];
+ rv = apr_uri_parse_hostinfo(p, t->hostinfo, &info);
+ failed = (rv != t->rv) ? "bad rc" : NULL;
+ if (!failed && t->rv == APR_SUCCESS) {
+ if (!same_str(info.hostname, t->hostname))
+ failed = "bad hostname";
+ if (!same_str(info.port_str, t->port_str))
+ failed = "bad port_str";
+ if (info.port != t->port)
+ failed = "bad port";
+ }
+ if (failed) {
+ ++rc;
+ fprintf(stderr, "failure for testcase %d/hostinfo %s: %s\n", i,
+ t->hostinfo, failed);
+ show_info(rv, t->rv, &info);
+ }
}
return rc;
@@ -209,5 +303,9 @@
rc = test_aup(pool);
+ if (!rc) {
+ rc = test_uph(pool);
+ }
+
return rc;
}
1.15 +50 -11 apr-util/uri/apr_uri.c
Index: apr_uri.c
===================================================================
RCS file: /home/cvs/apr-util/uri/apr_uri.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- apr_uri.c 6 Jul 2002 19:44:50 -0000 1.14
+++ apr_uri.c 7 Oct 2002 20:40:59 -0000 1.15
@@ -160,6 +160,12 @@
/* Construct scheme://site string */
if (uptr->hostname) {
int is_default_port;
+ const char *lbrk = "", *rbrk = "";
+
+ if (strchr(uptr->hostname, ':')) { /* v6 literal */
+ lbrk = "[";
+ rbrk = "]";
+ }
is_default_port =
(uptr->port_str == NULL ||
@@ -167,11 +173,11 @@
uptr->port == apr_uri_port_of_scheme(uptr->scheme));
ret = apr_pstrcat(p,
- uptr->scheme, "://", ret,
- uptr->hostname ? uptr->hostname : "",
- is_default_port ? "" : ":",
- is_default_port ? "" : uptr->port_str,
- NULL);
+ uptr->scheme, "://", ret,
+ lbrk, uptr->hostname, rbrk,
+ is_default_port ? "" : ":",
+ is_default_port ? "" : uptr->port_str,
+ NULL);
}
}
@@ -244,6 +250,7 @@
const char *hostinfo;
char *endstr;
int port;
+ int v6_offset1 = 0, v6_offset2 = 0;
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
@@ -318,15 +325,33 @@
/* again we want the common case to be fall through */
deal_with_host:
/* We expect hostinfo to point to the first character of
- * the hostname. If there's a port it is the first colon.
+ * the hostname. If there's a port it is the first colon,
+ * except with IPv6.
*/
- s = memchr(hostinfo, ':', uri - hostinfo);
+ if (*hostinfo == '[') {
+ v6_offset1 = 1;
+ v6_offset2 = 2;
+ s = uri;
+ do {
+ --s;
+ } while (s >= hostinfo && *s != ':' && *s != ']');
+ if (s < hostinfo || *s == ']') {
+ s = NULL; /* no port */
+ }
+ }
+ else {
+ s = memchr(hostinfo, ':', uri - hostinfo);
+ }
if (s == NULL) {
/* we expect the common case to have no port */
- uptr->hostname = apr_pstrmemdup(p, hostinfo, uri - hostinfo);
+ uptr->hostname = apr_pstrmemdup(p,
+ hostinfo + v6_offset1,
+ uri - hostinfo - v6_offset2);
goto deal_with_path;
}
- uptr->hostname = apr_pstrmemdup(p, hostinfo, s - hostinfo);
+ uptr->hostname = apr_pstrmemdup(p,
+ hostinfo + v6_offset1,
+ s - hostinfo - v6_offset2);
++s;
uptr->port_str = apr_pstrmemdup(p, s, uri - s);
if (uri != s) {
@@ -367,6 +392,8 @@
{
const char *s;
char *endstr;
+ const char *rsb;
+ int v6_offset1 = 0;
/* Initialize the structure. parse_uri() and parse_uri_components()
* can be called more than once per request.
@@ -378,11 +405,23 @@
/* We expect hostinfo to point to the first character of
* the hostname. There must be a port, separated by a colon
*/
- s = strchr(hostinfo, ':');
+ if (*hostinfo == '[') {
+ if ((rsb = strchr(hostinfo, ']')) == NULL ||
+ *(rsb + 1) != ':') {
+ return APR_EGENERAL;
+ }
+ /* literal IPv6 address */
+ s = rsb + 1;
+ ++hostinfo;
+ v6_offset1 = 1;
+ }
+ else {
+ s = strchr(hostinfo, ':');
+ }
if (s == NULL) {
return APR_EGENERAL;
}
- uptr->hostname = apr_pstrndup(p, hostinfo, s - hostinfo);
+ uptr->hostname = apr_pstrndup(p, hostinfo, s - hostinfo - v6_offset1);
++s;
uptr->port_str = apr_pstrdup(p, s);
if (*s != '\0') {