mod_rewrite supprime une variable GET

J’essaie de prendre

example.com/home?lang=fr&foo=bar

et redirect vers

example.com/fr/home?foo=bar

j’ai essayé

RewriteCond %{QUERY_STRING} lang=([az]{2})&? RewriteRule ^(.*) /%1/$1 [R=307] 

mais je reçois une boucle de redirection. Cela est dû au fait que lang = fr n’est pas retiré de la chaîne de requête après le déplacement de fr en avant de la chaîne de requête. Cela se traduit par:

example.com/fr/fr/fr/fr/fr/fr/fr/fr/fr/ ….

je peux utiliser

  RewriteRule ^(.*) /%1/$1? [R=307] 

mais cela supprime également la barre foo = de la chaîne de requête que je veux garder intacte

Je ne peux pas trouver un moyen de supprimer une seule variable de la chaîne de requête. Je suis sûr qu’il existe une solution simple, mais Google n’a pas aidé. Merci

En complément de @whoisgregg answer (+1), qui est une belle adaptation du wiki apache. Les règles ne sont pas très compliquées (par exemple, le contrôle d’access par chaîne de requête sur cette page ne résiste pas à un petit encodage d’url).

Nous avons une solution de travail pour le scénario de test, mais certains tests étendus peuvent échouer:

 RewriteCond %{QUERY_STRING} ^(.*)lang=([az]{2})&?(.*)$ RewriteRule (.*) /%2/$1?%1%3 [R=307] foo.php?foo=bar&novlang=fr&toto=titi => /fr/foo.php?foo=bar&novtoto=titi 

Ici, la partie lang= est détectée mais si un paramètre se termine par lang, vous aurez un problème.

Donc, nous avons besoin de correctifs, j’ai travaillé sur ce sujet cette semaine et voici une meilleure version je pense:

 RewriteCond %{QUERY_STRING} (.*)(^|&|%26|%20)lang(=|%3D)([^&]+)(.*)$ RewriteRule (.*) /%4/$1?%1%5 [R=307] foo.php?foo=bar&novlang=fr&toto=titi => not matched (normal, no lang=) foo.php?foo=bar&lang=fr&toto=titi&b=a => fr/foo.php?foo=bar&toto=titi&a=b 

Le seul problème en suspens ici est que lang pourrait être partiellement ou complètement encodé en url et ne serait pas détecté, mais c’est un cas rare. J’ai également supprimé le contrôle d’avoir seulement 2 caractères sur la valeur du langage. Je pense que ([^&]+) est meilleur, cela signifie tous les caractères jusqu’à ce que je corresponde à un & .

C’est une variante d’une technique du wiki apache qui devrait faire l’affaire:

 RewriteCond %{QUERY_STRING} ^(.*)lang=([az]{2})&?(.*)$ RewriteRule (.*) /%2/$1?%1%3 [R=307]