Improving Apache's canonical hostname rewrite rules
According to the Apache URL rewriting guide, the way to handle Canonical Hostnames is like this:
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]
Well, those rules are not always sufficient. Specifically, what if you also owned the www.example.com.au
domain, and
wished to redirect it also to the primary www.example.com
domain? The solution is simple - we just need to add a
single $
character to the end of the match-pattern of the first RewriteCond
like this:
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]
Now that will work nicely as long as the hosts use standard ports (ie 80 for HTTP, and 443 for HTTPS). However, some
Python versions unnecessarily
append the standard HTTPS port number to the
Host
HTTP header. Also I discovered today (after
some Apache debug logging) that Adobe AIR applications have the exact same
misbehavior for HTTPS, but only when running under Mac OS X.
So, to handle non-standard ports, and/or misbehaving (Python / Adobe AIR) clients, we need to extend the first match-pattern slightly to allow an optional port number, like this:
RewriteCond %{HTTP_HOST} !^fully\.qualified\.domain\.name(:.*)?$ [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule ^/(.*) http://fully.qualified.domain.name/$1 [L,R]
So adding the 7 characters (:.*)?$
to the officially recommended
Canonical Hostnames rules:
- redirects domains with suffixes (not just prefixes) back to the canonical host; and
- allows
Host
request headers to contain port specifiers (which is allowed by RFC2616 section 14.24).
Now I might just see if I can figure out who's responsible for the URL rewriting guide, and see I can get them to make a small addition... ;)