RewriteRule dernier drapeau [L] ne fonctionne pas?

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]

C'est mon .fichier htaccess. Dans le serverconfig j'ai juste AllowOVerride all.

Si je demande L'URL http://mydomain.com/id/authenticate je reçois une erreur 403. Si je supprime la dernière règle, cela fonctionne. Le [L] plat ne devrait-il pas empêcher d'autres règles de se produire?

Modifier:

Mon fichier htaccess se trouve dans le sous-dossier "id", donc les règles fonctionnent.

27
demandé sur The Surrican 2011-07-23 07:14:19

2 réponses

La règle [L] fonctionne bien - vous ne savez tout simplement pas comment fonctionne réellement .

Quand Apache voit le drapeau [L] et les correspondances de règle (réécriture se produit), Apache ira à itération suivante et commencera à faire correspondre Toutes les règles à partir du haut. L'indicateur [L] signifie " Ne pas traiter les règles ci-dessous dans cette itération".

Oui, le documentation Apache n'est pas 100% clair à ce sujet (ce qui signifie qu'il peut être amélioré), mais fournit suffisamment d'informations pour le comprendre éventuellement.


Apache arrêtera le cycle de réécriture dans quelques situations:

  1. Aucune règle ne correspond (aucune réécriture n'a eu lieu);

  2. "quitter maintenant" règle appariée (par exemple RewriteRule .* - [L]);

  3. La réécriture se produit, mais L'URL d'entrée et les URL finales sont les mêmes (se produit lors de la 2ème-3ème itération lorsque la règle" mal " écrite réécrit la même URL vers la même URL.

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

    • /hello => /index.php?page=hello
    • lors de la prochaine itération, il réécrira /index.php => /index.php?page=index.php
    • et sur la 3ème itération, il sera /index.php => /index.php?page=index.php .. ce qui n'a aucun sens maintenant);
  4. La limite D'itération de réécriture est atteinte ( par défaut = 10) - c'est si vous avez entré un cycle de réécriture infini (la valeur est contrôlée par la Directive LimitInternalRecursion).


Avec toutes les informations susmentionnées, je peux dire que vos règles actuelles fonctionnent comme attendu. Cela signifie que vous devez changer la logique et vous débarrasser de la dernière règle (peut-être gérer ce moment en parent .htaccess .. ou gérer différemment-tout dépend de la façon dont votre application est construite, je ne veux pas faire des suppositions sauvages).

71
répondu LazyOne 2011-07-23 11:50:28

Mettez ceci devant votre règle cath all.

RewriteCond %{ENV:REDIRECT_STATUS} !=200

Le problème est qu'une fois l'indicateur [L] traité, toutes les RewriteRules suivantes sont en effet ignorées, cependant, le fichier est traité à nouveau depuis le début, maintenant avec la nouvelle url.

Cette condition magique ne traitera pas le catch all si le fichier a déjà été redirigé.

PS: Si cela ne fonctionne pas, vous devrez peut-être modifier la condition un peu: 200, !=200, ^., ^$.
Apparemment, la variable est définie sur 200 pour une redirection, mais aussi d'autres pages (erreur et autres), définissez-le sur une certaine valeur. Maintenant cela signifie que vous vérifiez si c'est is empty, is not empty, is 200 ou is not 200, selon ce dont vous avez besoin.

9
répondu Qwerty 2014-05-25 00:19:28