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)
I don't mean to say ProxyPreserveHost On" should be the default behaviour, is that not stripping brackets should be the default behaviour
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
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....
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.
Changelog shows fixed in 2.2.12
*** Bug 46195 has been marked as a duplicate of this bug. ***