Mod rewrite

From Deep Thought

Jump to: navigation, search

Contents


Debugging mod_rewrite

You can debug mod_rewrite rule process by adding these commands to your httpd.conf file:

RewriteLog /usr/local/apache/logs/lcleveland_rewrite.log
RewriteLogLevel 3

Tips & Tricks

Catch All Short Circuit

Rewrite rules in a .htaccess file often use a "catch all" when a website uses an all-inclusive application to run the site such as a Content Management System. In a recent study, we have found that performance can be increased by writing an exception to short circuit the catch-all rewriting at the top of the file.

In our very short rewrite ruleset the "catch all short circuit" is more than twice as efficient, showing a total of 22 v. 46 "processes" occurring internally on mod-rewrite.

See #Case Study 001 for an example of the "before the short circuit" analysis.

See #Case Study 002 for an example of an "after the short circuit" analysis.

Existing Files Short Circuit

As a follow up to the #Catch All Short Circuit Trick noted above, you can further reduce mod_rewrite processing by testing for the existence of a file or directory at the top of the rewrite rules. The added benefit is that after the catch-all page is rendered any URLs it references within the program, such as a directly referenced CSS file, are not required to run through the entire mod_rewrite ruleset.

In our very short rewrite ruleset the "preexisting file short circuit" is nearly three times as efficient when looking up an existing file, showing a total of 4 v. 11 "processes" occurring internally on mod-rewrite.


See #Case Study 003 for an example of the "before the short circuit" analysis.

See #Case Study 004 for an example of an "after the short circuit" analysis.

Case Studies

Case Study 001 : Before The Short Circuit

The .htaccess

Options -Indexes
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # Exceptions
  #
  RewriteCond %{REQUEST_URI} eyore/thankyou(.*)$
  RewriteRule eyore/thankyou(.*)$ wiki/index.php/Eyore_Installation_Instructions [L]

  RewriteCond %{REQUEST_URI} ^sitemap\.(.*)$
  RewriteRule sitemap\.(.*)$ libraries/sitemap.php?format=$1 [L,QSA]

  # The Catch All
  #
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.php?wij_redirect=$1 [L,QSA]
</IfModule>

The rewrite process for http://www.cybersprocket.com/the_crew

(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'the_crew'
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-f' => matched
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-d' => matched
(2) [per-dir /home/cyberspr/public_html/] rewrite the_crew -> index.php?wij_redirect=the_crew
(3) split uri=index.php?wij_redirect=the_crew -> uri=index.php, args=wij_redirect=the_crew
(3) [per-dir /home/cyberspr/public_html/] add per-dir prefix: index.php -> /home/cyberspr/public_html/index.php
(2) [per-dir /home/cyberspr/public_html/] trying to replace prefix /home/cyberspr/public_html/ with /
(5) strip matching prefix: /home/cyberspr/public_html/index.php -> index.php
(4) add subst prefix: index.php -> /index.php
(1) [per-dir /home/cyberspr/public_html/] internal redirect with /index.php [INTERNAL REDIRECT]
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'index.php'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'index.php'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'index.php'
(4) RewriteCond: input='/home/cyberspr/public_html/index.php' pattern='!-f' => not-matched
(1) [per-dir /home/cyberspr/public_html/] pass through /home/cyberspr/public_html/index.php
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'the_crew'
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-f' => matched
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-d' => matched
(2) [per-dir /home/cyberspr/public_html/] rewrite the_crew -> index.php?wij_redirect=the_crew
(3) split uri=index.php?wij_redirect=the_crew -> uri=index.php, args=wij_redirect=the_crew
(3) [per-dir /home/cyberspr/public_html/] add per-dir prefix: index.php -> /home/cyberspr/public_html/index.php
(2) [per-dir /home/cyberspr/public_html/] trying to replace prefix /home/cyberspr/public_html/ with /
(5) strip matching prefix: /home/cyberspr/public_html/index.php -> index.php
(4) add subst prefix: index.php -> /index.php
(1) [per-dir /home/cyberspr/public_html/] internal redirect with /index.php [INTERNAL REDIRECT]
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'index.php'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'index.php'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'index.php'
(4) RewriteCond: input='/home/cyberspr/public_html/index.php' pattern='!-f' => not-matched
(1) [per-dir /home/cyberspr/public_html/] pass through /home/cyberspr/public_html/index.php

Case Study 002: After The Short Circuit

The .htaccess:

Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

  # Short circuit the "catch all"
  #
  RewriteCond %{REQUEST_URI} ^/index.php(.*) 
  RewriteRule (.*) - [L]

  # Exceptions
  #
  RewriteCond %{REQUEST_URI} eyore/thankyou(.*)$
  RewriteRule eyore/thankyou(.*)$ wiki/index.php/Eyore_Installation_Instructions [L]

  RewriteCond %{REQUEST_URI} ^sitemap\.(.*)$
  RewriteRule sitemap\.(.*)$ libraries/sitemap.php?format=$1 [L,QSA]

  # The Catch All
  #
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.php?wij_redirect=$1 [L,QSA]
</IfModule>

The rewrite process:

(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'the_crew'
(4) RewriteCond: input='/the_crew' pattern='^/index.php(.*)' => not-matched
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'the_crew'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/the_crew -> the_crew
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'the_crew'
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-f' => matched
(4) RewriteCond: input='/home/cyberspr/public_html/the_crew' pattern='!-d' => matched
(2) [per-dir /home/cyberspr/public_html/] rewrite the_crew -> index.php?wij_redirect=the_crew
(3) split uri=index.php?wij_redirect=the_crew -> uri=index.php, args=wij_redirect=the_crew
(3) [per-dir /home/cyberspr/public_html/] add per-dir prefix: index.php -> /home/cyberspr/public_html/index.php
(2) [per-dir /home/cyberspr/public_html/] trying to replace prefix /home/cyberspr/public_html/ with /
(5) strip matching prefix: /home/cyberspr/public_html/index.php -> index.php
(4) add subst prefix: index.php -> /index.php
(1) [per-dir /home/cyberspr/public_html/] internal redirect with /index.php [INTERNAL REDIRECT]
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/index.php -> index.php
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'index.php'
(4) RewriteCond: input='/index.php' pattern='^/index.php(.*)' => matched
(1) [per-dir /home/cyberspr/public_html/] pass through /home/cyberspr/public_html/index.php

Case Study 003: Before File/Directory Short Circuit

URL:http://cybersprocket.com/unauthorized.html

.htaccess file:

Options -Indexes
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  RewriteCond %{REQUEST_URI} ^/index.php(.*) 
 RewriteRule (.*) - [L]

  RewriteCond %{REQUEST_URI} eyore/thankyou(.*)$
  RewriteRule eyore/thankyou(.*)$ wiki/index.php/Eyore_Installation_Instructions [L]

  RewriteCond %{REQUEST_URI} ^sitemap\.(.*)$
  RewriteRule sitemap\.(.*)$ libraries/sitemap.php?format=$1 [L,QSA]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.php?wij_redirect=$1 [L,QSA]
</IfModule>

Rewrite Log:

(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/unauthorized.html -> unauthorized.html
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'unauthorized.html'
(4) RewriteCond: input='/unauthorized.html' pattern='^/index.php(.*)' => not-matched
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/unauthorized.html -> unauthorized.html
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'eyore/thankyou(.*)$' to uri 'unauthorized.html'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/unauthorized.html -> unauthorized.html
(3) [per-dir /home/cyberspr/public_html/] applying pattern 'sitemap\.(.*)$' to uri 'unauthorized.html'
(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/unauthorized.html -> unauthorized.html
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'unauthorized.html'
(4) RewriteCond: input='/home/cyberspr/public_html/unauthorized.html' pattern='!-f' => not-matched
(1) [per-dir /home/cyberspr/public_html/] pass through /home/cyberspr/public_html/unauthorized.html

Case Study 004: After File/Directory Short Circuit

URL:http://cybersprocket.com/unauthorized.html

.htaccess:

Options -Indexes
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # If we are requesting a real file/directory
  # we are done
  #
  RewriteCond %{REQUEST_FILENAME} -f [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule (.*) - [L]

  # Exceptions to catch-all
  #
  RewriteCond %{REQUEST_URI} eyore/thankyou(.*)$
  RewriteRule eyore/thankyou(.*)$ wiki/index.php/Eyore_Installation_Instructions [L]

  RewriteCond %{REQUEST_URI} ^sitemap\.(.*)$
  RewriteRule sitemap\.(.*)$ libraries/sitemap.php?format=$1 [L,QSA]

  # Catch-all
  #
  RewriteRule (.*) index.php?wij_redirect=$1 [L,QSA]
</IfModule>

Rewrite Log:

(3) [per-dir /home/cyberspr/public_html/] strip per-dir prefix: /home/cyberspr/public_html/unauthorized.html -> unauthorized.html
(3) [per-dir /home/cyberspr/public_html/] applying pattern '(.*)' to uri 'unauthorized.html'
(4) RewriteCond: input='/home/cyberspr/public_html/unauthorized.html' pattern='-f' => matched
(1) [per-dir /home/cyberspr/public_html/] pass through /home/cyberspr/public_html/unauthorized.html

Issues Preventing Running of Mod_rewrite

We were having a problem with the site for a particular client, whose server is running Apache 2 on Ubuntu 6.06.2. While rewriting rules had been set in the .htaccess file, the rules were not being used. We found a 4 part solution to allow the .htaccess file to work.

1. Mod_rewrite does not have to be hard linked in Apache 2, rather it can be loaded on demanded. To enable this, set a link to the module:

$sudo a2enmod
Which module would you like to enable?
Your choices are: actions asis auth_anon auth_dbm auth_digest auth_ldap cache cern_meta cgid cgi dav_fs dav deflate disk_cache expires ext_filter file_cache headers imap include info ldap mem_cache mime_magic php5 proxy_connect proxy_ftp proxy_http proxy rewrite speling ssl suexec unique_id userdir usertrack vhost_alias
Module name? mime_magic
Module mime_magic installed; run /etc/init.d/apache2 force-reload to enable.

2. Edit /etc/apache2/sites-available/apache2.conf to set AllowOverride to FileInfo:

  <Directory /var/www/anchor>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride FileInfo
  UseCanonicalName Off
  Order allow,deny
  allow from all
  # Uncomment this directive is you want to see apache2's
  # default start page (in /apache2-default) when you go to /
  #RedirectMatch ^/$ /apache2-default/
  </Directory>


3. Comment out the IfModule statements in the .htaccess file:

  #<IfModule mod_rewrite.c>
  ErrorDocument 404 ./ouch.html

  RewriteEngine On
  RewriteBase /

  RewriteCond %{REQUEST_FILENAME} -f
  RewriteRule (.*) - [L]

  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*) index.php?wij_redirect=$1 [L,QSA]
  #</IfModule>

4. Restart Apache.

Related Links

Personal tools
Cyber Sprocket Labs
Cyber Sprocket Tech