problem with nested rules

Oh, the strange things mod_rewrite does!

problem with nested rules

Postby needhelp » Thu Feb 14, 2008 2:51 pm

In one of my sites, www.whatever.com I prepared .htaccess file with rewrite rules that permanently redirect [r=301,nc] whatever.com to whatever.com/whatever/whatever.htm and then replace .htm files with corresponding .php files without 301 redirection, so that php would be completely hidden from the visitors.

I am pretty sure I tested it and it was working fine a few months ago. When I tried it today, I saw it showing php files instead, and all the links are, therefore, broken.

Here is my .htaccess file:

RewriteEngine on
Options +FollowSymLinks

# www.whatever.com -> www\.whatever\.com/whatever/whatever\.htm
RewriteCond %{HTTP_HOST} ^www\.whatever\.com$
RewriteRule ^index\.html*$ http://whatever\.com/whatever/whatever\.htm [r=301,nc]
RewriteCond %{HTTP_HOST} ^www\.whatever\.com$
RewriteRule ^$ http://www.whatever.com/whatever/whatever\.htm[r=301,nc]

# all htm to php, html stays
RewriteRule ^(.*)whatever/(.*)\.htm$ $1whatever\.php/$2.php

I expect the first set of rules 301 redirect www.whatever.com into www.whatever.com/whatever/whatever.htm, and it does it when I remove the last rule.

The last rule should convert resulting www.whatever.com/whatever/whatever.htm into
www.whatever.com/whatever.php/whatever.php, but since there is no 301 redirect in the last rule the visitors should still see www.whatever.com/whatever/whatever.htm in the browser address line! The problem is that they see www.whatever.com/whatever.php/whatever.php instead.

The last rule works correctly by itself, however.

Again, I am pretty sure I tested it and it was working fine a few months ago.

What could be the problem?

Thank you very much for your help,

-needhelp
needhelp
 
Posts: 6
Joined: Thu Feb 14, 2008 1:53 pm

Postby richardk » Fri Feb 15, 2008 1:18 pm

All the rules are processed and this is causing the problem. Use L to stop processing when a rule is matched
Code: Select all
Options +FollowSymLinks

RewriteEngine On

# www.whatever.com -> www.whatever.com/whatever/whatever.htm
# www.whatever.com/index.html -> www.whatever.com/whatever/whatever.htm
# www.whatever.com/index.htm -> www.whatever.com/whatever/whatever.htm
RewriteCond %{HTTP_HOST} ^www\.whatever\.com$ [NC]
RewriteRule ^(index\.html?)?$ http://whatever.com/whatever/whatever.htm [NC,R=301,L]

# All .htm to .php, .htm stays
RewriteRule ^whatever(/.+\.)htm$ /whatever.php$1php [NC,QSA,L]
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby needhelp » Sat Feb 16, 2008 10:22 pm

Richard,

Thank you very much for your help.

It did work after I added [NC,R=301,L] as you recommended. However, I still do not understand the logic there. After the first rule produced www.whatever.com/whatever/whatever.htm I do want the second rule to convert it to corresponding php. So, why do I mark the first rule with L?

Thanks again,
-needhelp
needhelp
 
Posts: 6
Joined: Thu Feb 14, 2008 1:53 pm

Postby richardk » Sun Feb 17, 2008 11:16 am

Without the L, it processes both rules then redirects (showing the .php). With the L, it processes the first rule, redirects and then processes the final rule.

L stops that round of processing (the redirect makes it a new request anyway), not all processing forever.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby needhelp » Sun Feb 17, 2008 7:45 pm

Now, I understand. Thank you very much, Richard.

One more question.

I noticed that you combined the first 2 rules into a single rule, which is obviously better.

You also changed my last rule
RewriteRule ^(.*)whatever/(.*)\.htm$ $1whatever\.php/$2.php
into
RewriteRule ^whatever(/.+\.)htm$ /whatever.php$1php [NC,QSA,L]

It certainly looks better than mine, but unfortunately I have hard time understaning it. Here is what I do not understand:

1. In mine $1 stands for www.whatever.com that preceeds the directory name. Why do you think it is unnecessary?
2. What is the advantage of using (/.+\.) instead of my /(.*)\. I do understand the reason of replacing * with +, but not combining (.+) with preceeding slash and the following dot.
3. What is the reason for QSA? (It seems to work without it too!)

Your answers will help me to become better "mod_rewriter". :wink:

Thank you again,

-needhelp
needhelp
 
Posts: 6
Joined: Thu Feb 14, 2008 1:53 pm

Postby richardk » Mon Feb 18, 2008 3:48 pm

1. In mine $1 stands for www.whatever.com that preceeds the directory name. Why do you think it is unnecessary?

Your $1 does not contain anything. The RewriteRule only matches the part of the URL after the directory the .htaccess file is in. So if you have a .htaccess file in /foo and go to example.com/foo/bar, the RewriteRule only matches bar.

2. What is the advantage of using (/.+\.) instead of my /(.*)\. I do understand the reason of replacing * with +, but not combining (.+) with preceeding slash and the following dot.

Just so you don't have to write it out again.

3. What is the reason for QSA? (It seems to work without it too!)

Query String Append:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule wrote:'qsappend|QSA' (query string append)
This flag forces the rewrite engine to append a query string part of the substitution string to the existing string, instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.

If you go to /whatever/a.htm?abc=def it would rewrite to /whatever.php/a.php?abc=def.
richardk
 
Posts: 8800
Joined: Wed Dec 21, 2005 7:50 am

Postby needhelp » Mon Feb 18, 2008 6:32 pm

Richard,

Now, I am much better "mod_rewriter". :)

Thank you for all your help,
-needhelp no more
needhelp
 
Posts: 6
Joined: Thu Feb 14, 2008 1:53 pm

Re: problem with nested rules

Postby needhelp » Tue Mar 27, 2012 3:28 pm

Hello Richard,

The following script worked for almost 2 years on my website hosted on 1and1.com server.
Yesterday it stopped working.

---------
RewriteEngine on
Options +FollowSymLinks

# http://www.WholesaleCarBattery.com -> http://www.WholesaleCarBattery.com/service/company.htm
RewriteCond %{HTTP_HOST} ^www\.WholesaleCarBattery\.com$ [NC]
RewriteRule ^(index\.html?)?$ http://www\.WholesaleCarBattery\.com/service/company\.htm [r=301,NC,L]

# all service/*.htm to service.php/*.php, html stays
RewriteRule ^service(/.+\.)htm$ /service.php$1php [NC,L]
---------

The first rule, which redirects http://www.wholesalecarbattery.com to http://www.wholesalecarbattery.com/service/company.htm
still works. However, the second rule that is supposed to silently redirect it to http://www.wholesalecarbattery.com/serv ... ompany.php
no longer works. The server just returns 404 error.

The same happened on all my other websites on 1and1 server that use similar mod_rewrite rules.

I tried to modify the rule to

RewriteRule ^service(/.+\.)htm$ /service\.php$1php [NC,L]

but that did not help.

Do you see any problems with the above rule?

Thank you again for all your help,
-needhelp
needhelp
 
Posts: 6
Joined: Thu Feb 14, 2008 1:53 pm


Return to Idiosyncrasies

Who is online

Users browsing this forum: No registered users and 8 guests

cron