Bug 47177 - mod_proxy rewrites incorrectly IPv6 literal addresses
Summary: mod_proxy rewrites incorrectly IPv6 literal addresses
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy_http (show other bugs)
Version: 2.2.9
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: FixedInTrunk
Depends on:
Blocks:
 
Reported: 2009-05-09 06:48 UTC by Carlos Garcia Braschi
Modified: 2010-02-12 08:08 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Carlos Garcia Braschi 2009-05-09 06:48:19 UTC
mod_proxy rewrites a received request of 
GET http://[2001:4860:a005::84]/search?q=cache:KD9mYbWwEgkJ:www.apache.org/+apache&cd=1&hl=en&ct=clnk HTTP/1.1
Host: [2001:4860:a005::84]

into 

GET /search?q=cache:KD9mYbWwEgkJ:www.apache.org/+apache&cd=1&hl=en&ct=clnk HTTP/1.1
Host: 2001:4860:a005::84

Which is incorrect, loosely according to RFC 3986 (for URI syntax), (http://tools.ietf.org/html/rfc3986), that says "A host identified by an Internet Protocol literal address, version 6 [RFC3513] or later, is distinguished by enclosing the IP literal within square brackets ("[" and "]")".

The right way to do it would be to use
GET /search?q=cache:KD9mYbWwEgkJ:www.apache.org/+apache&cd=1&hl=en&ct=clnk HTTP/1.1
Host: [2001:4860:a005::84]

This behaviour can be worked around by using "ProxyPreserveHost On", but that should be the default behaviours. 

This behaviour leads to infinite redirection in servers that detect the error and redirect to http://[2001:4860:a005::84]/search... (like Google Web Server when used for caching)
Comment 1 Carlos Garcia Braschi 2009-05-09 06:50:22 UTC
I don't mean to say ProxyPreserveHost On" should be the default behaviour, is that not stripping brackets should be the default behaviour
Comment 2 Carlos Garcia Braschi 2009-05-10 23:24:06 UTC
Referring to the HTTP/1.1 spec, it is clear that a Host: IPv6 field cannot be sent without brackets, as it would be then ambiguous if it contains or not a :port part.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.23
Comment 3 Carlos Garcia Braschi 2009-05-11 00:17:43 UTC
mod_proxy_http.c

A naive and untested fix (I'm sorry, but I don't have a developer environment to test it), borrowing from the proxy_http_canon function, would be to change function ap_proxy_http_request in this way. 

from:
    if (conf->preserve_host == 0) {
        if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
            buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", uri->port_str,
                              CRLF, NULL);
        } else {
            buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL);
        }
    }

to 
    if (conf->preserve_host == 0) {
        if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */
            if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
                buf = apr_pstrcat(p, "Host: [", uri->hostname, "]:", 
                                  uri->port_str, CRLF, NULL);
            } else {
                buf = apr_pstrcat(p, "Host: [", uri->hostname, "]", CRLF, NULL);
            }
        } else {
            if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
                buf = apr_pstrcat(p, "Host: ", uri->hostname, ":", 
                                  uri->port_str, CRLF, NULL);
            } else {
                buf = apr_pstrcat(p, "Host: ", uri->hostname, CRLF, NULL);
            }
        }
    }

I'm not sure if a more architectural fix having apr_uri_parse function leaving the brackets for IPv6 hostnames would be better, as they are always required to be there in URIs... but that means apr_uri and all of the code depending on apr_uri to be fixed....
Comment 4 Nick Kew 2009-05-25 16:22:12 UTC
Your patch looks fine to me.  Fixed in trunk in r778531.

There may be a similar issue with ProxyRemote and literal ipv6 addresses: I haven't checked for it.
Comment 5 Nick Kew 2009-12-26 14:41:52 UTC
Changelog shows fixed in 2.2.12
Comment 6 Nick Kew 2010-02-12 08:08:50 UTC
*** Bug 46195 has been marked as a duplicate of this bug. ***