<-
Apache > Serveur HTTP > Documentation > Version 2.3 > Modules

Module Apache mod_rewrite

Langues Disponibles:  en  |  fr 

Description:Ce module fournit un moteur de réécriture à base de règles permettant de réécrire les URLs des requêtes à la volée
Statut:Extension
Identificateur de Module:rewrite_module
Fichier Source:mod_rewrite.c
Compatibilité:Disponible à partir de la version 1.3 d'Apache

Sommaire

Ce module utilise un moteur de réécriture à base de règles (basé sur un interpréteur d'expressions rationnelles) pour réécrire les URLs des requêtes à la volée. Il accepte un nombre illimité de règles, ainsi q'un nombre illimité de conditions attachées à chaque règle, fournissant ainsi un mécanisme de manipulation d'URL vraiment souple et puissant. Les manipulations d'URL peuvent dépendre de nombreux tests, des variables du serveur, des variables d'environnement, des en-têtes HTTP ou de l'horodatage. On peut même lancer des requêtes vers une base de données externe sous divers formats, afin d'obtenir une sélection d'URL très fine.

Ce module agit sur l'ensemble de l'URL (la partie concernant le chemin incluse) au niveau du serveur (httpd.conf) mais aussi au niveau du répertoire (.htaccess), et peut inclure des arguments de chaîne de requête (query string) comme résultat. Le résultat de la réécriture peut renvoyer vers un sous-traitement interne, une redirection vers une requête externe, ou même vers le flux d'un proxy interne.

Vous trouverez d'avantage de détails, discussions et exemples dans la documentation détaillée sur mod_rewrite.

Directives

Sujets

Voir aussi

top

Marquage des caractères spéciaux

Depuis Apache 1.3.20, les caractères spéciaux dans les chaînes de test et les chaînes de Substitution peuvent être échappés (c'est à dire traités comme des caractères normaux sans tenir compte de leur signification en tant que caractère spécial), en les faisant précéder d'un caractère anti-slash ('\'). En d'autres termes, vous pouvez inclure un véritable signe "dollar" dans une chaîne de Substitution en utilisant '\$' ; ceci empêche mod_rewrite de le traiter comme une référence arrière.

top

Variables d'environnement

Ce module conserve le contenu de deux variables d'environnement CGI/SSI additionnelles (non standards) nommées SCRIPT_URL et SCRIPT_URI. Celles-ci contiennent l'adresse logique vue du Web de la ressource concernée, tandis que les variables CGI/SSI standards SCRIPT_NAME et SCRIPT_FILENAME contiennent l'adresse physique de la ressource vue du système.

Note : ces variables conservent l'URI/URL telle qu'elle était à l'arrivée de la requête, c'est à dire avant tout processus de réécriture. Il est important de le savoir car le processus de réécriture est principalement utilisé pour réécrire des URLs logiques en chemins physiques.
Ces variables sont définies dans un contexte du niveau serveur, ce qui signifie qu'elles ne sont disponibles que dans un contexte de répertoire, si RewriteEngine est positionné à on dans un contexte de niveau serveur.

Exemple

SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html
SCRIPT_FILENAME=/u/rse/.www/index.html
SCRIPT_URL=/u/rse/
SCRIPT_URI=http://en1.engelschall.com/u/rse/
top

Réécriture et hôtes virtuels

Par défaut, les hôtes virtuels n'héritent pas de la configuration de mod_rewrite telle qu'elle est définie dans le contexte du serveur principal. Pour que la configuration du serveur principal s'applique aux hôtes virtuels, vous devez insérez les directives suivantes dans chaque section <VirtualHost> :

RewriteEngine On
RewriteOptions Inherit

top

Solutions pratiques

Vous trouverez de nombreux exemples d'utilisation courante (et moins courante) de mod_rewrite dans le Guide de réécriture, et dans le Guide de réécriture avancée.

top

RewriteBase Directive

Description:Définit l'URL de base pour les réécritures au niveau répertoire
Syntaxe:RewriteBase chemin URL
Défaut:Voir utilisation pour plus d'informations.
Contexte:répertoire, .htaccess
Annuler:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteBase définit explicitement l'URL de base pour les réécritures au niveau du répertoire. Comme vous le verrez plus loin, la directive RewriteRule peut être utilisée dans les fichiers de configuration au niveau du répertoire (.htaccess). Elle agit alors localement, en amputant le répertoire local de son préfixe avant traitement, et en n'appliquant les règles de réécriture que sur ce qui reste de l'URL. Lorsque le traitement est terminé, le préfixe est automatiquement rajouté à l'URL. La valeur par défaut est RewriteBase chemin répertoire physique

Lorsqu'une substitution intervient pour une nouvelle URL, ce module doit réinjecter l'URL dans le traitement du serveur. Pour y parvenir, il doit connaître le préfixe de l'URL ou l'URL de base correspondants. Par défaut, le préfixe est le chemin du fichier correspondant lui-même. Cependant, pour la plupart des sites web, les URLs ne correspondent PAS directement aux chemins des fichiers physiques, cette assertion s'avère ainsi souvent fausse !. C'est pourquoi vous pouvez utiliser la directive RewriteBase pour spécifier le préfixe correct.

Si les URLs de votre serveur web ne correspondent pas directement aux chemins physiques des fichiers, vous devrez utiliser RewriteBase dans chaque fichier .htaccess où vous voudrez utiliser des directives RewriteRule.

Par exemple, considérons le fichier de configuration de répertoire suivant :

#
#  /abc/def/.htaccess -- fichier de configuration pour le répertoire
/abc/def
#  Rappel : /abc/def est le chemin physique de /xyz,
#  ce qui veut dire que la configuration du serveur comporte
#  une directive du style 'Alias /xyz /abc/def'.
#

RewriteEngine On

#  faisons savoir au serveur qu'on nous a atteint via /xyz et non par
#  le chemin physique /abc/def
RewriteBase   /xyz

#  maintenant les règles de réécriture
RewriteRule   ^avant\.html$  après.html

Dans l'exemple précédent, une requête pour /xyz/avant.html sera correctement réécrite sous sous sa forme chemin physique /abc/def/après.html.

Pour les hackers d'Apache

La liste suivante fournit des informations détaillées à propos des étapes du traitement interne :

Requête :
  /xyz/avant.html

Traitement interne :
  /xyz/avant.html     -> /abc/def/avant.html  (Alias au niveau serveur)
  /abc/def/avant.html -> /abc/def/après.html  (RewriteRule au niveau répertoire)
  /abc/def/après.html -> /xyz/après.html      (RewriteBase au niveau répertoire)
  /xyz/après.html     -> /abc/def/après.html  (Alias au niveau serveur)

Résultat :
  /abc/def/après.html

Tout ceci paraît très compliqué, mais correspond réellement au traitement interne d'Apache. Comme la réécriture au niveau du répertoire intervient plus tard au cours du traitement, la requête de réécriture doit être réinjectée dans le noyau d'Apache, comme s'il s'agissait d'une nouvelle requête (Voir les détails techniques à propos de mod_rewrite). La surcharge correspondante n'est pas aussi importante qu'il n'y paraît, car la réinjection est entièrement prise en charge en interne par Apache (comme c'est d'ailleurs le cas pour de nombreuses autres opérations effectuées à l'intérieur d'Apache).

top

RewriteCond Directive

Description:Définit une condition qui devra être satisfaite pour que la réécriture soit effectuée
Syntaxe: RewriteCond chaîne de test expression de comparaison
Contexte:configuration du serveur, serveur virtuel, répertoire, .htaccess
Annuler:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteCond définit une condition d'application d'une certaine règle. Une ou plusieurs directives RewriteCond peuvent précéder une directive RewriteRule. La règle qui suit n'est appliquée que si l'état actuel de l'URI correspond à son modèle, et si les conditions sont satisfaites.

chaîne de test est une chaîne de caractères qui peut contenir, en plus du texte plat, les constructions étendues suivantes :

Autres points à connaître :

  1. Les variables SCRIPT_FILENAME et REQUEST_FILENAME ont la même valeur - celle du champ filename de la structure interne du serveur Apache request_rec. Le premier nom est bien connu en tant que variable CGI, alors que le second est équivalent à REQUEST_URI (qui contient la valeur du champ uri de la structure request_rec).

    Si une substitution intervient et si la réécriture continue, les valeurs des deux variables seront mises à jour en conséquence.

    Dans un contexte de niveau serveur (c'est à dire avant que la requête soit mise en correspondance avec le système de fichiers), SCRIPT_FILENAME et REQUEST_FILENAME ne peuvent pas contenir le chemin complet dans le système de fichier local car ce dernier n'est pas encore connu à ce niveau du traitement. Dans ce cas, les deux variables contiendront initialement la valeur de REQUEST_URI. Pour avoir accès au chemin complet de la requête dans le système de fichiers local dans un contexte de niveau serveur, utilisez une référence avant à base d'URL %{LA-U:REQUEST_FILENAME} pour déterminer la valeur finale de REQUEST_FILENAME.

  2. On peut également utiliser %{ENV:variable}, où variable peut être remplacé par toute variable d'environnement. Ces variables sont recherchées dans les structures internes d'Apache, et (si elles n'y figurent pas) via getenv() depuis le processus du serveur Apache.
  3. Que mod_ssl soit chargé ou non, on peut utiliser %{SSL:variable}, où variable peut être remplacé par le nom d'une variable d'environnement SSL, mais la valeur produite sera toujours une chaîne de caractères vide si mod_ssl n'est pas chargé. Exemple : %{SSL:SSL_CIPHER_USEKEYSIZE} peut correspondre à 128.
  4. Pour obtenir la valeur d'un en-tête contenu dans une requête HTTP, on peut toujours utiliser %{HTTP:header}, où header peut être remplacé par tout nom d'en-tête MIME HTTP. Exemple : %{HTTP:Proxy-Connection} est la valeur de l'en-tête HTTP ``Proxy-Connection:''.

    Si une condition contient un en-tête HTTP, il est ajouté à l'en-tête Vary de la réponse dans le cas où la condition est évaluée à true pour la requête. Dans le cas contraire, il n'est pas ajouté. L'ajout de l'en-tête HTTP à l'en-tête Vary de la réponse s'avère nécessaire pour une mise en cache correcte.

    Il faut garder à l'esprit que les conditions suivent une logique de court-circuit en cas de présence du drapeau 'ornext|OR', si bien que certaines d'entre elles sont susceptibles de ne pas être évaluées du tout.

  5. On peut utiliser %{LA-U:variable} pour les recherches en avant qui effectuent une sous-requête interne (basée sur l'URL), pour déterminer la valeur finale de variable. Cela peut servir à accéder à une variable (nécessaire pour une réécriture) qui n'est pas disponible dans la situation présente, mais le sera dans une phase ultérieure.

    Par exemple, pour effectuer une réécriture qui tient compte de la variable REMOTE_USER dans un contexte niveau serveur (fichier httpd.conf), vous devez utiliser %{LA-U:REMOTE_USER} ; cette variable est définie au cours des phases d'autorisation, qui interviennent après la phase de traduction de l'URL (pendant laquelle agit mod_rewrite).

    Par contre, comme mod_rewrite implémente son contexte niveau répertoire (fichier .htaccess) via la phase Fixup de l'API, et comme les phases d'autorisation interviennent avant cette phase, vous pouvez vous contenter d'utiliser %{REMOTE_USER} dans le contexte niveau serveur.

  6. On peut utiliser %{LA-F:variable} pour effectuer une sous-requête interne (basée sur un nom de fichier), pour déterminer la valeur finale de variable. La plupart du temps, elle est identique à LA-U vue précédemment.

expression de comparaison est une expression rationnelle qui est appliquée à l'instance actuelle de chaîne de test. chaîne de test est d'abord évaluée, puis comparée à l'expression de comparaison.

A savoir : expression de comparaison est une expression rationnelle compatible perl avec quelques extensions :

  1. Vous pouvez préfixer l'expression avec un caractère '!' (point d'exclamation) pour indiquer une expression de non-correspondance.
  2. Il existe certaines variantes spéciales d'expressions de comparaison. A la place d'une expression rationnelle, vous pouvez utiliser :
    • '<expression' (inférieur au sens lexicographique)
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne de test. La condition est satisfaite si chaîne de test est inférieure au sens lexicographique à l'expression.
    • '>expression' (supérieur au sens lexicographique)
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne de test. La condition est satisfaite si chaîne de test est supérieure au sens lexicographique à l'expression.
    • '=expression' (égal au sens lexicographique)
      Traite l'expression comme une chaîne de caractères et la compare lexicographiquement à chaîne de test. La condition est satisfaite si chaîne de test est égale au sens lexicographique à l'expression (les deux chaînes sont exactement identiques, caractère pour caractère). Si expression est "" (deux guillemets), chaîne de test est comparée à la chaîne vide.
    • '-d' (est un répertoire - directory)
      Traite chaîne de test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un répertoire.
    • '-f' (est un fichier régulier)
      Traite chaîne de test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un fichier régulier.
    • '-s' (est un fichier régulier d'une certaine taille - size)
      Traite chaîne de test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un fichier régulier dont la taille est supérieure à zéro.
    • '-l' (est un lien symbolique)
      Traite chaîne de test comme un chemin et vérifie s'il existe ou pas, et s'il s'agit d'un lien symbolique.
    • '-x' (a le droit d'exécution)
      Traite chaîne de test comme un chemin et vérifie s'il existe ou pas, et a le droit d'exécution. Ce droit est déterminé en accord avec le système d'exploitation sous-jacent.
    • '-F' (test de l'existence d'un fichier via une sous-requête)
      Vérifie si chaîne de test est un fichier valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur peuvent s'en trouver affectées !
    • '-U' (test de l'existence d'une URL via une sous-requête)
      Vérifie si chaîne de test est une URL valide, accessible à travers tous les contrôles d'accès du serveur actuellement configurés pour ce chemin. C'est une sous-requête interne qui effectue cette vérification - à utiliser avec précautions car les performances du serveur peuvent s'en trouver affectées !

    Note :

    Tous ces tests peuvent aussi être préfixés par un point d'exclamation ('!') pour inverser leur signification.
  3. Vous pouvez aussi définir certains drapeaux pour l'expression de comparaison en ajoutant ces [drapeaux] comme troisième argument de la directive RewriteCond, où drapeaux est un sous-ensemble séparé par des virgules des drapeaux suivants :
    • 'nocase|NC' (no case)
      Rend le test insensible à la casse - il n'est pas fait de distinction entre majuscules et minuscules, à la fois dans le développement de chaîne de test et dans expression de comparaison. Ce drapeau n'est pris en compte que lors d'une comparaison entre chaîne de test et expression de comparaison. Il ne l'est pas pour les vérification par sous-requêtes ou sur le système de fichiers.
    • 'ornext|OR' (ou condition suivante)
      Permet de chaîner les conditions de règles avec un OU au lieu du AND implicite. Exemple typique :
      RewriteCond %{REMOTE_HOST}  ^hote1.*  [OR]
      RewriteCond %{REMOTE_HOST}  ^hote2.*  [OR]
      RewriteCond %{REMOTE_HOST}  ^hote3.*
      RewriteRule ...règles concernant tous ces hôtes...
      
      Sans ce drapeau, les paires condition/règle devraient être écrites trois fois.
    • 'novary|NV' (no vary)
      Si la condition contient un en-tête HTTP, ce drapeau empêche ce dernier d'être ajouté à l'en-tête Vary de la réponse.
      L'utilisation de ce drapeau peut provoquer une mise en cache incorrecte de la réponse, si la représentation de cette réponse varie avec la valeur de l'en-tête considéré. Ce drapeau ne devrait donc être utilisé que si l'on maîtrise parfaitement le fonctionnement de l'en-tête Vary.

Exemple :

Pour réécrire la page d'accueil d'un site en fonction de l'en-tête ``User-Agent:'' de la requête, vous pouvez utiliser ce qui suit :

RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/$                 /homepage.max.html  [L]

RewriteCond  %{HTTP_USER_AGENT}  ^Lynx.*
RewriteRule  ^/$                 /homepage.min.html  [L]

RewriteRule  ^/$                 /homepage.std.html  [L]

Explications : si vous utilisez un navigateur (Netscape Navigator, Mozilla etc) qui s'identifie comme 'Mozilla', vous accèderez à la page d'accueil max (qui peut contenir des frames, ou d'autres ressources particulières). Si vous utilisez le navigateur Lynx (qui est un navigateur en mode texte), vous accèderez à une page d'accueil min (qui peut être une version conçue pour une navigation simple basée sur le texte). Si aucune de ces conditions n'est satisfaite (vous utilisez tout autre navigateur, ou votre navigateur s'identifie de manière non standard), vous accèderez à la page d'accueil std (standard).

top

RewriteEngine Directive

Description:Active ou désactive l'exécution du moteur de réécriture
Syntaxe:RewriteEngine on|off
Défaut:RewriteEngine off
Contexte:configuration du serveur, serveur virtuel, répertoire, .htaccess
Annuler:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteEngine active ou désactive l'exécution du moteur de réécriture. Si sa valeur est off, ce module n'exécutera aucun traitement et ne mettra pas à jour les variables d'environnement SCRIPT_URx.

Pour désactiver le module, il vaut mieux utiliser cette directive que commenter toutes les directives RewriteRule !

Notez que les hôtes virtuels n'héritent pas des configurations de réécriture. Ceci implique que vous devez insérer une directive RewriteEngine on dans chaque hôte virtuel pour lequel vous souhaitez utiliser des règles de réécriture.

Les directives RewriteMap du type prg ne sont pas prises en compte au cours de l'initialisation du serveur si elle ont été définies dans un contexte où la directive RewriteEngine n'a pas été définie à on.

top

RewriteLock Directive

Description:Définit le nom du fichier verrou utilisé pour la synchronisation de RewriteMap
Syntaxe:RewriteLock chemin du fichier verrou
Contexte:configuration du serveur
Statut:Extension
Module:mod_rewrite

Cette directive définit le nom du fichier utilisé comme fichier verrou de synchronisation nécessaire à mod_rewrite pour communiquer avec les programmes liés à RewriteMap. Définissez ce fichier verrou dans un chemin local (et non sur un montage NFS) si vous voulez utiliser un programme de comparaison pour la réécriture. Il n'est pas nécessaire pour les autres types de comparaison pour la réécriture.

top

RewriteLog Directive

Description:Définit le nom du fichier utilisé pour la journalisation des traitements du moteur de réécriture
Syntaxe:RewriteLog chemin du fichier journal
Contexte:configuration du serveur, serveur virtuel
Statut:Extension
Module:mod_rewrite

La directive RewriteLog définit le nom du fichier dans lequel le serveur journalise tout processus de réécriture qu'il effectue. Si le nom ne commence pas par un slash ('/'), il est considéré comme relatif à la Racine du serveur. Cette directive ne doit apparaître qu'une seule fois dans la configuration du serveur.

Il est déconseillé de positionner chemin du fichier journal à /dev/null pour désactiver la journalisation des processus de réécriture, car même si le moteur de réécriture n'envoie plus sa sortie dans un fichier, il continue à créer un fichier journal en interne, ce qui va avoir pour effet de ralentir le serveur sans fournir aucun avantage à l'administrateur ! Pour désactiver la journalisation, vous pouvez soit supprimer (ou commenter) la directive RewriteLog, soit utiliser RewriteLogLevel 0 !

Sécurité

Se référer au document Conseils à propos de la sécurité dans Apache pour plus de détails sur la manière dont votre sécurité pourrait être compromise si le répertoire où se trouvent les fichiers journaux est accessible en écriture par quiconque autre que l'utilisateur qui démarre le serveur.

Exemple

RewriteLog "/usr/local/var/apache/logs/rewrite.log"

top

RewriteLogLevel Directive

Description:Définit la verbosité du fichier journal utilisé par le moteur de réécriture
Syntaxe:RewriteLogLevel niveau
Défaut:RewriteLogLevel 0
Contexte:configuration du serveur, serveur virtuel
Statut:Extension
Module:mod_rewrite

La directive RewriteLogLevel définit le niveau de verbosité du fichier journal de réécriture. Le niveau par défaut 0 signifie aucune journalisation, tandis que 9 ou plus signifie que pratiquement toutes les actions sont journalisées.

Pour désactiver la journalisation des actions de réécriture, positionnez simplement niveau à 0. Ceci désactive toute journalisation des actions de réécriture.

Utiliser une valeur élevée pour niveau va ralentir considérablement votre serveur Apache ! N'utilisez une journalisation de la réécriture à un niveau supérieur à 2 qu'à des fins de débogage !

Exemple

RewriteLogLevel 3

top

RewriteMap Directive

Description:Définit une fonction de mise en correspondance pour la recherche de mots-clés
Syntaxe:RewriteMap nom de la correspondance type de correspondance:source de la correspondance
Contexte:configuration du serveur, serveur virtuel
Statut:Extension
Module:mod_rewrite
Compatibilité:Il est possible de choisir entre plusieurs types de bases de données depuis la version 2.0.41 d'Apache

La directive RewriteMap définit une Table de correspondance pour la réécriture que les fonctions de mise en correspondance peuvent utiliser dans les chaînes de substitution des règles pour insérer/substituer des champs en recherchant des mots-clés. La source utilisée pour cette recherche peut être de plusieurs types.

nom de la correspondance est le nom de la table de correspondance et servira à spécifier une fonction de mise en correspondance pour les chaînes de substitution d'une règle de réécriture selon une des constructions suivantes :

${ nom de la correspondance : mot-clé }
${ nom de la correspondance : mot-clé | valeur par défaut }

Lorsqu'une telle construction est rencontrée, la table de correspondance Nom de la correspondance est consultée et la clé mot-clé recherchée. Si la clé est trouvée, la construction est remplacée par la valeur de remplacement. Si la clé n'est pas trouvée, elle est remplacée par la valeur par défaut, ou par une chaîne vide si aucune valeur par défaut n'est spécifiée.

Par exemple, vous pouvez définir une directive RewriteMap comme suit

RewriteMap map-exemple txt:/chemin/vers/fichier/map.txt

Vous pourrez ensuite utiliser cette table dans une directive RewriteRule comme suit :

RewriteRule ^/ex/(.*) ${map-exemple:$1}

Les combinaisons suivantes pour type de correspondance et source de la correspondance peuvent être utilisées :

La directive RewriteMap peut apparaître plusieurs fois. Utilisez une directive RewriteMap par fonction de correspondance pour déclarer son fichier de correspondance pour la réécriture. Bien que vous ne puissiez pas déclarer une table de correspondance dans un contexte de répertoire, vous pouvez bien entendu utiliser cette table dans un contexte de répertoire.

Note

En ce qui concerne les fichiers au format DBM et texte plat, les clés de recherches sont mises en cache en interne jusqu'à ce que le mtime (date de modification) du fichier soit modifié, ou que le serveur soit redémarré. Ainsi, certaines fonctions de correspondance dans les règles peuvent être utilisées pour chaque requête. Cela ne pose pas problème, car la recherche externe n'intervient qu'une seule fois !
top

RewriteOptions Directive

Description:Configure certaines options spéciales pour le moteur de réécriture
Syntaxe:RewriteOptions Options
Contexte:configuration du serveur, serveur virtuel, répertoire, .htaccess
Annuler:FileInfo
Statut:Extension
Module:mod_rewrite
Compatibilité:MaxRedirects n'est plus disponible depuis la version version 2.1

La directive RewriteOptions définit certaines options spéciales pour la configuration au niveau du serveur ou du répertoire. La chaîne de caractères Option ne peut actuellement prendre qu'une des valeurs suivantes :

inherit
Ceci force la configuration locale à hériter de la configuration du niveau supérieur. Dans le contexte des hôtes virtuels, cela signifie que les correspondances, conditions et règles du serveur principal sont héritées. Dans le contexte des répertoires, cela signifie que les conditions et règles de la configuration .htaccess ou les sections <Directory> du répertoire parent sont héritées. Les règles héritées sont virtuellement copiées dans la section où cette directive est utilisée. Si elles sont utilisées avec des règles locales, les règles héritées sont placées après ces dernières. La place de cette directive - avant ou après les règles locales - n'a aucune influance sur ce comportement. Si des règles locales ont forcé l'arrêt de la réécriture, les règles héritées ne seront pas traitées.
top

RewriteRule Directive

Description:Définit les règles pour le moteur de réécriture
Syntaxe:RewriteRule Modèle Substitution [drapeaux]
Contexte:configuration du serveur, serveur virtuel, répertoire, .htaccess
Annuler:FileInfo
Statut:Extension
Module:mod_rewrite

La directive RewriteRule est le véritable cheval de trait de la réécriture. La directive peut apparaître plusieurs fois, chaque instance définissant une règle de réécriture particulière. L'ordre dans lequel ces règles sont définies est important - il s'agit de l'ordre dans lequel les règles seront appliquées au cours du processus de réécriture.

Modèle est une expression rationnelle compatible perl. Dans la première règle de réécriture, l'expression est comparée au (%-encoded) chemin de l'URL de la requête ; les expressions suivantes sont comparées à la sortie de la dernière règle de réécriture qui a été appliquée.

Qu'est-ce qui est comparé ?

Le Modèle est d'abord comparé à la partie de l'URL après le nom d'hôte et le port, et avant la chaîne de requête. Si vous souhaitez faire une comparaison sur le nom d'hôte, le port, ou la chaîne de requête, utilisez une directive RewriteCond comportant les variables %{HTTP_HOST}, %{SERVER_PORT}, ou %{QUERY_STRING}.

Pour quelques conseils à propos des expressions rationnelles, voir le document Introduction à mod_rewrite.

Dans mod_rewrite, on peut aussi utiliser le caractère NON ('!') comme préfixe de modèle. Ceci vous permet d'inverser la signification d'un modèle, soit pour dire ``si l'URL considérée ne correspond PAS à ce modèle''. Le caractère NON peut donc être utilisé à titre exceptionnel, lorsqu'il est plus simple d'effectuer une comparaison avec le modèle inversé, ou dans la dernière règle par défaut.

Note

Si vous utilisez le caractère NON pour inverser la signification d'un modèle, vous ne pouvez pas inclure de parties génériques groupées dans le modèle. Ceci est dû au fait que, lorsque le modèle ne correspond pas (autrement dit, sa négation correspond), les groupes sont vides. Ainsi, si vous utilisez des modèles inversés, vous ne pouvez pas vous référer aux groupes par $N dans la chaîne de substitution !

Dans une règle de réécriture, Substitution est la chaîne de caractères qui remplace le chemin de l'URL original qui correspondait au Modèle. Substitution peut être :

un chemin du système de fichiers
Il indique alors la localisation dans le système de fichiers de la ressource qui doit être envoyée au client.
chemin d'URL
Un chemin relatif à la valeur de DocumentRoot vers la ressource qui doit être servie. Notez que mod_rewrite essaie de deviner si vous avez spécifié un chemin du système de fichiers ou un chemin d'URL en vérifiant si la première partie du chemin existe à la racine du système de fichiers. Par exemple, si vous avez spécifié comme chaîne de Substitution /www/file.html, cette dernière sera traitée comme un chemin d'URL à moins qu'un répertoire nommé www n'existe à la racine de votre système de fichiers, auquel cas la chaîne de substitution sera traitée comme un chemin du système de fichiers. Si vous désirez que d'autres directives de correspondance d'URL (comme la directive Alias) soient appliquées au chemin d'URL résultant, utilisez le drapeau [PT] comme décrit ci-dessous.
URL absolue
Si une URL absolue est spécifiée, mod_rewrite vérifie si le nom d'hôte correspond à celui de l'hôte local. Si c'est le cas, le protocole et le nom d'hôte sont supprimés, et ce qui reste est traité comme un chemin d'URL. Dans le cas contraire, une redirection externe vers l'URL indiquée est effectuée. Pour forcer une redirection externe vers l'hôte local, voir le drapeau [R] ci-dessous.
- (tiret)
Un tiret indique qu'aucune substitution ne doit être effectuée (le chemin considéré est transmis sans changement). Ceci est utile quand un drapeau doit être appliqué sans modifier le chemin (voir ci-dessous).

En plus du texte, la chaîne Substition peut comporter :

  1. des références arrières ($N) vers le modèle d'une directive RewriteRule
  2. des références arrières (%N) vers le dernier modèle d'une directive RewriteCond qui correspondait
  3. des variables du serveur comme dans les chaînes de test de condition d'une règle (%{VARNAME})
  4. des appels de fonctions de comparaison (${nom correspondance:clé|défaut})

Les références arrières sont des identificateurs de la forme $N (N=0..9), qui seront remplacés par le contenu du Nème groupe du Modèle qui correspondait. Les variables du serveur sont les mêmes que dans la Chaîne de test d'une directive RewriteCond. Les fonctions de comparaison sont issues de la directive RewriteMap dans la section de laquelle elles sont décrites. Ces trois types de variables sont évaluées dans l'ordre ci-dessus.

Comme mentionné précédemment, toutes les règles de réécriture sont appliquées à la chaîne de Substitution (selon l'ordre dans lequel elles sont définies dans le fichier de configuration). L'URL est intégralement remplacée par la chaîne de Substitution et le processus de réécriture se poursuit jusqu'à ce que toutes les règles aient été appliquées, ou qu'il soit explicitement stoppé par un drapeau L.

Modifier la chaîne de requête

Par défaut, la chaîne de requête est transmise sans modification. Vous pouvez cependant créer dans la chaîne de substitution des URLs dont une partie constitue une chaîne de requête. Pour cela, ajoutez simplement un point d'interrogation dans la chaîne de substitution pour indiquer que le texte qui suit doit être réinjecté dans la chaîne de requête. Pour supprimer une chaîne de requête, terminez simplement la chaîne de substitution par un point d'interrogation. Pour combiner les nouvelles chaînes de requête avec les anciennes, utilisez le drapeau [QSA].

En outre, vous pouvez spécifier des actions spéciales à effectuer en ajoutant des [drapeaux] comme troisième argument de la directive RewriteRule. Séparés par des virgules au sein d'une liste encadrée par des crochets, les drapeaux peuvent être choisis parmi les suivants :

'B' (références arrière échappées)

Les URLs ne doivent pas être échappées pour pouvoir être comparées par Apache, si bien que les références arrières renverront une valeur non échappée au moment où elles seront appliquées. En utilisant le drapeau B, les caractères non alphanumériques des références arrières seront echappés. Par exemple, considérons la règle :

RewriteRule ^(/.*)$ /index.php?show=$1

Elle va faire correspondre /C++ à index.php?show=/C++. Mais elle va aussi faire correspondre /C%2b%2b à /index.php?show=/C++, car le caractère %2b n'a pas été échappé. Par contre, avec le drapeau B, la substitution s'effectuera vers /index.php?show=/C%2b%2b.

Ce processus d'échappement est particulièrement nécessaire dans le contexte du mandataire, où l'adresse d'arrière-plan ne fonctionnera pas si elle se présente sous une forme non échappée.

'chain|C' (chaînage avec la règle suivante)
Ce drapeau effectue un chaînage entre la règle courante et la suivante (qui peut elle-même être chaînée avec la suivante, et ainsi de suite). Ceci provoque l'effet suivant : si une règle correspond, le processus continue normalement - le drapeau n'a aucun effet. Si la règle ne correspond pas, toutes les règles chaînées suivantes sont ignorées. Par exemple, ce drapeau peut être utilisé pour supprimer la partie ``.www'', dans un jeu de règles au niveau du répertoire, lorsque vous faites intervenir une redirection externe (où la partie ``.www'' ne doit pas figurer !).
'cookie|CO=NOM:VAL:domaine[:durée de vie[:chemin[:sécurité[:http seulement]]]]' (définit un cookie)
Ce drapeau définit un cookie au niveau du navigateur du client. Le nom du cookie est spécifié par NOM, et sa valeur par VAL. Le champ domaine est le domaine du cookie, comme '.apache.org', le champ optionnel durée de vie est la durée de vie du cookie en minutes (0 signifie que le cookie expire à la fin de la session), et le champ optionnel chemin le chemin du cookie. Si sécurité est défini à 'secure, 'true' ou '1', le cookie ne peut être transmis que par une connexion sécurisée. Si http seulement est défini à ''HttpOnly', 'true' ou '1', le drapeau HttpOnly est utilisé, ce qui rend le cookie inaccessible au code JavaScript sur les navigateurs qui supportent ce dernier.
'discardpathinfo|DPI' (ne pas tenir compte de PATH_INFO)

Dans un contexte de répertoire, l'URI par rapport auquel chaque règle RewriteRule effectue ses comparaisons est la concaténation de la valeur courante de l'URI et de PATH_INFO.

L'URI courant est soit l'URI initial tel qu'envoyé par le client, soit le résultat d'un passage à travers le processus de réécriture, soit le résultat de la règle précédente du processus de réécriture courant.

Par contre, PATH_INFO qui est ajouté à l'URI avant chaque règle reflète la valeur qu'avait PATH_INFO avant le processus de réécriture. En conséquence, si de larges parties de l'URI sont retenues et copiées dans une chaîne de substitution au cours de multiples directives RewriteRule, et ceci sans tenir compte de la part qui revient à PATH_INFO dans l'URI, il se peut que l'URI final se voit ajouter plusieurs copies de PATH_INFO.

Utilisez ce drapeau dans toute substitution où le PATH_INFO résultant de la mise en correspondance précédente de cette requête avec le système de fichiers ne présente pas d'intérêt. Ce drapeau indique qu'il ne faut pas tenir compte du PATH_INFO construit avant que le processus de réécriture courant ait commencé. PATH_INFO ne sera pas recalculé avant que le processus de réécriture courant se termine. Les règles suivantes rencontrées au cours du processus ne verront que le résultat direct des substitutions, sans ajout du PATH_INFO.

'env|E=VAR:VAL' (définit une variable d'environnement)
Ce drapeau force une variable d'environnement nommée VAR à prendre la valeur VAL, où VAL peut contenir des références arrières vers des expressions rationnelles ($N et %N) qui seront évaluées. Vous pouvez utiliser ce drapeau plusieurs fois pour définir plusieurs variables. Les variables peuvent ensuite être déréférencées dans de nombreux cas, et le plus souvent depuis XSSI (via <!--#echo var="VAR"-->) ou CGI ($ENV{'VAR'}). Vous pouvez déréférencer la variable dans un modèle de directive RewriteCond ultérieure, en utilisant %{ENV:VAR}. Ce drapeau permet de supprimer des informations d'une URL, tout en conservant la trace de ces informations.
'forbidden|F' (force l'interdiction d'une URL)
Ce drapeau force l'interdiction de l'URL courante - il renvoie immédiatement une réponse HTTP 403 (FORBIDDEN). Ce drapeau, associé à des directives RewriteCond appropriées, permet de bloquer de manière conditionnelle certaines URLs.
'gone|G' (signale la non-existence d'une URL)
Ce drapeau signale la non-existence d'une URL - il renvoie immédiatement une réponse HTTP 410 (GONE). Il permet de marquer les pages qui n'existent plus comme "gone".
'handler|H=Gestionnaire de contenu' (impose un gestionnaire de contenu)
Impose Gestionnaire de contenu comme gestionnaire de contenu pour le fichier cible. Ce drapeau permet par exemple de simuler la directive ScriptAlias du module mod_alias, qui impose en interne le gestionnaire ``cgi-script'' à tous les fichiers du répertoire correspondant.
Dans un contexte de niveau répertoire, aucune substitution ne doit modifier le chemin. N'utilisez ce drapeau dans un contexte de répertoire qu'avec - (tiret) comme substitution, faute de quoi la requête echouera.
'last|L' (dernière règle)
Termine le processus de réécriture ici et n'applique plus aucune règle de réécriture. Ce drapeau est équivalent à la commande Perl last ou la commande C break. Il permet d'éviter la réécriture par les règles suivantes d'une URL déjà réécrite. Rappelez-vous cependant que si une directive RewriteRule génère une redirection interne (ce qui arrive fréquemment lors d'une réécriture dans un contexte de répertoire), la requête sera réinjectée et le processus de réécriture sera réitéré à partir de la première directive RewriteRule.
'next|N' (prochain round)
Relance le processus de réécriture (toujours à partir de la première règle). Cette fois, l'URL à comparer n'est plus l'URL originale, mais plutôt l'URL renvoyée par la dernière règle de réécriture. Ce drapeau est équivalent à la commande Perl next ou la commande C continue. Il permet de redémarrer le processus de réécriture - en se positionnant immédiatement au niveau de la première règle. Prenez garde à ne pas créer de bouclage infini !
'nocase|NC' (insensible à la casse)
Ce drapeau rend le Modèle insensible à la casse, c'est à dire ne tenant pas compte des majuscules/minuscules lorsque le Modèle est comparé avec l'URL courante.
'noescape|NE' (pas d'échappement de l'URI en sortie)
Ce drapeau empêche mod_rewrite d'appliquer les règles d'échappement d'URI usuelles au résultat d'une réécriture. Normalement, les caractère spéciaux (comme '%', '$', ';', etc...) sont échappés en leurs équivalents hexadécimaux (respectivement '%25', '%24', et '%3B') ; ce drapeau empêche cela de se produire. Il permet au symbole '%' d'apparaître en sortie, comme dans

RewriteRule ^/foo/(.*) /bar?arg=P1\%3d$1 [R,NE]

qui remplacerait '/foo/zed' par la requête plus sure '/bar?arg=P1=zed'.
'nosubreq|NS' (sous-requêtes non concernées)

Si ce drapeau est présent, le moteur de réécriture n'applique pas la règle si la requête courante est une sous-requête interne. Par exemples, des sous-requêtes sont générées en interne par Apache lorsque mod_dir essaie de trouver des informations à propos d'éventuels fichiers de répertoire par défaut (fichiers index.xxx). Dans le cas d'une sous-requête, ce n'est pas toujours utile, et peut même provoquer des erreurs si l'ensemble du jeu de règles est appliqué. Ce drapeau permet d'exclure certaines règles.

Pour déterminer si l'on doit appliquer une règle ou pas, si une URL est préfixée par un script CGI, pour forcer son traitement par le script CGI, vous allez probablement rencontrer des problèmes (ou tout du moins une surcharge significative) avec les sous-requêtes. Dans ce cas, utilisez ce drapeau

'proxy|P' (impose le mandataire)
Ce drapeau force l'envoi de la partie substitution en interne en tant que requête mandataire, et (le processus de réécriture s'arrête ici) son envoi immédiat vers le module proxy. Vous devez vous assurer que la chaîne de substitution est un URI valide (débutant typiquement par http://nom d'hôte) pouvant être traitée par le module proxy d'Apache. Si ce n'est pas le cas, le module proxy vous renverra une erreur. Utilisez ce drapeau pour implémenter de manière plus puissante la directive ProxyPass, pour mettre en correspondance un contenu distant dans l'espace de nommage du serveur local.

Note: mod_proxy doit être activé pour pouvoir utiliser ce drapeau..

'passthrough|PT' (passage au gestionnaire suivant)
Ce drapeau force le moteur de réécriture à affecter la valeur du champ filename au champ uri de la structure interne request_rec. Ce drapeau n'est qu'une astuce permettant un traitement supplémentaire de la sortie des directives RewriteRule, en utilisant Alias, ScriptAlias, Redirect, ou d'autres directives en provenance de divers traducteurs URI/nom de fichier. Par exemple, pour réécrire /abc vers /def avec mod_rewrite, puis /def vers /ghi avec mod_alias :

RewriteRule ^/abc(.*) /def$1 [PT]
Alias /def /ghi

Si le drapeau PT est omis, mod_rewrite va réécrire uri=/abc/... vers filename=/def/... comme tout traducteur URI/nom de fichier compatible avec l'API doit le faire. Puis, mod_alias va tenter une transition URI vers nom de fichier, et va échouer.

Note: Vous devez utiliser ce drapeau si vous voulez mélanger des directives en provenance de différents modules qui effectuent une traduction URL/nom de fichier. Un exemple typique est l'utilisation conjointe de mod_alias et de mod_rewrite.

Le drapeau PT rend implicite la présence du drapeau L flag : la réécriture sera stoppée afin de transmettre la requête à la phase suivante du traitement.

'qsappend|QSA' (ajout d'une chaîne de requête - query string)
Ce drapeau force le moteur de réécriture à ajouter la chaîne de substitution à la chaîne de requête au lieu de remplacer cette dernière par la chaîne de substitution. Vous pouvez ainsi ajouter des données à la chaîne de requête via une règle de réécriture.
'redirect|R [=code]' (force une redirection)

Préfixe la chaîne de substitution par http://hôte[:port]/ (ce qui fait de la nouvelle URL un URI) pour forcer une redirection externe. Si aucun code n'est défini, une réponse HTTP 302 (MOVED TEMPORARILY) sera renvoyée. Si vous voulez renvoyer un autre code de réponse, spécifiez simplement le nombre approprié ou utilisez un des noms symboliques suivants : temp (défaut), permanent ou seeother. Vous pouvez utiliser ce drapeau pour que les règles mettent l'URL sous forme canonique et la renvoient au client, pour traduire ``/~'' en ``/u/'', ou pour ajouter systématiquement un slash à /u/utilisateur, etc...
Note: Si vous utilisez ce drapeau, assurez-vous que le champ de substitution est une URL valide ! Si ce n'est pas le cas, vous serez redirigé vers une URL invalide. Souvenez-vous que, s'il est seul, ce drapeau va seulement préfixer l'URL par http://hôte[:port]/, et que le processus de réécriture va se poursuivre. En général, vous voudrez plutôt stopper la réécriture à ce point, et rediriger immédiatement. Pour stopper la réécriture, vous pouvez ajouter le drapeau 'L'.

Bien qu'on utilise en général ce drapeau pour les redirections, on peut spécifier tout code de statut valide. Si le code de statut est en dehors de la gamme des codes de redirection (300-399), la chaîne de Substitution est supprimée et le processus de réécriture stoppé comme si le drapeau L était présent.

'skip|S=num' (saute la/les règle(s) suivantes)
Ce drapeau force le moteur de réécriture à sauter les num règles consécutives suivantes, si la règle courante s'applique. Il permet de simuler une structure if-then-else : la dernière règle du bloc "then" devient skip=N, où N est le nombre de règles contenues dans le bloc "else" (ce qui est un comportement différent de celui du drapeau 'chain|C' !).
'type|T=type MIME' (force le type MIME)
Force le type MIME du fichier cible à type MIME. Ceci permet de définir le type de contenu en fonction de certaines conditions. Dans un contexte de répertoire, utilisez exclusivement - (tiret) comme substitution, faute de quoi le type MIME défini à l'aide de ce drapeau sera perdu à cause d'un rejeu du traitement en interne.

Développement du répertoire home

Quand la chaîne de substitution commence par quelque chose comme "/~user" (de manière explicite ou par références arrières), mod_rewrite développe le répertoire home sans tenir compte de la présence ou de la configuration du module mod_userdir.

Ce développement n'est pas effectué si le drapeau PT est utilisé dans la directive RewriteRule

Réécritures dans le contexte de répertoire

Le moteur de réécriture peut être utilisé dans les fichiers .htaccess. Pour activer le moteur de réécriture pour ces fichiers, vous devez préciser "RewriteEngine On" et "Options FollowSymLinks" doit être activé. Si votre administrateur a interdit la surcharge de FollowSymLinks pour un répertoire utilisateur, vous ne pouvez pas utiliser le moteur de réécriture. Cette restriction est nécessaire pour des raisons de sécurité.

Lorsqu'on utilise le moteur de réécriture dans les fichiers .htaccess, le préfixe du répertoire (qui est toujours le même pour un répertoire donné) est automatiquement supprimé pour la comparaison du modèle et automatiquement ajouté une fois la substitution effectuée. Cette fonctionnalité est nécessaire pour de nombreux cas de réécriture ; sans elle, vous seriez obligé de tenir compte du répertoire parent pour la comparaison, ce qui n'est pas toujours possible. Il y a une exception : si une chaîne de substitution commence par http://, le préfixe du répertoire ne sera pas ajouté, et une redirection externe (ou le passage par un mandataire, si le drapeau P est utilisé) sera initiée. Voir la directive RewriteBase pour plus de détails.

Le moteur de réécriture peut aussi être utilisé dans les sections <Directory> avec les mêmes règles de comparaison des préfixes que celles qui s'appliquent pour les fichiers .htaccess. Cependant, il est en général plus simple, pour éviter la complication des substitutions de préfixes, de définir les règles de réécriture dans le contexte du serveur principal ou des hôtes virtuels, plutôt que dans une section <Directory>.

Bien que du point de vue syntaxique, il soit permis de définir des règles de réécriture dans les sections <Location> et <Files>, ce n'est à priori d'aucune utilité et n'est pas supporté.

Voici toutes les combinaisons de substitution et leurs significations :

Dans la configuration au niveau du serveur principal (httpd.conf)
pour la requête ``GET /chemin/infochemin'':

Règle                          Résultat de la substitution
----------------------------------------------  ----------------------------------
^/chemin(.*) autre-chemin$1                      non valide, non supporté

^/chemin(.*) autre-chemin$1  [R]                 non valide, non supporté

^/chemin(.*) autre-chemin$1  [P]                 non valide, non supporté
----------------------------------------------  ----------------------------------
^/chemin(.*) /autre-chemin$1                     /autre-chemin/infochemin

^/chemin(.*) /autre-chemin$1 [R]                 http://cet-hôte/autre-chemin/infochemin
                                                via redirection externe

^/chemin(.*) /autre-chemin$1 [P]                 n'a pas lieu d'être, non supporté
----------------------------------------------  ----------------------------------
^/chemin(.*) http://cet-hôte/autre-chemin$1      /autre-chemin/infochemin

^/chemin(.*) http://cet-hôte/autre-chemin$1 [R]  http://cet-hôte/autre-chemin/infochemin
                                                via redirection externe

^/chemin(.*) http://cet-hôte/autre-chemin$1 [P]  n'a pas lieu d'être, non supporté
----------------------------------------------  ----------------------------------
^/chemin(.*) http://autre hôte/autre-chemin$1     http://autre hôte/autre-chemin/infochemin
                                                via redirection externe

^/chemin(.*) http://autre hôte/autre-chemin$1 [R] http://autre hôte/autre-chemin/infochemin
                                                via redirection externe
                                                (le drapeau [R] est
						redondant)

^/chemin(.*) http://autre hôte/autre-chemin$1 [P] http://autre hôte/autre-chemin/infochemin
                                                via un mandataire interne

Dans une configuration de niveau répertoire pour /chemin
(/chemin/physique/vers/chemin/.htacccess, avec RewriteBase /chemin)
pour la requête ``GET /chemin/chemin-local/infochemin'':

Règle                          Résultat de la substitution
----------------------------------------------  ----------------------------------
^chemin-local(.*) autre-chemin$1                      /chemin/autre-chemin/infochemin

^chemin-local(.*) autre-chemin$1  [R]                 http://cet-hôte/chemin/autre-chemin/infochemin
                                                via redirection externe

^chemin-local(.*) autre-chemin$1  [P]                 n'a pas lieu d'être, non supporté
----------------------------------------------  ----------------------------------
^chemin-local(.*) /autre-chemin$1                     /autre-chemin/infochemin

^chemin-local(.*) /autre-chemin$1 [R]                 http://cet-hôte/autre-chemin/infochemin
                                                via redirection externe

^chemin-local(.*) /autre-chemin$1 [P]                 n'a pas lieu d'être, non supporté
----------------------------------------------  ----------------------------------
^chemin-local(.*) http://cet-hôte/autre-chemin$1      /autre-chemin/infochemin

^chemin-local(.*) http://cet-hôte/autre-chemin$1 [R]  http://cet-hôte/autre-chemin/infochemin
                                                via redirection externe

^chemin-local(.*) http://cet-hôte/autre-chemin$1 [P]  n'a pas lieu d'être, non supporté
----------------------------------------------  ----------------------------------
^chemin-local(.*) http://autre hôte/autre-chemin$1     http://autre hôte/autre-chemin/infochemin
                                                via redirection externe

^chemin-local(.*) http://autre hôte/autre-chemin$1 [R] http://autre hôte/autre-chemin/infochemin
                                                via redirection externe
                                                (le drapeau [R] est
						redondant)

^chemin-local(.*) http://autre hôte/autre-chemin$1 [P] http://autre hôte/autre-chemin/infochemin
                                                via un mandataire interne

Langues Disponibles:  en  |  fr