RewriteRule Last flag [L] not working?

php_flag display_errors 1 php_value auto_prepend_file init.php RewriteEngine on RewriteRule ^$ /id/authenticate [R] RewriteRule ^login_openid$ /id/login_openid.php [QSA,L] RewriteRule ^authenticate$ /id/authenticate.php [QSA,L] RewriteRule ^facebook$ /id/facebook.php [QSA,L] RewriteRule ^createfromopenid$ /id/createfromopenid.php [QSA,L] RewriteRule .* - [L,R=403] 

This is my .htaccess file. In serverconfig, I just AllowOVerride all .

If I request the URL http://mydomain.com/id/authenticate , I get error 403. If I delete the last rule, it will work. Should the waist [L] hamper further rules?

Edit:

My htaccess file is located in the subfolder "id", so the rules work.

+26
url-rewriting apache mod-rewrite
Jul 23 '11 at 3:14
source share
2 answers

The rule [L] works just fine - you just don't know how it works .

When Apache sees the [L] flag and the rules match (rewriting happens), Apache will go to the next iteration and start matching all the rules from above again. The [L] flag means "do not process any rules below in this iteration ."

Yes, the Apache Documentation is not 100% understandable (which means it can be improved), but it provides enough information to understand this in the long run.




Apache will stop the rewrite cycle in several situations:

  • Compatible rules (without rewriting);

  • Complies with the rule "exit now" (for example, RewriteRule .* - [L] );

  • Rewriting happens, but the input URL and the ending URLs are the same (happens on the 2nd-3rd iteration, when a β€œbad” written rule rewrites the same URL to the same URL.

    For example RewriteRule (.*) /index.php?page=$1 [L] :

    • /hello => /index.php?page=hello
    • at the next iteration, he will rewrite /index.php => /index.php?page=index.php
    • and in the third iteration it will be /index.php => /index.php?page=index.php .., which now makes no sense);
  • The renaming iteration limit has been reached (default = 10) - if you enter an infinite rewrite cycle (the value is controlled by LimitInternalRecursion Directive ).




With all the above information, I can say that your current rules work as expected . This means that you need to change the logic and get rid of the last rule (maybe deal with this moment in the parent .htaccess .. or handle it differently - it all depends on how your application is built, I don’t want to make wild guesses) .

+68
Jul 23 '11 at 11:50
source share

Put this in front of your cath all rule.

 RewriteCond %{ENV:REDIRECT_STATUS} !=200 

The problem is that after processing the [L] flag, all of the following RewriteRules are really ignored, however, the file is processed from the beginning, now with a new URL.

This magic condition will not handle catch all if the file is already redirected.

PS: If this does not work, you may need to adjust the condition a little: 200 !=200 , ^. , ^$ .
Obviously, the variable gets a value of 200 for redirection, but other pages (error, etc.) set it for some value. Now this means that you are either checking if it is empty , is not empty , is 200 or is not 200 , depending on what you need.

+8
May 25 '14 at
source share



All Articles