URL rewrite in Apache is done through the rewrite module.
The rules are set in the htaccess file
This module operates on the full URLs (including the path-info part) both:
By default, mod_rewrite configuration settings from the main server context are not inherited by virtual hosts. To make the main server settings apply to virtual hosts, you must place the following directives in each <VirtualHost> section:
RewriteEngine On
RewriteOptions Inherit
mod_rewrite evaluates the left-hand-side of the RewriteRule before it evaluates the RewriteCond directives.
RewriteCond $1.php -f
RewriteCond $1.html !-f
RewriteRule ^(.*).html$ $1.php
Consequently, $1 is already defined by the time the RewriteCond directives are evaluated. This allows us to test for the existence of the original (document.html) and target (document.php) files using the same base filename.
RewriteEngine On
# /abc/def is the physical path of /xyz
# let the server know that we were reached via /xyz and not
# via the physical path prefix /abc/def
RewriteBase /xyz
# now the rewriting rules
RewriteRule ^oldstuff\.html$ newstuff.html
In the above example, a request to /xyz/oldstuff.html gets correctly rewritten to the physical file /abc/def/newstuff.html.
Because the per-directory rewriting comes late in the process, the rewritten request has to be re-injected into the Apache kernel, as if it were a new request.
RewriteCond TestString CondPattern [Flags]
where:
You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.
Special pattern expression | Short Description | Description |
---|---|---|
'<CondPattern' | lexicographically precedes | Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically precedes CondPattern. |
'>CondPattern' | lexicographically follows | Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString lexicographically follows CondPattern. |
'=CondPattern' | lexicographically equal | Treats the CondPattern as a plain string and compares it lexicographically to TestString. True if TestString is lexicographically equal to CondPattern (the two strings are exactly equal, character for character). If CondPattern is “” (two quotation marks) this compares TestString to the empty string. |
'-d' | is directory | Treats the TestString as a pathname and tests whether or not it exists, and is a directory. |
'-f' | is regular file | Treats the TestString as a pathname and tests whether or not it exists, and is a regular file. |
'-s' | is regular file, with size | Treats the TestString as a pathname and tests whether or not it exists, and is a regular file with size greater than zero. |
'-l' | is symbolic link | Treats the TestString as a pathname and tests whether or not it exists, and is a symbolic link. |
'-x' | has executable permissions | Treats the TestString as a pathname and tests whether or not it exists, and has executable permissions. These permissions are determined according to the underlying OS. |
'-F' | is existing file, via sub-request | Checks whether or not TestString is a valid file, accessible via all the server's currently-configured access controls for that path. This uses an internal subrequest to do the check, so use it with care - it can impact your server's performance! |
'-U' | is existing URL, via subrequest | Checks whether or not TestString is a valid URL, accessible via all the server's currently-configured access controls for that path. This uses an internal subrequest to do the check, so use it with care - it can impact your server's performance! |
You can add special flags after CondPattern by appending [flags] as the third argument. flags is a comma-separated list of any of the following flags:
Flages | Short Description | Description |
---|---|---|
'nocase|NC' | test case-insensitive | This makes the test case-insensitive - differences between 'A-Z' and 'a-z' are ignored, both in the expanded TestString and the CondPattern. This flag is effective only for comparisons between TestString and CondPattern. It has no effect on filesystem and subrequest checks. |
'ornext|OR' | OR Operator | Use this to combine rule conditions with a local OR instead of the implicit AND. |
'novary|NV' | no vary | If a HTTP header is used in the condition, this flag prevents this header from being added to the Vary header of the response. Using this flag might break proper caching of the response if the representation of this response varies on the value of this header. So this flag should be only used if the meaning of the Vary header is well understood. |
Example:
RewriteCond %{REMOTE_HOST} =host1 [OR]
RewriteCond %{REMOTE_HOST} =host2 [OR]
RewriteCond %{REMOTE_HOST} =host3
RewriteRule ...some special stuff for any of these hosts...
To rewrite the Homepage of a site according to the User-Agent: header of the request, you can use the following:
RewriteCond %{HTTP_USER_AGENT} ^Mozilla
RewriteRule ^/$ /homepage.mozilla.html [L]
RewriteCond %{HTTP_USER_AGENT} ^Lynx
RewriteRule ^/$ /homepage.lynx.html [L]
RewriteRule ^/$ /homepage.standard.html [L]
<VirtualHost *:80>
RewriteEngine On
# Rewrite everything except the blog
RewriteCond %{REQUEST_URI} !^/blog
</VirtualHost>
The RewriteRule directive is the real rewriting workhorse. The directive can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important - this is the order in which they will be applied at run-time.
RewriteRule Pattern Substitution [flags]
where:
The Pattern will be matched
If you wish to match against the hostname, port, or query string, use a RewriteCond with the
Syntax:
RewriteLog file-path