Cheat Sheet: Apache's mod_rewrite
Introduction
I was recently requested to document common Apache rewrite pitfalls and examples. As a result, I have crafted the following document. It is intended as a two page document where the first page is a reference guide of commonly used rewrite variables and flags; the second page is a short list of examples, gotchas, and troubleshooting advice.
Rewrite Cheat Sheet
Common Variables
HTTP Headers
- HTTP_USER_AGENT
- HTTP_REFERER
- HTTP_COOKIE
- HTTP_FORWARDED
- HTTP_HOST
- HTTP_PROXY_CONNECTION
- HTTP_ACCEPT
Connection & Request
- REMOTE_ADDR
- REMOTE_HOST
- REMOTE_PORT
- REMOTE_USER
- REMOTE_IDENT
- REQUEST_METHOD
- SCRIPT_FILENAME
- PATH_INFO
- QUERY_STRING
- AUTH_TYPE
Server Internals
- DOCUMENT_ROOT
- SERVER_ADMIN
- SERVER_NAME
- SERVER_ADDR
- SERVER_PORT
- SERVER_PROTOCOL
- SERVER_SOFTWARE
Date and Time
- TIME_YEAR
- TIME_MON
- TIME_DAY
- TIME_HOUR
- TIME_MIN
- TIME_SEC
- TIME_WDAY
- TIME
Specials
- API_VERSION
- THE_REQUEST
- REQUEST_URI
- REQUEST_FILENAME
- IS_SUBREQ
- HTTPS
Variable Descriptions
REQUEST_FILENAME: | |
---|---|
The full local filesystem path to the file or script matching the request, if this has already been determined by the server at the time REQUEST_FILENAME is referenced. Otherwise, such as wehn used in virtual host context, the same value as REQUEST_URI. | |
HTTPS: | Will contain the text "on" if the connection is using SSL/TLS, or "off" otherwise. (This variable can be safely used regardless of whether or not mod_ssl is loaded.) |
Flag Descriptions
nocase|NC: | This makes the test case-insensitive — differences between uppercase (i.e. A, B, C, &c) and lowercase (i.e. a, b, c, %c) are ignored, both in the expanded TestString and the CondPattern. |
---|---|
last|L: | Stop the rewriting process immediately and don't apply any more rules. |
proxy|P: | Force the substitution URL to be internally sent as a proxy request. |
qsappend|QSA: | Appends any query string created in the rewrite target to any query string that was in the original request URL. |
redirect|R[=code]: | |
Forces an external redirect, optionally with the specified HTTP status code. | |
forbidden|F: | Returns a 403 FORBIDDEN response to the client browser. |
Good Examples
Add www to the domain of all requests:
RewriteCond %{HTTP_HOST} !^www [NC] RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
Force all requests to HTTPS:
RewriteCond %{HTTPS} off RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
Redirect a specific subweb to another domain:
RewriteRule ^/?subweb/(.*) https://other.example.com/$1 [R,L,QSA]
Block specific IPs from access:
RewriteCond %{REMOTE_ADDR} ^127.0.0 RewriteRule ^ - [F,L]
Creating a filesystem alias with mod_rewrite:
RewriteRule ~/?alias/(.*) /var/www/vhosts/$1/httpdocs/$1 [L,R]
A condition that stops CMS software from over-riding fullstatus (added before the offending rewriterule):
RewriteCond %{REQUEST_URI} !server-status [NC]
Bad Examples
Recursive rewrites:
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
Gotchas
Some rewrites may conflict with existing rewrites provided by CMS packages (i.e. wordpress, drupal, &c). Check for any existing rewrites in an .htaccess file.
RewriteRule and RewriteCond can only be used in the following contexts:
- server config
- virtual host
- directory
- .htaccess
Common Troubleshooting
-
Enable logging with RewriteLog and RewriteLogLevel; example:
RewriteLog <file path> RewriteLogLevel 3 # range: 0 — 9
-
Check the regular expressions with a PCRE checker; many can be found on the Internet
-
Utilize curl to test redirects, R, curl -I example.com
Comments
Comments powered by Disqus