]> granicus.if.org Git - apache/commitdiff
Fix handling of IPv6 numeric strings in mod_proxy.
authorJeff Trawick <trawick@apache.org>
Wed, 19 May 2004 13:30:14 +0000 (13:30 +0000)
committerJeff Trawick <trawick@apache.org>
Wed, 19 May 2004 13:30:14 +0000 (13:30 +0000)
(Some such operations would work if port was specified
in url due to way parsing was performed, finding last ':'
and considering everything after as the port.)

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@103698 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/proxy/proxy_ftp.c
modules/proxy/proxy_http.c
modules/proxy/proxy_util.c

diff --git a/CHANGES b/CHANGES
index 04a82fd934e10f2783b5abba4790a231b694ae42..db9a869bf9fbea39f2ad8605a02e7509d1c263c7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,8 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) Fix handling of IPv6 numeric strings in mod_proxy.  [Jeff Trawick]
+
   *) External rewrite map responses are no longer limited to 2048
      bytes.  [AndrĂ© Malo]
 
index ad29d08463bf928c5df495c132b7c329bef86fd3..23483c1b198fe6c90ab00ef7f571b5ba1174e06f 100644 (file)
@@ -205,6 +205,9 @@ int ap_proxy_ftp_canon(request_rec *r, char *url)
     else
         sport[0] = '\0';
 
+    if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */
+        host = apr_pstrcat(p, "[", host, "]");
+    }
     r->filename = apr_pstrcat(p, "proxy:ftp://", (user != NULL) ? user : "",
                               (password != NULL) ? ":" : "",
                               (password != NULL) ? password : "",
index 58485931efc0cbf8ec49646a25f56f85e32cb08f..a0296d90e2aec7032506c702214117d3ded3390d 100644 (file)
@@ -71,8 +71,12 @@ int ap_proxy_http_canon(request_rec *r, char *url)
      */
     port = def_port;
     err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
-    if (err)
+    if (err) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "error parsing URL %s: %s",
+                      url, err);
         return HTTP_BAD_REQUEST;
+    }
 
     /* now parse path/search args, according to rfc1738 */
     /* N.B. if this isn't a true proxy request, then the URL _path_
@@ -97,6 +101,9 @@ int ap_proxy_http_canon(request_rec *r, char *url)
     else
         sport[0] = '\0';
 
+    if (ap_strchr_c(host, ':')) { /* if literal IPv6 address */
+        host = apr_pstrcat(r->pool, "[", host, "]", NULL);
+    }
     r->filename = apr_pstrcat(r->pool, "proxy:", scheme, "://", host, sport, 
             "/", path, (search) ? "?" : "", (search) ? search : "", NULL);
     return OK;
index 718d49237c90af0971655c3d9a2ec359d88fa3e6..813437137188366e15371711403247444e831288 100644 (file)
@@ -197,9 +197,10 @@ PROXY_DECLARE(char *)
      ap_proxy_canon_netloc(apr_pool_t *p, char **const urlp, char **userp,
                        char **passwordp, char **hostp, apr_port_t *port)
 {
-    int i;
-    char *strp, *host, *url = *urlp;
+    char *addr, *scope_id, *strp, *host, *url = *urlp;
     char *user = NULL, *password = NULL;
+    apr_port_t tmp_port;
+    apr_status_t rv;
 
     if (url[0] != '/' || url[1] != '/')
        return "Malformed URL";
@@ -238,44 +239,21 @@ PROXY_DECLARE(char *)
        *passwordp = password;
     }
 
-    strp = strrchr(host, ':');
-    if (strp != NULL) {
-       *(strp++) = '\0';
-
-       for (i = 0; strp[i] != '\0'; i++)
-           if (!apr_isdigit(strp[i]))
-               break;
-
-       /* if (i == 0) the no port was given; keep default */
-       if (strp[i] != '\0') {
-           return "Bad port number in URL";
-       } else if (i > 0) {
-            int int_port = atoi(strp);
-
-           if (int_port > 65535)
-               return "Port number in URL > 65535";
-
-           *port = (apr_port_t)int_port;
-       }
+    /* Parse the host string to separate host portion from optional port.
+     * Perform range checking on port.
+     */
+    rv = apr_parse_addr_port(&addr, &scope_id, &tmp_port, host, p);
+    if (rv != APR_SUCCESS || addr == NULL || scope_id != NULL) {
+        return "Invalid host/port";
     }
-    ap_str_tolower(host);              /* DNS names are case-insensitive */
-    if (*host == '\0')
-       return "Missing host in URL";
-/* check hostname syntax */
-    for (i = 0; host[i] != '\0'; i++)
-       if (!apr_isdigit(host[i]) && host[i] != '.')
-           break;
-    /* must be an IP address */
-    if (host[i] == '\0' && (apr_inet_addr(host) == -1))
-    {
-       return "Bad IP address in URL";
+    if (tmp_port != 0) { /* only update caller's port if port was specified */
+        *port = tmp_port;
     }
 
-/*    if (strchr(host,'.') == NULL && domain != NULL)
-   host = pstrcat(p, host, domain, NULL);
- */
+    ap_str_tolower(addr); /* DNS names are case-insensitive */
+
     *urlp = url;
-    *hostp = host;
+    *hostp = addr;
 
     return NULL;
 }