Introduction
The mod_rewrite module is a rule-based Apache engine for rewriting URLs. The rules allow writing various queries to change URLs into the desired format. Some applications include page redirecting or proxy fetching.
This article shows how to set up, configure, and rewrite URLs using mod_rewrite.
Prerequisites
- Apache web server installed, configured, and active (running).
- Access to an account with sudo.
- Access to a command-line utility/terminal.
- Access to a browser or the curl command installed.
Note: A small Bare Metal Cloud (BMC) server is an affordable and powerful solution for creating a testing environment. Check out our use-case guide for setting up a dev sandbox environment on a small BMC instance.
The small BMC instance prices go for as low as $0.08/h!
What Is mod_rewrite in Apache?
The mod_rewrite Apache module helps manipulate URL requests on the server's side. Rules and patterns check an inputted URL through regular expressions and variables to extract information and serve the desired page.
For example, if a requested URL is in the following format:
example.com/foo/bar
The mod_rewrite module helps translate the URL into something the server understands how to handle:
example.com/foo.php?id=bar
Allowing the first format comes with a few benefits:
- The URL is less cryptic, more memorable, and easier to replicate from a user's perspective.
- Search engines extract semantic meaning from the first URL format.
- A user is unaware that the foo.php page exists as a file from the first URL, which is essential from a security perspective.
The mod_rewrite module does not prettify a URL. Instead, it turns pretty links into HTTP requests the server knows how to handle.
How to Use mod_rewrite?
To use the mod_rewrite module, Apache requires:
- Enabling the module.
- Configuring the server.
- Setting up the .htaccess file.
The configuration for mod_rewrite and URL rewriting is an easy two-step process.
Enable mod_rewrite
To enable mod_rewrite, open the terminal and run:
sudo a2enmod rewrite
The command outputs a message that the module is enabled or is already active. Restart the Apache service to apply the changes:
sudo systemctl apache2 restart
The new configuration is now running.
Configure .htaccess to Override Website Configs
The .htaccess file modifies website details without changing the configuration files. Store the file appropriately because it affects all other files in the current directory and subdirectories.
The example project is in the /var/www/html/ directory.
1. Create the .htaccess file in the website directory:
sudo touch /var/www/html/.htaccess
Next, configure .htaccess to override website configuration:
2. Open the apache2.conf file:
sudo nano /etc/apache2/apache2.conf
Making changes requires sudo privileges.
3. Locate the following section:
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
Change the AllowOverride
option from None
to All
:
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
Save the file and close (CTRL + X, Y, Enter).
4. Restart the Apache service:
sudo systemctl apache2 restart
The .htaccess file now overrides all other configurations, allowing URL rewrites.
mod_rewrite Directives
The URL rewriting operations occur in the .htaccess file and consist of various directives. Some of the available directives are:
1. RewriteEngine
is the engine that enables or disables the runtime. The syntax is:
RewriteEngine On|Off
By default, the RewriteEngine
is off. Control the runtime processing by switching the directive on or off.
2. RewriteCond
is a directive that stores the conditions under which rewrites happen. It has the following syntax:
RewriteCond TestString ConditionPattern [Flags]
RewriteCond
is the directive keyword for a single condition. Multiple condition directives are possible before a single rule.TestString
contains plain text and additional constructs, such as backreferences or server variables.ConditionPattern
is a Pearl Compatible Regular Expressions (PCRE), which applies to theTestString
.
3. RewriteRule
are the rules which the rewrite engine runs. The syntax looks like this:
RewriteRule Pattern Substitution [Flags]
RewriteRule
is the directive keyword for a single rule instance. Multiple rules are possible, and order is important.Pattern
is the regex pattern to match a part of the requested URL. The mod_rewrite module uses Pearl Compatible Regular Expression (PCRE) syntax.Substitution
is the actual URL to the information we want to show.[Flags]
is an optional parameter that changes the expression's behavior.
4. RewriteMap
is a mapping function for a key lookup. The syntax is:
RewriteMap MapName MapType:MapSource [MapTypeOptions]
RewriteMap
is the directive keyword for the mapping function.MapName
is the name of the function and the way to reference it to aRewriteRule
.MapType
states the file type of theMapSource
. TheMapTypeOptions
also depend on theMapType
.MapSource
is the path to the file containing mapping information.
URL Rewrite Examples
The best way to understand mod_rewrite directives is through practical use cases. Below are a few typical examples to demonstrate how mod_rewrite works.
Write Contents from One Page on Another Page
A simple example of a URL rewrite is when requesting one page, we serve the contents of another page. This use case applies to situations where we want to replace an old page with new content without changing the URL.
The .htaccess file looks like the following:
RewriteEngine On
RewriteRule ^old.html$ new.html [NC]
- Line 1 enables the rewrite engine.
- Line 2 contains the
RewriteRule
directive:- The pattern
^old.html$
matches the page which starts (^
) and ends ($
) withold.html
. - The substitution is the
new.html
page. - The flag
[NC]
means the pattern is not case-sensitive.
- The pattern
When a user tries to access the old page, the server shows the contents from the new.html page instead.
Backreferencing RewriteRule Parameters
For a user accessing a URL in the following format:
http://example.com/product/foo/bar
The rewritten URL request has the following format:
http://example.com/request.php?id=foo&name=bar
The .httaccess URL rewrite contents are:
RewriteEngine On
RewriteRule ^product/([A-Za-z]+)/([A-Za-z]+)$ request.php?id=$1&name=$2
The rewrite rule takes the pattern from the parenthesis and stores it in the reference variables. The reference parameters go from $1
to $9
.
RewriteCondition Directive
The RewriteCondition
directive helps create a constraint to RewriteRules
. In other words, the condition tells the RewriteRule
under which circumstances to apply the rewrite.
The condition helps provide a general constraint. For example, if all the web page extensions are migrated from HTML to PHP, the rewrite helps redirect all requests ending in .html to .php.
The .htaccess file looks like this:
RewriteEngine On
RewriteCond %{HTTP_HOST} !php$
RewriteRule "^(.*).html$" "$1.php"
RewriteCond
consists of:
%{HTTP_HOST}
is the test string. Specifically, it is a server variable with the complete HTTP host.!php$
is the condition pattern that looks for all requests not ending in .php.
RewriteRule
acts only in case the RewriteCondition
evaluates to true. The rewrite is:
"^(.*).html$"
is the pattern match. The rewrite pattern specifically looks for requests starting with any characters and ending with .html."$1.php"
is the substitution. The$1
backreferences the string before.html
((.*)
) and adds.php
at the end.
RewriteCond
helps perform any migration quickly, allowing a quick redirect from old pages or domains to new ones.
RewriteEngine Directive
The RewriteEngine
directive is how every .htaccess file begins - switching the RewriteEngine
on oand off controls whether the rewrites happen. The feature is handy for debugging and testing purposes.
Another use case of the RewriteEngine
is to "comment" sections in the .htaccess file. For example:
RewriteEngine On
RewriteCond %{HTTP_HOST} !php$
RewriteRule "^(.*).html$" "$1.php"
RewriteEngine Off
RewriteRule ^old.html$ new.html [NC]
RewriteEngine On
RewriteRule ^product/([A-Za-z]+)/([A-Za-z]+)$ request.php?id=$1&name=$2
Turning the RewriteEngine
off for rules and conditions means that mod_rewrite does not execute the rewrite rules until the engine is on again.
RewriteMap Directive
The RewriteMap
directive helps enhance rule substitution strings. For an example URL in the form:
http://example.com/product/database
The rewrite requirement is:
http://example.com/products.php?id=272
Instead of searching for the product ID by hand, use RewriteMap
and provide a file with key-value pairs containing the product names and IDs.
The following example demonstrates how to map from a file.txt with key-value pairs:
database 272
server 273
cloud 274
The rewrite file looks like the following:
RewriteEngine On
RewriteMap prodID "txt:/path/to/file.txt"
RewriteRule "^product/(.*)" "products.php?id=${prodID:$1}"
The file has the following structure:
1. file.txt
is the file with key-value pairs. Rewrite map uses the information as a reference.
2. prodID
is the map name. The name helps reference the function in the rewrite rule substitution.
3. (.*)
is the string in the URL or the product name (database, server, cloud). The map function uses the value to search the file.txt for the corresponding ID.
4. ${profID:$1}
maps the product name to an ID and returns the ID from the file.
The RewriteMap
directive offers various map types. For example, the randomized plain text map type (rnd) helps create load balancing solutions, while the databases map type (dbd or fastdbd) uses a SELECT statement to fetch data.
Conclusion
After going through the steps and examples in this guide, you should know how to activate and use mod_rewrite. The examples show how to use the mod_rewrite module for fundamental rewriting problems.
Next, see how you can use the curl to control the user agent for testing and debugging.