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') {