Linux-Apache-ModRewrite

From DevRandom

Jump to: navigation, search

Notes

  • REQUEST_URI is URL minus http:// & anything after the ?
  •  ? makes single character match optional and importantly makes the match non-greedy.

Consider the string "indian" and the need to match any character followed by n

(.*?)n will stop at the first n

(.*)n will parse through the whole string

with (.*)n $1 = "india"

with (.*?)n $1 = "i"

To further demonstrate with perl

# echo "indian" | perl -pe 's|(.*)n|R|'
R
# echo "indian" | perl -pe 's|(.*?)n|R|'
Rdian
  • RewriteCond is tried only if RewriteRule is matched. So in the order of execution, RewriteRule comes first.

If the rule matches, then the condition is checked and if the condition is satisfied the rule is executed.

  • Rewrite Rules run before the authentication phase.
  • Entries in RewriteMap are case sensitive and this cannot be overridden.
  • RewriteMap & RewriteLog are not allowed in htaccess
  • RewriteCond rules are additive by default
  • Cookies can be used for one time redirection
  • Besides rewriting URLs, mod_rewrite can be used for proxying, access control & virtual hosting. In almost all cases, it better to use a module

like mod_proxy, mod_access, mod_vhost or mod_vhost_alias. They do a better job and provide better performance.


Examples

Redirect all requests to www.example.com

RewriteEngine On
RewriteCond %{HTTP_HOST}        !^www.example.com
RewriteRule ^.*?$                http://www.example.com/


Redirect all to a sub folder /example to /example/newsite

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/example/newsite/.*$
RewriteRule ^(.*)$ public/$1 [NC]


Provide www.username.example.com for the homepage of username via just DNS A records to the same machine and without any virtualhosts on this machine

RewriteEngine on
RewriteCond   %{HTTP_HOST}                 ^www\.[^.]+\.example\.com$
RewriteRule   ^(.+)                        %{HTTP_HOST}$1          [C]
RewriteRule   ^www\.([^.]+)\.example\.com(.*) /home/$1$2


Search pages in more than one directory

RewriteEngine on

#   first try to find it in custom/...
RewriteCond         /docroot/dir1/%{REQUEST_FILENAME}  -f
RewriteRule  ^(.+)  /docroot/dir1/$1  [L]

#   second try to find it in pub/...
RewriteCond         /docroot/dir2/%{REQUEST_FILENAME}  -f
RewriteRule  ^(.+)  /docroot/dir2/$1  [L]


Time based rewriting

RewriteEngine on
RewriteCond   %{TIME_HOUR}%{TIME_MIN} >0700
RewriteCond   %{TIME_HOUR}%{TIME_MIN} <1900
RewriteRule   ^foo\.html$             foo.day.html
RewriteRule   ^foo\.html$             foo.night.html


Content based on username Redirect to the users folder based on the user named provided in the authentication scheme

http://example.com/protected/<username> is rewritten to http://example.com/protected/<{REMOTE USERNAME}>

Note: This needs to be tied with authentication directives and directory /var/www/sriramrajan.com/protected must be protected by it.

RewriteEngine On
RewriteCond %{LA-U:remote_user} !^$
RewriteRule ^/protected(.*) /var/www/example.com/protected/%{LA-U:remote_user}/$1   


Randomized content

Load a random image from a rewrite map

RewriteMap loadrandom rnd:/etc/httpd/conf/randompic.rnd
RewriteRule ^/nicepic.jpg /randompic/${loadrandom:nicepic}.jpg
RewriteRule ^/garbage.jpg /randompic/${loadrandom:garbage}.jpg

The rnd file contains he following

nicepic	photo1|photo2|photo3
garbage	photo7|photo6|photo5

Or a poor mans load balancer. Note there are better ways to load balance in Apache also. This is just a demonstration of how mod_rewrite can be used to do that.

RewriteEngine On
RewriteMap loadradom rnd:/etc/httpd/conf/imageservers.rnd
RewriteRule ^/(.*\.png|jpg)) http://${loadrandom:images}/$1 [NC,P,L]

imageservers.rnd contains the followng

images   servera|serverb


Clean URLS

Map the URLS to a query argument.

http://example.com/search
http://example.com/search/country/US
http://example.com/search/country/UK/London
http://example.com/search/country/UK/London/Essex
to
http://example.com/search.php
http://example.com/search.php?country=US
http://example.com/search.php?country=UK&city=London
http://example.com/search.php?country=UK&city=London&county=Essex

The rule looks like this

RewriteWEngine On
RewriteRule ^/search/?([^/]*)/?([^/]*)/?([^/]*)/?  http://example.com/search.php?country=$1&city=$2&county=$3 [PT]


Redirecting based on User Agents

Note, HTTP_USER_AGENT is reasonably easy to fake. So don't rely on this for any security specific feature.

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT}  MSIE [NC]
RewriteRule /index.php /index-IE.php? [L,R]


One time redirect

Redirect once per session using cookies. This will break user bookmarks.

RewriteEngine On
RewriteCond %{HTTP_COOKIE}  !alreadyhere=1
RewriteRule .* /index.php [R,L]
RewriteRule /index.php - [CO=alreadyhere:1:.example.com]

Rewrite www.subdomain.domain.com to subdomain.domain.com

Credit: Shawn Warren

RewriteCond %{HTTP_HOST} !^subdomain.example.com$ [NC] 
RewriteCond %{HTTP_HOST} ^(www.)?([a-z0-9-]+).example.com [NC] 
RewriteRule (.*) http://%2.example.com [NC,L]

The first line states, match if the HTTP_HOST is not subdomain.example.com.

The second line states, if the HTTP_HOST begins with 'www' followed by any combination of letters and numbers to form the subdomain name; then match. The first set of '()' form the first back-trace of this rewrite rule, represented by a %1. I have included two back-traces in this rewrite rule but we only reference the second back-trace, %2.

The third and final line is the actual rewrite rule that will take the second back-trace, %2, and rewrite that in place of the subdomain name.

Resources

http://www.addedbytes.com/cheat-sheets/mod_rewrite-cheat-sheet/

http://www.amazon.com/exec/obidos/asin/1590595610/drbacchus

http://httpd.apache.org/docs/2.0/es/misc/rewriteguide.html

Views
Personal tools
About Me

Blog

Contact Me

Resume

Photos