Rewrite Détails techniques sur le module Apache mod_rewrite

Ce document passe en revue certains détails techniques à propos du module mod_rewrite et de la mise en correspondance des URLs

Documentation du module mod_rewrite Introduction à mod_rewrite Redirection et remise en correspondance Contrôle d'accès Serveurs virtuels Mise en cache Utilisation de RewriteMap Techniques avancées Quand ne pas utiliser mod_rewrite
Phases de l'API

Le traitement des requêtes par le serveur HTTP Apache se déroule en plusieurs phases. Au cours de chaque phase, un ou plusieurs modules peuvent être appelés pour traiter la partie concernée du cycle de vie de la requête. Les différentes phases peuvent consister en traduction d'URL en nom de fichier, authentification, autorisation, gestion de contenu ou journalisation (la liste n'est pas exhaustive).

mod_rewrite agit dans deux de ces phases (ou accroches - hooks - comme on les nomme souvent) pour la réécriture des URLs.

Tout d'abord, il utilise le hook traduction URL vers nom de fichier qui intervient après la lecture de la requête HTTP, mais avant le processus d'autorisation. Ensuite, il utilise le hook Fixup, qui intervient après les phases d'autorisation, après la lecture des fichiers de configuration de niveau répertoire (fichiers .htaccess), mais avant l'appel du gestionnaire de contenu.

Ainsi, lorsqu'une requête arrive et une fois le serveur correspondant ou le serveur virtuel déterminé, le moteur de réécriture commence à traiter toute directive apparaissant dans la configuration de niveau serveur (autrement dit dans le fichier de configuration principal du serveur et les sections Virtualhost). Tout ce processus s'exécute au cours de la phase de traduction URL vers nom de fichier.

Quelques étapes plus loin, une fois les répertoires de données finaux trouvés, les directives de configuration de niveau répertoire (fichiers .htaccess et sections Directory) sont appliquées. Ce processus s'exécute au cours de la phase Fixup.

Dans tous ces cas, mod_rewrite réécrit le REQUEST_URI soit vers une nouvelle URL, soit vers un nom de fichier.

Dans un contexte de niveau répertoire (autrement dit dans les fichiers .htaccess et les sections Directory), les règles de réécriture s'appliquent après la traduction de l'URL en nom de fichier. C'est pourquoi le chemin URL auquel mod_rewrite compare initialement les directives RewriteRule est le chemin complet vers le nom de fichier traduit amputé de la partie répertoires (y compris le dernier slash).

Un exemple : si les règles se trouvent dans /var/www/foo/.htaccess et si une requête pour /foo/bar/baz est traité, une expression comme ^bar/baz$ correspondra.

Si une substitution intervient dans un contexte de répertoire, une nouvelle sous-requête interne est générée avec la nouvelle URL, ce qui relance le traitement des phases de la requête. Si la substitution est un chemin relatif, la directive RewriteBase détermine le chemin URL devant préfixer cette substitution. Dans un contexte de répertoire, il faut s'assurer de créer des règles qui n'effectueront pas de substitution au cours d'une passe ultérieure du processus de réécriture au niveau répertoire afin d'éviter les bouclages . Voir Bouclage dans le processus de réécriture pour une discussion plus détaillée à propos de ce problème.

En conséquence de cette manipulation de l'URL , vous devrez pensez à confectionner différemment vos règles de réécriture dans un contexte de niveau répertoire. En particulier, rappelez-vous que le chemin de répertoire sera absent de l'URL que vos règles de réécriture verront. Voici quelques exemples qui permettront de clarifier les choses :

Position de la règle Règle
Section VirtualHost RewriteRule ^/images/(.+)\.jpg /images/$1.gif
Fichier .htaccess à la racine des documents RewriteRule ^images/(.+)\.jpg images/$1.gif
Fichier .htaccess dans le répertoire images RewriteRule ^(.+)\.jpg $1.gif

Pour une étude plus approfondie de la manière dont mod_rewrite manipule les URLs dans les différents contextes, vous pouvez consulter les entrées du journal générées au cours du processus de réécriture.

Traitement du jeu de règles

Maintenant, quand mod_rewrite se lance dans ces deux phases de l'API, il lit le jeu de règles configurées depuis la structure contenant sa configuration (qui a été elle-même créée soit au démarrage d'Apache pour le contexte du serveur, soit lors du parcours des répertoires par le noyau d'Apache pour le contexte de répertoire). Puis le moteur de réécriture est démarré avec le jeu de règles contenu (une ou plusieurs règles associées à leurs conditions). En lui-même, le mode opératoire du moteur de réécriture d'URLs est exactement le même dans les deux contextes de configuration. Seul le traitement du résultat final diffère.

L'ordre dans lequel les règles sont définies est important car le moteur de réécriture les traite selon une chronologie particulière (et pas très évidente). Le principe est le suivant : le moteur de réécriture traite les règles (les directives RewriteRule) les unes à la suite des autres, et lorsqu'une règle s'applique, il parcourt les éventuelles conditions (directives RewriteConddirectives) associées. Pour des raisons historiques, les conditions précèdent les règles, si bien que le déroulement du contrôle est un peu compliqué. Voir la figure 1 pour plus de détails.

Flux des comparaisons des directives RewriteRule et RewriteCond
Figure 1:Déroulement du contrôle à travers le jeu de règles de réécriture

L'URL est tout d'abord comparée au Modèle de chaque règle. Lorsqu'une règle ne s'applique pas, mod_rewrite stoppe immédiatement le traitement de cette règle et passe à la règle suivante. Si l'URL correspond au Modèle, mod_rewrite recherche la présence de conditions correspondantes (les directives Rewritecond apparaissant dans la configuration juste avant les règles de réécriture). S'il n'y en a pas, mod_rewrite remplace l'URL par une chaîne élaborée à partir de la chaîne de Substitution, puis passe à la règle suivante. Si des conditions sont présentes, mod_rewrite lance un bouclage secondaire afin de les traiter selon l'ordre dans lequel elles sont définies. La logique de traitement des conditions est différente : on ne compare pas l'URL à un modèle. Une chaîne de test TestString est tout d'abord élaborée en développant des variables, des références arrières, des recherches dans des tables de correspondances, etc..., puis cette chaîne de test est comparée au modèle de condition CondPattern. Si le modèle ne correspond pas, les autres conditions du jeu ne sont pas examinées et la règle correspondante ne s'applique pas. Si le modèle correspond, la condition suivante est examinée et ainsi de suite jusqu'à la dernière condition. Si toutes les conditions sont satisfaites, le traitement de la règle en cours se poursuit avec le remplacement de l'URL par la chaîne de Substitution.