Introduction
I was recently requested to document common apache rewrite pitfalls and examples and crafted the following document as a response. It is intended as a two page document (Rewrite Cheat Sheet) where the first page is a reference guide of commonly used rewrite variables and flags and 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_FILENAMEis referenced. Otherwise, such as when used in virtual host context, the same value asREQUEST_URI.
- 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
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_sslis loaded).
- 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
Flag Descriptions
- ‘
nocase|NC‘ (no case) :: This makes the test case-insensitive – differences between ‘A-Z’ and ‘a-z’ are ignored, both in the expanded TestString and the CondPattern. - ‘
ornext|OR‘ (or next condition) (RewriteCond Only) :: Use this to combine rule conditions with a local OR instead of the implicit AND. - ‘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
- Adding www to all requests
- RewriteCond %{HTTP_HOST} !^www [NC]
- RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
- Forcing 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/(.*) http://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 modrewrite
- RewriteRule ^/?alias/(.*) /var/www/vhosts/$1/httpdocs/$1 [L,R]
- A condition to stop CMS software from over-riding fullstatus (added before the offending rewriterule)
- RewriteCond ${REQUEST_URI} !server-status [NC]
Bad Examples
- Recursive rewrite
- RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R,L,QSA]
Gotchas
- Some rewrites may conflict with existing rewrites provided by many CMS packages (wordpress, drupal, joomla, etc). Check for any existing rewrites in a .htaccess file.
- Rewriterule and rewritecond can only be used in the following contexts: server config, virtual host, directory, .htaccess
Common Troubleshooting
- Enable the rewrite logs with RewriteLog and RewriteLevel
- RewriteLog <file path>
- RewriteLogLevel 3 # ranges from 0 to 9
- Check your regular expressions against a PCRE checker (they are very bountiful on the Internet [http://tinyurl.com/3hop7xu]).
- Utilize curl to test redirects (R), `curl -I example.com`