Forum Moderators: phranque

Message Too Old, No Replies

Rewrite Rules in httpd.conf

         

s_i_v

7:42 am on May 10, 2007 (gmt 0)

10+ Year Member



We have extensively used rewrites (around 250 rewrite rules) in .htaccess and its affecting the performance badly. We initially tried to have the rewrite rules in httpd.conf, but did not work.

We dont need any directory specific redirects. Will rewrite rules work if placed in httpd.conf?

Are there any other ways to tune rewrites?

phranque

12:51 pm on May 10, 2007 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



there are subtle differences between server config and per-directory usage of rewriterule to be aware of.
from the apache rewriterule doc [httpd.apache.org]:
Never forget that Pattern is applied to a complete URL in per-server configuration files. However, in per-directory configuration files, the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done. This feature is essential for many sorts of rewriting - without this, you would always have to match the parent directory which is not always possible.

jdMorgan

4:25 pm on May 10, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



In short, the following rules, one for use in .htaccess and the other for use in http.conf, or conf.d, etc., are functionallly equivalent:

In /.htaccess:
RewriteRule ^index\.html$ /index.php [L]

In httpd.conf:
RewriteRule ^/index\.html$ /index.php [L]

In other words, when coding in .htaccess, the URL-path matched by the RewriteRule pattern will not include the path to the current directory. So, in the case above, the leading slash is stripped before the RewriteRule in .htaccess 'sees' it. To make it even clearer, take the case where the .htaccess file and the rule are in a subdirectory:

In /foo/.htaccess:
RewriteRule ^index\.html$ /foo/index.php [L]

In httpd.conf:
RewriteRule ^/foo/index\.html$ /foo/index.php [L]

Also, look at your regular-expressions patterns carefully: Are they as specific as possible, or do you have a bunch of patterns with multiple instances of ".*" in them? That is a sure sign of inefficient pattern-coding. If it is not possible to determine what characters you want to match, then how about determining what characters you don't want to match? Example:

# Replace underscore with hyphen
RewriteRule ^(.*)_(.*)$ http://www.example.com/$1-$2 [R=301,L]

can be much more efficiently coded as:
RewriteRule ^([^_]*)_(.*)$ http://www.example.com/$1-$2 [R=301,L]

In the first case, we tell the parser to match any and all characters into the first pattern, because the first pattern accepts any number of any characters. So, it does that, and the match fails because the rest of the pattern is 'starved' by having no characters left to match. So the parser retries -- this time taking one character out of the first match, and trying it against the remainder of the pattern. This can repeat N-1 times, where N is the number of characters in the requested URL. If three or more ".*" patterns are used, the number of retries increases geometrically, and can reach ridiculous numbers.

In the second case, in the first sub-pattern, we tell the parser, "match any number of characters NOT equal to an underscore." Therefore, we tell the parser exactly what character should terminate a matching attempt for the first sub-pattern. This is much more efficient.

Jim