Wrangling HTTP and HTTPS versions of the same Apache virtual host
It has been '0' days since I have been bitten by the fact that in Apache you usually have separate configurations for the HTTP and the HTTPS version of a site even if you want them the same, so you can change the wrong one when testing and be confused when a fix doesn't work.
(This was part of discovering how not to use RewriteRule in a reverse proxy.)
We have a bunch of named virtual hosts that we have set up for people; many although not all of them are reverse proxies to user run web servers. Increasingly people ask for (and we provide) both a HTTP and a HTTPS version of the site. The most natural and least complicated way to do this is to have a big Apache configuration file with all of our named vhosts and to repeat the configuration for a host between the HTTP and HTTPS versions.
This tends to look something like:
<VirtualHost 128.100.X.XX:80> ServerName ahost.cs.<etc> [all of ahost's configuration] </VirtualHost> <VirtualHost 128.100.X.XX:443> ServerName ahost.cs.<etc> SSLEngine on [TLS certificate settings] [all of ahost's configuration] </VirtualHost>
When you do this and you have some RewriteRule settings or something complex that you're trying to fix, it's possible to accidentally change the HTTPS version of the site but not the HTTP version and then test against the HTTP version. Or vice versa. This is made easier when the site's configuration is big enough to push the other version of the site off your editor screen.
One answer is that we're shooting both ourselves and other people in the foot by even having a meaningful HTTP site here. If people ask for a HTTPS site, we should default to making their HTTP site redirect everything to the HTTPS one (and probably the HTTPS one should set a HSTS header). This would make the mistake impossible to commit, because the only site with real configuration would be the HTTPS one.
Failing that, what I would like is some way to have the same block apply to both the HTTP and HTTPS virtual host. In my imagination, it would look something like:
<VirtualHost 128.100.X.XX:80 128.100.X.XX:443> ServerName ahost.cs.<etc> <IfPort :443> SSLEngine on [TLS certificate settings] </IfPort> [all of ahost's configuration] </VirtualHost>
(Apache 2.4 has an <If> directive, but my understanding is that it takes effect too late to do this.)
One possible answer is to put the vhost's real configuration in a
separate file that is
Include'd in both. Unfortunately I don't think
this scales for us; we don't like splitting things up this way in
general, and we have enough virtual hosts where the HTTP and HTTPS
versions are different that they would be exceptions in this scheme in
one way or another. We'd prefer to keep everything in one file where
it's at least readily visible all at once.
Another possible answer is mod_macro (first brought to my attention by @ch2500). Unfortunately as far as I can see this involves adding an extra configuration block for each such virtual host (for the <Macro> definition), and makes the actual HTTP and HTTPS <VirtualHost> blocks more magical and harder to read. I'm not all that enthused and my co-workers would almost certainly reject this as too much magic even if I proposed it.
(Some but not all of our virtual hosts could be done with a common <Macro> template, but that would create even more magic.)