Recently, I had to write a bunch of Apache rewrite rules which applied to the whole URL, including the hostname. I also add to use RewriteMap
for efficiency.
I initially though this would be difficult to test locally but, in fact, with little modifications of a local Apache instance and use of the /etc/hosts
file, it's pretty easy.
This article will detail how I did it on my computer running Ubuntu and hopefully it will help others setup their own computer.
Testing rewrite rules¶
online¶
Online tools such as htaccess tester exists and can come in handy to test simple rules but that are limited techically (they usually advertise their limitations) but also by design: e.g. they can not support RewriteMap.
when working rules, regex101.com is pretty usefull to test regular expressions. Be sure to be in "pcre" mode as this is the intepretor used by Apache.
locally¶
Testing locally is the only way to fully test the rewrite rules you write, you can even test various version of Apache (but I won't cover that here).
Fortunatly, it is not so complicated to set up a local instance to test even host-based rewrite rules.
Installing and configuring Apache¶
install¶
If you already have Apache installed, skip this.
Installation under Ubuntu is trivial:
sudo apt-get install apache2
By default, the installed Apache instance is bound to port 80 and any host.
Make sure the instance not bound to a specific ip or host.
enable mod_rewrite¶
When installing Apache, mod_rewrite
might not be installed by default.
Under Ubuntu, just add a link in directory /etc/apache2/mods-enabled
to the rewrite.load
file in /etc/apache2/mods-available
;
cd /etc/apache2/mods-enabled
ln -s ../mods-available/rewrite.load
Modify the default host¶
use a dedicated conf file¶
Open file 000-default.conf
where the default host is configured.
sudo vi /etc/apache2/sites-available/000-default.conf
The default host is bound to any host on port 80:
<VirtualHost *:80>
Add an Include
directive before the closing tag of the VirtualHost
directive to import the configuration file where you will write your Rewrite rules.
This is optional but you will find it convenient to clean your installation later or disable all changes you made by just commenting this directive.
Include /etc/apache2/sites-available/my_rewrite_rule_tests.conf
mod_rewrite logging¶
enable logging¶
Inside the VirtualHost
directive, look for the LogLevel
directive, it may be commented out, or add it.
What matters is having an argument to the directive starting with rewrite
, such as the following:
LogLevel alert rewrite:trace8
The part after the colon in rewrite:trace8
is the logging level.
As we are testing locally, we can use the maximum logging level (level8) but be aware that it should be used carefull (don't go lower than trace3) as mod_rewrite quickly gets extremely verbose.
read mod_rewrite logs¶
mod_rewrite logs into /var/log/apache2/error.log
with a [rewrite
prefix.
tail -f /var/log/apache2/error.log | fgrep '[rewrite:'
Add hosts to /etc/hosts¶
The point here is to make any hostname involved in our rewrite rules point to the local computer (127.0.O.1).
You can then test rewrite rule based on existing host but also on non existing ones.
for existing host, make sure you revert modifications in
/etc/hosts
after your are done testing. Otherwise, if you addedwwww.google.com
and bound it tolocalhost
in/etc/hosts
you won't be able to reach the real Google website
Open /etc/hosts
(sudo required):
sudo vi /etc/hosts
and add a line such as the following:
127.0.0.1 store.mydomain.com boutique.mydomain.com
bind Apache to hostnames¶
Add a ServerName
directive (if none is already set yet) and any number of ServerAlias
directive to bind Apache to hostnames you defined in /etc/hosts
.
My advice is to add these directive to the dedicated configuration file created earlier.
ServerName store.mydomain.com
ServerAlias boutique.mydomain.com
add rewrite rules¶
Make sure the mod_rewrite engine is enabled by adding the RewriteEngine
directive:
RewriteEngine On
Now, add your RewriteRule, RewriteCond and RewriteMap directives.
test changes¶
You can either start/restart or reload Apache after each change.
sudo /etc/init.d/apache2 start
sudo /etc/init.d/apache2 restart
# only reload the configuration without restarting Apache
sudo /etc/init.d/apache2 reload
Now, open your favorite browser, type in a URL to test, see the result in the browser: are you being redirected or not? to the correct URL?
It does really matter if the URL your are being redirect to actually exists, worse case scenario, you'll get a 404 error but you will know if the rewrite rule worked.
If it is not working, check out the logs.
At log level trace8
every operations run by mod_rewrite is visible. This even convenient to understand how the mod and directives work.