web-dev-qa-db-fra.com

Boucle de redirection dans .htaccess lors de la suppression de la barre oblique finale

J'ai le fichier .htaccess suivant:

AddDefaultCharset utf-8
RewriteEngine on
Options +SymLinksIfOwnerMatch
RewriteBase /

# redirect all www-requests to no-www
# -
RewriteCond %{HTTP_Host} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

# redirect all home pages to / (root)
# -
RewriteCond %{THE_REQUEST} ^.*/index\.(php|html?)
RewriteRule ^(.*)index\.(php|html?)$ /$1 [R=301,L] 

# remove trailing slash from dirs
# -
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/$ /$1 [R=301,L]

# automatically add index.php when needed
# -
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|login\.php|reg\.php|robots\.txt|css/|js/)
RewriteRule ^(.*)$ /index.php [L]

Le fichier .htaccess doit effectuer les opérations suivantes (pour le référencement):

  1. La conversion en no-www (http://www.example.com devrait devenir http://example.com)
  2. Tous les URI avec des barres obliques de fin doivent être convertis en une barre oblique pas de fin: http://example.com/me/ doit être redirigé http://example.com/me
  3. Tous les URI avec index.php/index.html ne devraient être convertis en rien: http://example.com/admin/index.php ou http://example.com/admin/ devraient finalement être affichés sous la forme http://example.com.

Cependant, la version actuelle de .htaccess entraîne une redirection cyclique lorsque vous tentez d'accéder à http://example.com/admin. Le document réel qui doit être récupéré par le navigateur est http://example.com/admin/index.php.

Quelqu'un peut-il m'aider s'il vous plaît avec ce problème?

2
wh1t3cat1k

redirection cyclique lors de la tentative d'accès à http://example.com/admin. Le document réel qui doit être récupéré par le navigateur est http://example.com/admin/index.php

Puisque /admin est un répertoire physique, mod_dir "corrigera" l'URL en ajoutant une barre oblique finale. Ceci est réalisé via une redirection 301.

Toutefois...

# remove trailing slash from dirs
# -
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/$ /$1 [R=301,L]

Ces directives suppriment la barre oblique finale sur tout ce qui n'est pas un fichier (ce qui inclut naturellement les répertoires). Ceci est également réalisé via une redirection 301.

D'où la boucle "redirection cyclique"/redirect.

On peut soutenir que vous ne devriez pas supprimer la barre oblique finale des répertoires physiques (malgré le commentaire de code). Vous pouvez certainement supprimer la barre oblique finale des segments de chemin d'URL (ou "fichiers") qui ressemblent peut-être à des répertoires, mais pas des répertoires de système de fichiers physiques (OK, vous pouvez, mais cela nécessite plus de travail). Je ne sais pas pourquoi vous voudriez conserver la barre oblique finale sur les fichiers physiques (à moins que vous n'utilisiez PATH_INFO - mais il n'y a aucune preuve de cela ici - cela ressemble donc à une erreur). Donc, pour résoudre ce problème, il vous suffit de remplacer le contrôle !-f (pas un fichier) par le contrôle !-d (pas un répertoire). Par exemple:

# Remove trailing slash from everything except physical directories
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]

Supprimer la barre oblique finale des répertoires physiques

Vous pouvez supprimer la barre oblique finale des répertoires physiques, mais cela nécessite davantage de travail et de diligence, car vous allez vraiment à l'encontre du fonctionnement du système de fichiers. Les répertoires physiques nécessitent une barre oblique finale.

Pour supprimer la barre oblique de fin sur les répertoires physiques, vous devez:

  1. Empêche mod_dir de "réparer" l'URL en ajoutant une barre oblique finale aux répertoires:

    DirectorySlash Off
    
  2. Supprimez (redirigez) la barre oblique de fin sur toute URL demandée directement (à l'exception des demandes réécrites, comme dans le n ° 3):

    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^(.*)/$ /$1 [R=301,L]
    
  3. Ajouter (réécrire) la barre oblique de fin sur n'importe quel répertoire où il est absent:

    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule !/$ %{REQUEST_URI}/ [L]
    

Notez également le avertissement de sécurité dans la documentation Apache en ce qui concerne la directive DirectorySlash:

Avertissement de sécurité
La désactivation de la redirection de fin de barre oblique peut entraîner la divulgation d’informations. Prenons une situation où mod_autoindex est actif (Options +Indexes) et DirectoryIndex est défini sur une ressource valide (par exemple, index.html) et qu'aucun autre gestionnaire spécial n'est défini pour cette URL. Dans ce cas, une demande avec une barre oblique finale afficherait le fichier index.html. Mais une requête sans barre de fin afficherait le contenu du répertoire.

1
MrWhite

Je connais bien les expressions régulières, bien que je ne sois pas un expert, mais il semblerait que vous obteniez une boucle des conditions sous # redirect all home pages to / (root) et # automatically add index.php when needed

Il semble que le dernier bit puisse être la redirection de http://example.com/admin vers http://example.com/admin/index.php, qui tente de se charger puis est redirigé vers http://example.com/admin par le bit précédent.

Je pense tu n'as pas besoin du dernier bit. Sauf si votre serveur est configuré de manière incorrecte, http://example.com/admin devrait extraire automatiquement le document à http://example.com/admin/index.php

0
joshuahedlund