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

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.

Drapeaux des règles de réécriture
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.

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/
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
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.

RewriteEngine Active ou désactive l'exécution du moteur de réécriture RewriteEngine on|off RewriteEngine off server configvirtual host directory.htaccess FileInfo

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.

RewriteOptions Configure certaines options spéciales pour le moteur de réécriture RewriteOptions Options server configvirtual host directory.htaccess FileInfo 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.
RewriteLog Définit le nom du fichier utilisé pour la journalisation des traitements du moteur de réécriture RewriteLog chemin du fichier journal server configvirtual host

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"
RewriteLogLevel Définit la verbosité du fichier journal utilisé par le moteur de réécriture RewriteLogLevel niveau RewriteLogLevel 0 server configvirtual host

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
RewriteLock Définit le nom du fichier verrou utilisé pour la synchronisation de RewriteMap RewriteLock chemin du fichier verrou server config

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.

RewriteMap Définit une fonction de mise en correspondance pour la recherche de mots-clés RewriteMap nom de la correspondance type de correspondance:source de la correspondance server configvirtual host 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 :

  • Format texte standard
    type de correspondance : txt, source de la correspondance : chemin du système de fichiers Unix vers un fichier régulier valide

    Il s'agit de la mise en oeuvre standard de la table de correspondance pour la réécriture où la source de la correspondance est un fichier ASCII dont les différentes lignes sont soit des lignes vides, soit des lignes de commentaires (commençant par un caractère "#"), soit des paires de valeurs (une seule paire par ligne) comme suit :

    mot-clé valeur de remplacement

    Exemple
    ##
    ##  map.txt -- table de correspondance pour la réécriture
    ##
    
    Ralf.S.Engelschall    rse   # Bastard Operator From Hell
    Mr.Joe.Average        joe   # Mr. Average
    
    RewriteMap real-to-user txt:/chemin/vers/fichier/map.txt
  • Format texte avec valeurs aléatoires
    type de correspondance: rnd, source de la correspondance : chemin du système de fichiers Unix vers un fichier régulier valide

    Ce format se différencie du format texte standard précédent par l'ajout d'un traitement supplémentaire : en plus de la recherche de clés, le fichier est interprété en tenant compte de la présence éventuelle dans les valeurs de remplacement de caractères ``|'' signifiant ``ou''. En d'autres termes, ces caractères ``|'' permettent de spécifier un jeu de valeurs parmi lesquelles la valeur de retour sera choisie aléatoirement. Par exemple, vous pouvez utiliser les fichier de correspondance et directives suivants pour mettre en oeuvre une répartition de charge aléatoire entre plusieurs serveurs en arrière-plan, via un mandataire inverse. Les images sont envoyées à un des serveurs de l'ensemble "statique", tandis que tout le reste est envoyé à un des serveurs de l'ensemble "dynamique".

    Exemple:

    Fichier de correspondances pour la réécriture
    ##
    ##  map.txt -- correspondances pour la réécriture
    ##
    
    static   www1|www2|www3|www4
    dynamic  www5|www6
    
    Directives de configuration RewriteMap serveurs rnd:/chemin/vers/fichier/map.txt

    RewriteRule ^/(.*\.(png|gif|jpg)) http://${serveurs:static}/$1 [NC,P,L]
    RewriteRule ^/(.*) http://${serveurs:dynamic}/$1 [P,L]
  • Fichier à accès direct (Hash file)
    type de correspondance : dbm[=type], source de la correspondance : chemin du système de fichiers Unix vers un fichier régulier valide

    Ici, la source de la correspondance est un fichier binaire au format DBM contenant les mêmes données qu'un fichier au format Plein texte, mais selon une représentation particulière optimisée en vue d'une recherche très rapide. Le type peut être sdbm, gdbm, ndbm, ou db selon la configuration à la compilation . Si type est omis, la valeur retenue sera la valeur par défaut définie à la compilation.

    La création du fichier dbm à partir d'un fichier texte s'effectue à l'aide de l'utilitaire httxt2dbm.

    $ httxt2dbm -i fichier-source.txt -o fichier-dbm.map
  • Fonction interne
    type de la correspondance : int, source de la correspondance : fonction interne à Apache

    Ici, la source de la correspondance est une fonction interne à Apache. Actuellement, vous ne pouvez pas créer votre propre fonction, mais les fonctions suivantes existent déjà :

    • toupper:
      Convertit tous les caractères de la clé en majuscules.
    • tolower:
      Convertit tous les caractères de la clé en minuscules.
    • escape:
      Traduit les caractères spéciaux que contient la clé en séquences hexadécimales.
    • unescape:
      Reconvertit les séquences hexadécimales que contient la clé en caractères spéciaux.
  • Programme de réécriture externe
    type de la correspondance : prg, source de la correspondance : chemin du système de fichiers Unix vers un fichier régulier valide

    Ici, la source n'est pas un fichier de correspondances, mais un programme. Pour le créer, vous pouvez utiliser le langage de votre choix, mais le programme doit être un exécutable (soit du code objet, soit un script contenant le fameux "#!/chemin/vers/interpréteur" au début de sa première ligne).

    Ce programme est lancé une seule fois au démarrage du serveur Apache, puis communique avec le moteur de réécriture via ses entrée et sortie standards (stdin et stdout). A chaque recherche effectuée par la fonction de correspondance, il reçoit sur son entrée standard la clé à rechercher sous la forme d'une chaîne de caractères terminée par le caractère "nouvelle ligne". Il doit ensuite renvoyer sur sa sortie standard la valeur recherchée sous la forme d'une chaîne de caractères terminée par le caractère "nouvelle ligne", ou la chaîne de quatre caractères ``NULL'' en cas d'échec (c'est à dire si aucune valeur ne correspond à la clé fournie).

    Les programmes de réécriture externes ne seront pas lancés s'ils ont été définis dans un contexte où la directive RewriteEngine n'a pas été définie à on.

    Voici un exemple de ce pourrait être un programme trivial qui implémenterait une correspondance 1:1 (c'est à dire, clé == valeur) :

    #!/usr/bin/perl
    $| = 1;
    while (<STDIN>) {
        # ...insérer ici le code de transformation ou de recherche...
        print $_;
    }
    

    Mais soyez très prudent :

    1. ``Ce programme doit être simple, basique'' (MERCI). Si ce programme se bloque, il bloquera aussi Apache lorsqu'il tentera d'utiliser la règle de réécriture correspondante.
    2. L'utilisation d'entrées/sorties avec tampon sur stdout est une erreur courante. Ceci est à proscrire sous peine de créer une boucle infernale ! Pour éviter ceci, on utilise (en langage Perl) ``$|=1'' comme dans l'exemple ci-dessus.
    3. On peut définir la directive RewriteLock pour spécifier un fichier verrou que mod_rewrite pourra utiliser pour synchroniser les communications avec le programme de correspondance. Par défaut, aucune synchronisation de ce type n'est mise en oeuvre.
  • Requête SQL
    type de correspondance : dbd ou fastdbd, source de la correspondance : une requête SQL SELECT qui comporte un seul argument et renvoie une seule valeur.

    Ici, on utilise mod_dbd pour implémenter une correspondance pour la réécriture par recherche dans une base de données SQL. Deux modes sont possibles : fastdbd met en cache les recherches dans la base de données en interne, alors que dbd ne le fait pas. Ainsi, dbd diminue les performances, mais donnera toujours une réponse actualisée, même si le contenu de la base de données est mise à jour, alors que fastdbd est plus performant mais ne relira pas le contenu de la base de données tant que le serveur ne sera pas redémarré.

    Si une requête renvoie plusieurs réponses, une de ces dernières sera choisie aléatoirement.

    Example RewriteMap ma-requete "fastdbd:SELECT destination FROM rewrite WHERE source = %s"

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 !
RewriteBase Définit l'URL de base pour les réécritures au niveau répertoire RewriteBase chemin URL Voir utilisation pour plus d'informations. directory.htaccess FileInfo

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).

RewriteCond Définit une condition qui devra être satisfaite pour que la réécriture soit effectuée RewriteCond chaîne de test expression de comparaison server configvirtual host directory.htaccess FileInfo

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 :

  • références arrières de règle de réécriture : ce sont des références arrières de la forme $N (0 <= N <= 9), qui donnent accès aux parties groupées (entre parenthèses) du modèle tiré de la RewriteRule assujettie au jeu de conditions concerné.
  • Références arrières de condition de réécriture : ce sont des références arrières de la forme %N (1 <= N <= 9), qui donnent accès aux parties groupées (là aussi entre parenthèses) du modèle de la dernière condition satisfaite du jeu de conditions concerné.
  • extensions de table de réécriture : ce sont des extensions de la forme ${nomTable:clé|défaut}. Voir la documentation de RewriteMap pour plus de détails.
  • Variables du serveur : ce sont des variables de la forme %{ NOM_DE_VARIABLE } %{ NOM_DE_VARIABLE }NOM_DE_VARIABLE peut être une chaîne de caractères faisant partie de la liste suivante :
    En-têtes HTTP : connexion & requête:
    HTTP_USER_AGENT
    HTTP_REFERER
    HTTP_COOKIE
    HTTP_FORWARDED
    HTTP_HOST
    HTTP_PROXY_CONNECTION
    HTTP_ACCEPT
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_PORT
    REMOTE_USER
    REMOTE_IDENT
    REQUEST_METHOD
    SCRIPT_FILENAME
    PATH_INFO
    QUERY_STRING
    AUTH_TYPE
    variables internes au serveur : date et heure : spéciaux :
    DOCUMENT_ROOT
    SERVER_ADMIN
    SERVER_NAME
    SERVER_ADDR
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME
    API_VERSION
    THE_REQUEST
    REQUEST_URI
    REQUEST_FILENAME
    IS_SUBREQ
    HTTPS

    Toutes ces variables correspondent nom pour nom aux en-têtes MIME HTTP, aux variables C du serveur Apache ou aux champs struct tm du système Unix. La plupart sont documentées dans une autre partie du manuel ou dans la spécification CGI. Vous trouverez dans ce qui suit quelques variables spécifiques à mod_rewrite.

    IS_SUBREQ
    Contiendra le texte "true" si la requête en cours de traitement est une sous-requête, "false" dans le cas contraire. Une sous-requête est générée quand un module a besoin de se référer à des fichiers ou URIs addidionnels pour pouvoir mener à bien sa tâche.
    API_VERSION
    Il s'agit de la version de l'API des modules Apache (l'interface interne entre le serveur et les modules) dans la construction actuelle de httpd, telle qu'elle est définie dans include/ap_mmn.h. La version de l'API des modules correspond à la version d'Apache utilisée (pour Apache 1.3.14, par exemple, la version de l'API sera 19990320:10), mais cette information intéresse principalement les développeurs de modules.
    THE_REQUEST
    La ligne de requête HTTP complète envoyée par le navigateur au serveur (par exemple, "GET /index.html HTTP/1.1"), à l'exclusion de tout en-tête ajouté par le navigateur.
    REQUEST_URI
    La ressource demandée dans la ligne de requête HTTP (correspondrait, dans l'exemple précédent, à "/index.html").
    REQUEST_FILENAME
    Le chemin complet local au système de fichiers du fichier ou du script correspondant à la requête.
    HTTPS
    Contiendra le texte "on" si la connexion utilise SSL/TLS, "off" dans le cas contraire (L'utilisation de cette variable est pertinente, indépendamment du fait que mod_ssl soit chargé ou non).

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).

RewriteRule Définit les règles pour le moteur de réécriture RewriteRule Modèle Substitution [drapeaux] server configvirtual host directory.htaccess FileInfo

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