2 votes

mod_rewrite ajoute mystérieusement un sous-dossier à l'url réécrite

EDIT : [Résolu] J'ai finalement trouvé la solution dans la documentation ; j'ai posté une réponse. En bref : le DPI drapeau.

EDITAR: au bas de la page, a ajouté un moyen facile de reproduire le problème en ligne.

J'ai passé quelques heures à déboguer certaines réécritures. Tout va bien sauf un comportement qui me laisse perplexe.

D'une manière ou d'une autre, lorsqu'on lui fournit une url avec deux sous-répertoires ou plus, mod_rewrite ajoute automatiquement tous les sous-répertoires (sauf le premier) à l'url réécrite. Voici l'exemple le plus simple auquel j'ai pu le réduire. C'est dans un htaccess à DOCUMENT_ROOT .

  • url : http://localhost/stripthis/stripthat
  • RewriteRule ^ RewriteWasHere_
  • Sortie : RewriteWasHere_/stripthat

Où cela s'est-il produit ? stripthat d'où vient-elle ? Une option en amont pourrait-elle être à l'origine de ce problème ?

J'ai essayé de supprimer les sous-dossiers à l'aide de diverses règles. Par exemple :

  • url : http://localhost/stripthis/stripthat
  • RewriteRule ^/?([^/]+) RewriteWasHere_$1
  • Sortie : RewriteWasHere_stripthis/stripthat

Curieusement, cela se produit à la fois sur un xampp local x Apache 2.4.7 et sur un CentOS x Apache 2.2 distant.

J'ai inspecté les urls réécrites en les envoyant vers un script, mais voici un moyen de reproduire le problème en ligne.

Comment reproduire cela en ligne

Pour les règles, collez ceci :

# the `(?!)` negative lookaheads are just to make triple sure
# we're not running the same rules multiple times
RewriteRule ^(?!m[yo])([^/]+) my_$1
#RewriteRule ^(?!mo])\D*(\d+) mo_$1:$1:$1
  1. Exécution : le résultat est http://example.com/my_a/123/b
  2. Décommenter la deuxième ligne.
  3. Exécution : le résultat est http://example.com/mo_123:123:123/b
  4. Commentez la deuxième ligne, remplacez la première ligne par RewriteRule ^(?!m[yo])([^/]+).*$ my_$1 : le problème disparaît sur ce site, mais pas sur mes serveurs.

Toute information serait très appréciée.

3voto

zx81 Points 151

[DPI] (discardpathinfo)

Après des heures de tests et de perplexité, je suis retourné à l'adresse suivante la documentation et a trouvé la solution : le [DPI] drapeau.

L'indicateur DPI fait en sorte que la partie PATH_INFO du fichier réécrite.

Ce drapeau est disponible à partir de la version 2.2.12.

Dans le contexte d'un répertoire, l'URI auquel chaque RewriteRule se compare est le suivant la concaténation des valeurs actuelles de l'URI et de PATH_INFO.

L'URI actuel peut être l'URI initial comme suit résultat d'un traitement mod_rewrite antérieur, ou le résultat d'une d'une règle antérieure dans le cycle actuel de traitement mod_rewrite.

En revanche, le PATH_INFO qui est ajouté à l'URI avant chaque ne reflète que la valeur de PATH_INFO avant ce cycle de mod_rewrite. Par conséquent, si de grandes parties de l'URI sont comparées et copiées dans une substitution dans plusieurs directives RewriteRule sans tenir compte des parties de l'URI qui proviennent de la directive PATH_INFO actuel, l'URI final peut avoir plusieurs copies de PATH_INFO qui lui sont annexées.

Utilisez cet indicateur pour toute substitution où de cette requête au système de fichiers n'est pas intéressant. n'est pas intéressant. Cette option oublie définitivement le PATH_INFO établi avant le début de ce cycle de traitement par mod_rewrite. PATH_INFO ne sera pas sera pas recalculé avant la fin du cycle de traitement mod_rewrite en cours. se termine. Les règles ultérieures au cours de ce cycle de traitement ne verront que le résultat direct des substitutions. uniquement le résultat direct des substitutions, sans aucun ajout de PATH_INFO. n'est ajouté.

-1voto

cnst Points 12508

Il vous manque peut-être la virgule $ dans votre RewriteRule expression, d'où le fait que les éléments ne sont pas entièrement compatibles ?

Vous pourriez envisager de passer à nginx ; sa documentation est très claire et raisonnable, sans le gonflement et le non-déterminisme qui font la réputation d'Apache.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X