From: Vincent Deffontaines Date: Wed, 15 Jul 2009 20:27:34 +0000 (+0000) Subject: rewrite : Completed the doc .fr translation. X-Git-Tag: 2.3.3~439 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c77e341ef26f70249f0ebd2025987f3935378a64;p=apache rewrite : Completed the doc .fr translation. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@794405 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/rewrite/rewrite_flags.html b/docs/manual/rewrite/rewrite_flags.html index ac41b36d61..1f941ffc8c 100644 --- a/docs/manual/rewrite/rewrite_flags.html +++ b/docs/manual/rewrite/rewrite_flags.html @@ -3,3 +3,7 @@ URI: rewrite_flags.html.en Content-Language: en Content-type: text/html; charset=ISO-8859-1 + +URI: rewrite_flags.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 diff --git a/docs/manual/rewrite/rewrite_flags.html.fr b/docs/manual/rewrite/rewrite_flags.html.fr new file mode 100644 index 0000000000..ab754d02c3 --- /dev/null +++ b/docs/manual/rewrite/rewrite_flags.html.fr @@ -0,0 +1,462 @@ + + + +Les drapeaux du module Apache mod_rewrite - Serveur Apache HTTP + + + + + +
<-
+
+Apache > Serveur HTTP > Documentation > Version 2.3 > Rewrite

Les drapeaux du module Apache mod_rewrite

+
+

Langues Disponibles:  en  | + fr 

+
+ +

Ce document décrit les drapeaux disponibles dans la directive +RewriteRule, en fournissant +des explications détaillées et des exemples. Vous n'y trouverez pas +une liste exhaustive de tous les drapeaux disponibles, c'est pourquoi +vous devez aussi consulter la documentation de référence.

+
+ +
top
+
+

Introduction

+

Le comportement des directives RewriteRule peut être modifié par un ou +plusieurs drapeaux. Les drapeaux sont situés en fin de règle, entourés +de crochets, et séparés le cas échéant par des virgules.

+

+RewriteRule modèle cible [drapeau1,drapeau2,drapeau3] +

+ +

Les drapeaux ont tous une forme courte, comme CO, ainsi +qu'une forme longue, comme cookie. Certains drapeaux +peuvent avoir un ou plusieurs arguments. Les drapeaux sont insensibles à +la casse.

+ +
top
+
+

Les drapeaux

+ +

Chaque drapeau possède une forme longue et une forme courte. Bien que +la forme courte soit la plus couramment utilisée, nous vous recommandons +de vous familiariser avec les drapeaux sous leur forme longue, afin de +bien mémoriser ce que chaque drapeau est supposé faire.

+ +

Chaque drapeau disponible est présenté ici, avec un exemple +d'utilisation.

+ +

C|chain

+

Le drapeau [C] ou [chain] indique que la règle RewriteRule est chaînée avec la +suivante. Autrement dit, si la règle s'applique, elle est traitée +normalement et passe le contrôle à la règle suivante. Par contre, si +elle ne s'applique pas, la règle suivante, ainsi que toutes les règles +chaînées qui suivent, seront sautées.

+ + + +

CO|cookie

+

Le drapeau [CO], ou [cookie], vous permet de définir un cookie +lorsqu'une règle RewriteRule +s'applique. Il possède cinq arguments dont trois sont obligatoires et +deux optionnels.

+

Vous devez déclarer un nom et une valeur pour définir le cookie, +ainsi que le domaine pour lequel vous souhaitez que le cookie soit +valide. Vous pouvez aussi définir la durée de vie du cookie, ainsi que +le chemin pour lequel il doit être renvoyé.

+

Par défaut, la durée de vie du cookie correspond à la session du +navigateur en cours.

+

Par défaut, le chemin pour lequel le cookie sera valide est "/" - +c'est à dire, pour tout le site web.

+

Voici un exemple :

+ +

+RewriteEngine On
+RewriteRule ^/index\.html - [CO=frontdoor:yes:.apache.org:1440:/] +

+ +

Cette règle ne réécrit pas la requête (la cible de réécriture "-" +indique à mod_rewrite de transmettre la requête sans modification), mais +définit un cookie nommé 'frontdoor' avec une valeur 'yes'. Le cookie est +valide pour tout hôte situé dans le domaine .apache.org. Sa +durée de vie est limitée à 1440 minutes (24 heures), et il sera renvoyé +pour tous les URIs.

+ + + +

E|env

+

Avec le drapeau [E], ou [env], vous pouvez définir la valeur d'une +variable d'environnement. Notez que certaines variables d'environnement +peuvent être définies après le traitement de la règle, annulant par +la-même ce que vous avez défini. Voir le document +sur les variables d'environnement pour plus de détails sur le +fonctionnement des variables d'environnement.

+ +

L'exemple suivant définit une variable d'environnement nommée 'image' +avec une valeur de '1' si l'URI de la requête correspond à un fichier +image. Cette variable d'environnement est ensuite utilisée pour exclure +une telle requête du journal des accès.

+ +

+RewriteRule \.(png|gif|jpg) - [E=image:1]
+CustomLog logs/access_log combined env=!image +

+ +

Notez que le même effet peut être obtenu à l'aide de la directive +SetEnvIf. Cette technique +est présentée à titre d'exemple et non de recommandation.

+ + +

F|forbidden

+

L'utilisation du drapeau [F] permet de faire envoyer par Apache au +client un code de statut "403 Forbidden". Le même effet peut être obtenu à +l'aide de la directive Deny, +mais ce drapeau offre plus de souplesse dans l'attribution d'un statut +Forbidden.

+ +

La règle suivante va interdire la téléchargement de fichiers +.exe depuis votre serveur.

+ +

+RewriteRule \.exe - [F] +

+ +

Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce +qui signifie que l'URI de la requête n'est pas modifié. Il n'y a aucune +raison de réécrire un URI, si vous avez l'intention d'interdire la +requête.

+ + + +

G|gone

+

Le drapeau [G] permet de faire envoyer par Apache un code de statut +"410 Gone" avec la réponse. Ce code indique qu'une ressource qui était +disponible auparavant ne l'est plus actuellement.

+ +

Comme dans le cas du drapeau [F], on utilise en général la syntaxe +"-" pour la cible de réécriture lorsqu'on utilise le drapeau [G] :

+ +

+RewriteRule ancienne-ressource - [G,NC] +

+ + +

H|handler

+

Force le traitement de la requête résultante par le gestionnaire +spécifié. Par exemple, on peut utiliser ce drapeau pour forcer +l'interprétation de tous les fichiers sans extension par le gestionnaire +php :

+ +

+RewriteRule !\. - [H=application/x-httpd-php] +

+ +

+L'expression rationnelle ci-dessus - !\. - correspond à +toute requête qui ne contient pas le caractère .. +

+

On peut aussi utiliser ce drapeau pour forcer l'utilisation d'un +certain gestionnaire en fonction de certaines conditions. Par exemple, +l'extrait suivant utilisé dans un contexte de niveau serveur permet de +faire en sorte que les fichiers .php soient +affichés par mod_php dans le cas où ils font +l'objet d'une requête avec l'extension .phps : + +

+RewriteRule ^(/source/.+\.php)s$ $1 [H=application/x-httpd-php-source] +

+

+ +

L'expression rationnelle ci-dessus - +^(/source/.+\.php)s$ - va correspondre à toute requête qui +débutera par /source/, continuera par 1 ou n caractères +puis par .phps. La référence arrière $1 fait référence à la +correspondance capturée entre parenthèses de l'expression +rationnelle.

+ + + + +

L|last

+

Lorsque le drapeau [L] est présent, mod_rewrite +arrête le traitement du jeu de règles. Cela signifie dans la plupart des +situations que si la règle s'applique, aucune autre règle ne sera +traitée.

+ +

Si vous utilisez des règles RewriteRule dans des fichiers +.htaccess ou des sections <Directory>, il est important d'avoir quelques +notions sur la manière dont les règles sont traitées. Pour simplifier, +une fois les règles traitées, la requête réécrite est passée à nouveau +au moteur d'interprétation des URLs afin que ce dernier puisse la +traiter. Il est possible qu'au cours du traitement de la requête +réécrite, le fichier .htaccess ou la section <Directory> soient à nouveau +rencontrés, entraînant un nouveau traitement du jeu de règles depuis le +début. Cette situation se présente le plus souvent lorsqu'une des règles +provoque une redirection - interne ou externe - ce qui réinitialise le +traitement de la requête.

+ +

Si vous utilisez des directives RewriteRule dans un de ces contextes, +il importe par conséquent de prévoir explicitement des étapes permettant +d'éviter un bouclage infini sur les règles, +et de ne pas compter seulement sur +le drapeau [L] pour terminer l'exécution d'une série de règles, comme +décrit ci-dessous.

+ +

Dans l'exemple donné ici, toute requête est réécrite en +index.php, la requête originale étant ajoutée comme chaîne +de requête en argument à index.php ; cependant, la +directive RewriteCond permet de s'assurer que si +la requête concerne déjà index.php, la directive RewriteRule sera sautée.

+ +

+RewriteCond %{REQUEST_URI} !=index\.php
+RewriteRule ^(.*) index.php?req=$1 [L] +

+ + +

N|next

+

Le drapeau [N] provoque un redémarrage du traitement des règles +depuis le début ; à utiliser avec précautions car il peut provoquer un +bouclage infini. +

+

+Le drapeau [Next] peut servir, par exemple, +à remplacer de manière répétitive +une chaîne de caractère ou une lettre dans une requête. Dans l'exemple +suivant, chaque occurence de A sera remplacée par B dans la requête, et +ceci jusqu'il n'y ait plus de A à remplacer. +

+ +

+RewriteRule (.*)A(.*) $1B$2 [N] +

+ +

Vous pouvez vous représenter ce traitement comme une boucle +while : tant que le modèle de la règle correspond (c'est à +dire, tant que l'URI contient un A), +effectuer la substitution (c'est à dire, remplacer le A par +un B).

+ + + +

NC|nocase

+

Avec le drapeau [NC], le modèle de la règle RewriteRule est comparé à la requête de +manière insensible à la casse. C'est à dire que cette comparaison +s'effectue sans tenir compte des majuscules/minuscules dans l'URI +comparé.

+ +

Dans l'exemple suivant, toute requête pour un fichier image sera +transmise par Apache à votre serveur d'images dédié. La correspondance est +insensible à la casse, si bien que par exemple, .jpg aussi +bien que .JPG seront acceptés.

+ +

+RewriteRule (.*\.(jpg|gif|png))$ http://images.example.com$1 [P,NC] +

+ + +

NE|noescape

+

Par défaut, les caractères spéciaux, comme & et +?, sont convertis en leur équivalent +hexadécimal. Le drapeau [NE] permet d'éviter cette conversion. +

+ +

+RewriteRule ^/ancre/(.+) /grosse-page.html#$1 [NE,R] +

+ +

+Dans l'exemple ci-dessus, /anchor/xyz est réécrit en +/bigpage.html#xyz. En l'absence du drapeau [NE], le # +aurait été converti en son équivalent hexadécimal, %23, ce +qui aurait provoqué un code d'erreur "404 Not Found". +

+ + + +

NS|nosubreq

+

Le drapeau [NS] empêche la règle de s'appliquer aux sous-requêtes. +Par exemple, une page incluse au moyen d'une SSI (Server +Side Include) est une sous-requête, et vous ne voudrez peut-être pas que +la réécriture s'applique à ces sous-requêtes.

+ +

+Les images, scripts java, ou fichiers css, chargés en tant que partie +d'une page html, ne sont pas des sous-requêtes - le navigateur les +appelle sous forme de requêtes HTTP à part entière. +

+ + +

P|proxy

+

L'utilisation du drapeau [P] entraîne le traitement de la requête par +le module mod_proxy, et ceci via une requête de +mandataire. Par exemple, si vous voulez que toutes les requêtes d'images +soient traitées par un serveur d'images annexe, vous pouvez utiliser +une règle de ce style :

+ +

+RewriteRule (.*)\.(jpg|gif|png) http://images.exemple.com$1.$2 [P] +

+ +

L'utilisation du drapeau [P] provoque aussi l'effet du drapeau [L] - +autrement dit, la requête est immédiatement envoyée au mandataire, et +toute règle ultérieure sera ignorée.

+ + + +

PT|passthrough

+ +

+Par défaut, la cible (ou chaîne de substitution) d'une règle +RewriteRule est sensée être un chemin de fichier. Avec le drapeau [PT], +par contre, elle est traitée comme un URI. Autrement dit, avec le +drapeau [PT], le résultat de la règle RewriteRule est passé à nouveau au +système de mise en correspondance des URLs avec le système de fichiers, +de façon à ce que les systèmes de mise en correspondance basés sur les +chemins de fichiers, comme la directive Alias, par exemple, puissent avoir une +chance d'accomplir leur tâche. +

+ +

+Si par exemple, vous avez un Alias pour /icons, et une règle RewriteRule qui renvoie vers /icons, +vous devez utiliser le drapeau [PT] pour être sûr que l'Alias sera bien évalué. +

+ +

+Alias /icons /usr/local/apache/icons
+RewriteRule /pics/(.+)\.jpg /icons/$1.gif [PT] +

+ +

+Dans l'exemple précédent, en l'absence du drapeau [PT], l'Alias aurait +été ignoré, ce qui aurait provoqué une erreur 'File not found'. +

+ + + +

QSA|qsappend

+

+Quand l'URI de remplacement contient une chaîne de requête, le +comportement par défaut de la règle RewriteRule est de supprimer la +query string (il s'agit des paramètres éventuellement passés dans l'URL après le +caractère ?, usuellement pour les formulaires traités par la +méthode HTTP GET) existante, et de la remplacer par celle nouvellement créée. +Avec le drapeau [QSA], les chaînes de requête peuvent être combinées. +

+ +

Considérons la règle suivante :

+ +

+RewriteRule /pages/(.+) /page.php?page=$1 [QSA] +

+ +

Avec le drapeau [QSA], une requête pour +/pages/123?one=two sera réécrite en +/page.php?page=123&one=two. Sans le drapeau [QSA], la +même requête sera réécrite en /page.php?page=123 - +autrement dit, la chaîne de requête (query string) existante sera supprimée. +

+ + +

R|redirect

+

+L'utilisation du drapeau [R] provoque l'envoi d'une redirection au +navigateur. Si une URL pleinement qualifiée (FQDN - fully qualified domain name) + est spécifiée (c'est à dire incluant http://nom-du-serveur/), + une redirection sera effectuée vers cette adresse. Dans le cas contraire, + c'est le nom du serveur local qui sera utilisé pour générer l'URL envoyée avec la +redirection. +

+ +

+Un code de statut entre 300 et 399 peut être spécifié, le code 302 étant +utilisé par défaut si aucun code n'est spécifié. +

+ +

+Vous utiliserez presque toujours [R] en conjonction avec [L] (c'est à +dire [R,L]), car employé seul, le drapeau [R] préfixe l'URI avec +http://cet-hôte[:ce-port], mais passe ensuite cette adresse +à la règle suivante, ce qui provoquera le plus souvent des +avertissements 'Invalid URI in request'. +

+ + + +

S|skip

+

Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir +exécuter. Ceci peut s'interpréter comme une instruction +goto dans votre jeu de règles de réécriture. Dans +l'exemple suivant, nous ne voulons exécuter la règle RewriteRule que si l'URI demandé ne +correspond pas à un fichier existant.

+ +

+# La requête concerne-t-elle un fichier qui n'existe pas ?
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+# Si c'est la cas, on saute les deux règles de réécriture suivantes
+RewriteRule .? - [S=2]
+
+RewriteRule (.*\.gif) images.php?$1
+RewriteRule (.*\.html) docs.php?$1 +

+ +

Cette technique trouve son utilité dans le fait qu'une directive +RewriteCond ne s'applique +qu'à la règle qui la suit immédiatement. Ainsi, si vous voulez +qu'une directive RewriteCond s'applique à plusieurs règles +RewriteRule, vous pouvez utiliser le drapeau [Skip].

+ + + +

T|type

+

Définit le type MIME de la réponse résultante renvoyée. L'effet est +identique à celui de la directive AddType.

+ +

Par exemple, vous pouvez utiliser la technique suivante pour servir +du code source Perl en tant que plein texte, s'il est requis d'une +certaine manière :

+ +

+# Sert les fichier .pl en tant que plein texte
+RewriteRule \.pl$ - [T=text/plain] +

+ +

Ou encore, si vous possédez une caméra qui produit des fichiers +images jpeg sans extension, vous pouvez forcer le renvoi de ces images +avec le type MIME correct en se basant sur le nom du fichier :

+ +

+# Les fichiers dont le nom contient 'IMG' sont des images jpg.
+RewriteRule IMG - [T=image/jpg] +

+ +

Notez cependant qu'il s'agit d'un exemple trivial, et que le problème +aurait pu être résolu en utilisant à la place la directive <FilesMatch>. Il faut toujours +envisager la possibilité d'une solution alternative à un problème avant +d'avoir recours à la réécriture, qui sera toujours moins efficace qu'une +solution alternative.

+ + +
+
+

Langues Disponibles:  en  | + fr 

+
+ \ No newline at end of file diff --git a/docs/manual/rewrite/rewrite_flags.xml.fr b/docs/manual/rewrite/rewrite_flags.xml.fr new file mode 100644 index 0000000000..df15e44e27 --- /dev/null +++ b/docs/manual/rewrite/rewrite_flags.xml.fr @@ -0,0 +1,482 @@ + + + + + + + + + + +Rewrite + + Les drapeaux du module Apache mod_rewrite + + +

Ce document décrit les drapeaux disponibles dans la directive +RewriteRule, en fournissant +des explications détaillées et des exemples. Vous n'y trouverez pas +une liste exhaustive de tous les drapeaux disponibles, c'est pourquoi +vous devez aussi consulter la documentation de référence.

+
+ +Documentation du module +Détails techniques +Guide de réécriture - exemples +utiles +Guide de réécriture +avancée - exemples utiles avancés + +
Introduction +

Le comportement des directives RewriteRule peut être modifié par un ou +plusieurs drapeaux. Les drapeaux sont situés en fin de règle, entourés +de crochets, et séparés le cas échéant par des virgules.

+ +RewriteRule modèle cible [drapeau1,drapeau2,drapeau3] + + +

Les drapeaux ont tous une forme courte, comme CO, ainsi +qu'une forme longue, comme cookie. Certains drapeaux +peuvent avoir un ou plusieurs arguments. Les drapeaux sont insensibles à +la casse.

+ +
+ +
Les drapeaux + +

Chaque drapeau possède une forme longue et une forme courte. Bien que +la forme courte soit la plus couramment utilisée, nous vous recommandons +de vous familiariser avec les drapeaux sous leur forme longue, afin de +bien mémoriser ce que chaque drapeau est supposé faire.

+ +

Chaque drapeau disponible est présenté ici, avec un exemple +d'utilisation.

+ +
C|chain +

Le drapeau [C] ou [chain] indique que la règle RewriteRule est chaînée avec la +suivante. Autrement dit, si la règle s'applique, elle est traitée +normalement et passe le contrôle à la règle suivante. Par contre, si +elle ne s'applique pas, la règle suivante, ainsi que toutes les règles +chaînées qui suivent, seront sautées.

+ +
+ +
CO|cookie +

Le drapeau [CO], ou [cookie], vous permet de définir un cookie +lorsqu'une règle RewriteRule +s'applique. Il possède cinq arguments dont trois sont obligatoires et +deux optionnels.

+

Vous devez déclarer un nom et une valeur pour définir le cookie, +ainsi que le domaine pour lequel vous souhaitez que le cookie soit +valide. Vous pouvez aussi définir la durée de vie du cookie, ainsi que +le chemin pour lequel il doit être renvoyé.

+

Par défaut, la durée de vie du cookie correspond à la session du +navigateur en cours.

+

Par défaut, le chemin pour lequel le cookie sera valide est "/" - +c'est à dire, pour tout le site web.

+

Voici un exemple :

+ + +RewriteEngine On
+RewriteRule ^/index\.html - [CO=frontdoor:yes:.apache.org:1440:/] +
+ +

Cette règle ne réécrit pas la requête (la cible de réécriture "-" +indique à mod_rewrite de transmettre la requête sans modification), mais +définit un cookie nommé 'frontdoor' avec une valeur 'yes'. Le cookie est +valide pour tout hôte situé dans le domaine .apache.org. Sa +durée de vie est limitée à 1440 minutes (24 heures), et il sera renvoyé +pour tous les URIs.

+ +
+ +
E|env +

Avec le drapeau [E], ou [env], vous pouvez définir la valeur d'une +variable d'environnement. Notez que certaines variables d'environnement +peuvent être définies après le traitement de la règle, annulant par +la-même ce que vous avez défini. Voir le document +sur les variables d'environnement pour plus de détails sur le +fonctionnement des variables d'environnement.

+ +

L'exemple suivant définit une variable d'environnement nommée 'image' +avec une valeur de '1' si l'URI de la requête correspond à un fichier +image. Cette variable d'environnement est ensuite utilisée pour exclure +une telle requête du journal des accès.

+ + +RewriteRule \.(png|gif|jpg) - [E=image:1]
+CustomLog logs/access_log combined env=!image +
+ +

Notez que le même effet peut être obtenu à l'aide de la directive +SetEnvIf. Cette technique +est présentée à titre d'exemple et non de recommandation.

+
+ +
F|forbidden +

L'utilisation du drapeau [F] permet de faire envoyer par Apache au +client un code de statut "403 Forbidden". Le même effet peut être obtenu à +l'aide de la directive Deny, +mais ce drapeau offre plus de souplesse dans l'attribution d'un statut +Forbidden.

+ +

La règle suivante va interdire la téléchargement de fichiers +.exe depuis votre serveur.

+ + +RewriteRule \.exe - [F] + + +

Cet exemple utilise la syntaxe "-" pour la cible de réécriture, ce +qui signifie que l'URI de la requête n'est pas modifié. Il n'y a aucune +raison de réécrire un URI, si vous avez l'intention d'interdire la +requête.

+ +
+ +
G|gone +

Le drapeau [G] permet de faire envoyer par Apache un code de statut +"410 Gone" avec la réponse. Ce code indique qu'une ressource qui était +disponible auparavant ne l'est plus actuellement.

+ +

Comme dans le cas du drapeau [F], on utilise en général la syntaxe +"-" pour la cible de réécriture lorsqu'on utilise le drapeau [G] :

+ + +RewriteRule ancienne-ressource - [G,NC] + +
+ +
H|handler +

Force le traitement de la requête résultante par le gestionnaire +spécifié. Par exemple, on peut utiliser ce drapeau pour forcer +l'interprétation de tous les fichiers sans extension par le gestionnaire +php :

+ + +RewriteRule !\. - [H=application/x-httpd-php] + + +

+L'expression rationnelle ci-dessus - !\. - correspond à +toute requête qui ne contient pas le caractère .. +

+

On peut aussi utiliser ce drapeau pour forcer l'utilisation d'un +certain gestionnaire en fonction de certaines conditions. Par exemple, +l'extrait suivant utilisé dans un contexte de niveau serveur permet de +faire en sorte que les fichiers .php soient +affichés par mod_php dans le cas où ils font +l'objet d'une requête avec l'extension .phps : + + +RewriteRule ^(/source/.+\.php)s$ $1 [H=application/x-httpd-php-source] + +

+ +

L'expression rationnelle ci-dessus - +^(/source/.+\.php)s$ - va correspondre à toute requête qui +débutera par /source/, continuera par 1 ou n caractères +puis par .phps. La référence arrière $1 fait référence à la +correspondance capturée entre parenthèses de l'expression +rationnelle.

+ + +
+ +
L|last +

Lorsque le drapeau [L] est présent, mod_rewrite +arrête le traitement du jeu de règles. Cela signifie dans la plupart des +situations que si la règle s'applique, aucune autre règle ne sera +traitée.

+ +

Si vous utilisez des règles RewriteRule dans des fichiers +.htaccess ou des sections Directory, il est important d'avoir quelques +notions sur la manière dont les règles sont traitées. Pour simplifier, +une fois les règles traitées, la requête réécrite est passée à nouveau +au moteur d'interprétation des URLs afin que ce dernier puisse la +traiter. Il est possible qu'au cours du traitement de la requête +réécrite, le fichier .htaccess ou la section Directory soient à nouveau +rencontrés, entraînant un nouveau traitement du jeu de règles depuis le +début. Cette situation se présente le plus souvent lorsqu'une des règles +provoque une redirection - interne ou externe - ce qui réinitialise le +traitement de la requête.

+ +

Si vous utilisez des directives RewriteRule dans un de ces contextes, +il importe par conséquent de prévoir explicitement des étapes permettant +d'éviter un bouclage infini sur les règles, +et de ne pas compter seulement sur +le drapeau [L] pour terminer l'exécution d'une série de règles, comme +décrit ci-dessous.

+ +

Dans l'exemple donné ici, toute requête est réécrite en +index.php, la requête originale étant ajoutée comme chaîne +de requête en argument à index.php ; cependant, la +directive RewriteCond permet de s'assurer que si +la requête concerne déjà index.php, la directive RewriteRule sera sautée.

+ + +RewriteCond %{REQUEST_URI} !=index\.php
+RewriteRule ^(.*) index.php?req=$1 [L] +
+
+ +
N|next +

Le drapeau [N] provoque un redémarrage du traitement des règles +depuis le début ; à utiliser avec précautions car il peut provoquer un +bouclage infini. +

+

+Le drapeau [Next] peut servir, par exemple, +à remplacer de manière répétitive +une chaîne de caractère ou une lettre dans une requête. Dans l'exemple +suivant, chaque occurence de A sera remplacée par B dans la requête, et +ceci jusqu'il n'y ait plus de A à remplacer. +

+ + +RewriteRule (.*)A(.*) $1B$2 [N] + + +

Vous pouvez vous représenter ce traitement comme une boucle +while : tant que le modèle de la règle correspond (c'est à +dire, tant que l'URI contient un A), +effectuer la substitution (c'est à dire, remplacer le A par +un B).

+ +
+ +
NC|nocase +

Avec le drapeau [NC], le modèle de la règle RewriteRule est comparé à la requête de +manière insensible à la casse. C'est à dire que cette comparaison +s'effectue sans tenir compte des majuscules/minuscules dans l'URI +comparé.

+ +

Dans l'exemple suivant, toute requête pour un fichier image sera +transmise par Apache à votre serveur d'images dédié. La correspondance est +insensible à la casse, si bien que par exemple, .jpg aussi +bien que .JPG seront acceptés.

+ + +RewriteRule (.*\.(jpg|gif|png))$ http://images.example.com$1 [P,NC] + +
+ +
NE|noescape +

Par défaut, les caractères spéciaux, comme & et +?, sont convertis en leur équivalent +hexadécimal. Le drapeau [NE] permet d'éviter cette conversion. +

+ + +RewriteRule ^/ancre/(.+) /grosse-page.html#$1 [NE,R] + + +

+Dans l'exemple ci-dessus, /anchor/xyz est réécrit en +/bigpage.html#xyz. En l'absence du drapeau [NE], le # +aurait été converti en son équivalent hexadécimal, %23, ce +qui aurait provoqué un code d'erreur "404 Not Found". +

+ +
+ +
NS|nosubreq +

Le drapeau [NS] empêche la règle de s'appliquer aux sous-requêtes. +Par exemple, une page incluse au moyen d'une SSI (Server +Side Include) est une sous-requête, et vous ne voudrez peut-être pas que +la réécriture s'applique à ces sous-requêtes.

+ +

+Les images, scripts java, ou fichiers css, chargés en tant que partie +d'une page html, ne sont pas des sous-requêtes - le navigateur les +appelle sous forme de requêtes HTTP à part entière. +

+
+ +
P|proxy +

L'utilisation du drapeau [P] entraîne le traitement de la requête par +le module mod_proxy, et ceci via une requête de +mandataire. Par exemple, si vous voulez que toutes les requêtes d'images +soient traitées par un serveur d'images annexe, vous pouvez utiliser +une règle de ce style :

+ + +RewriteRule (.*)\.(jpg|gif|png) http://images.exemple.com$1.$2 [P] + + +

L'utilisation du drapeau [P] provoque aussi l'effet du drapeau [L] - +autrement dit, la requête est immédiatement envoyée au mandataire, et +toute règle ultérieure sera ignorée.

+ +
+ +
PT|passthrough + +

+Par défaut, la cible (ou chaîne de substitution) d'une règle +RewriteRule est sensée être un chemin de fichier. Avec le drapeau [PT], +par contre, elle est traitée comme un URI. Autrement dit, avec le +drapeau [PT], le résultat de la règle RewriteRule est passé à nouveau au +système de mise en correspondance des URLs avec le système de fichiers, +de façon à ce que les systèmes de mise en correspondance basés sur les +chemins de fichiers, comme la directive Alias, par exemple, puissent avoir une +chance d'accomplir leur tâche. +

+ +

+Si par exemple, vous avez un Alias pour /icons, et une règle RewriteRule qui renvoie vers /icons, +vous devez utiliser le drapeau [PT] pour être sûr que l'Alias sera bien évalué. +

+ + +Alias /icons /usr/local/apache/icons
+RewriteRule /pics/(.+)\.jpg /icons/$1.gif [PT] +
+ +

+Dans l'exemple précédent, en l'absence du drapeau [PT], l'Alias aurait +été ignoré, ce qui aurait provoqué une erreur 'File not found'. +

+ +
+ +
QSA|qsappend +

+Quand l'URI de remplacement contient une chaîne de requête, le +comportement par défaut de la règle RewriteRule est de supprimer la +query string (il s'agit des paramètres éventuellement passés dans l'URL après le +caractère ?, usuellement pour les formulaires traités par la +méthode HTTP GET) existante, et de la remplacer par celle nouvellement créée. +Avec le drapeau [QSA], les chaînes de requête peuvent être combinées. +

+ +

Considérons la règle suivante :

+ + +RewriteRule /pages/(.+) /page.php?page=$1 [QSA] + + +

Avec le drapeau [QSA], une requête pour +/pages/123?one=two sera réécrite en +/page.php?page=123&one=two. Sans le drapeau [QSA], la +même requête sera réécrite en /page.php?page=123 - +autrement dit, la chaîne de requête (query string) existante sera supprimée. +

+
+ +
R|redirect +

+L'utilisation du drapeau [R] provoque l'envoi d'une redirection au +navigateur. Si une URL pleinement qualifiée (FQDN - fully qualified domain name) + est spécifiée (c'est à dire incluant http://nom-du-serveur/), + une redirection sera effectuée vers cette adresse. Dans le cas contraire, + c'est le nom du serveur local qui sera utilisé pour générer l'URL envoyée avec la +redirection. +

+ +

+Un code de statut entre 300 et 399 peut être spécifié, le code 302 étant +utilisé par défaut si aucun code n'est spécifié. +

+ +

+Vous utiliserez presque toujours [R] en conjonction avec [L] (c'est à +dire [R,L]), car employé seul, le drapeau [R] préfixe l'URI avec +http://cet-hôte[:ce-port], mais passe ensuite cette adresse +à la règle suivante, ce qui provoquera le plus souvent des +avertissements 'Invalid URI in request'. +

+ +
+ +
S|skip +

Le drapeau [S] sert à sauter des règles que vous ne voulez pas voir +exécuter. Ceci peut s'interpréter comme une instruction +goto dans votre jeu de règles de réécriture. Dans +l'exemple suivant, nous ne voulons exécuter la règle RewriteRule que si l'URI demandé ne +correspond pas à un fichier existant.

+ + +# La requête concerne-t-elle un fichier qui n'existe pas ?
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+# Si c'est la cas, on saute les deux règles de réécriture suivantes
+RewriteRule .? - [S=2]
+
+RewriteRule (.*\.gif) images.php?$1
+RewriteRule (.*\.html) docs.php?$1 +
+ +

Cette technique trouve son utilité dans le fait qu'une directive +RewriteCond ne s'applique +qu'à la règle qui la suit immédiatement. Ainsi, si vous voulez +qu'une directive RewriteCond s'applique à plusieurs règles +RewriteRule, vous pouvez utiliser le drapeau [Skip].

+ +
+ +
T|type +

Définit le type MIME de la réponse résultante renvoyée. L'effet est +identique à celui de la directive AddType.

+ +

Par exemple, vous pouvez utiliser la technique suivante pour servir +du code source Perl en tant que plein texte, s'il est requis d'une +certaine manière :

+ + +# Sert les fichier .pl en tant que plein texte
+RewriteRule \.pl$ - [T=text/plain] +
+ +

Ou encore, si vous possédez une caméra qui produit des fichiers +images jpeg sans extension, vous pouvez forcer le renvoi de ces images +avec le type MIME correct en se basant sur le nom du fichier :

+ + +# Les fichiers dont le nom contient 'IMG' sont des images jpg.
+RewriteRule IMG - [T=image/jpg] +
+ +

Notez cependant qu'il s'agit d'un exemple trivial, et que le problème +aurait pu être résolu en utilisant à la place la directive FilesMatch. Il faut toujours +envisager la possibilité d'une solution alternative à un problème avant +d'avoir recours à la réécriture, qui sera toujours moins efficace qu'une +solution alternative.

+
+ +
+
+ diff --git a/docs/manual/rewrite/rewrite_flags.xml.meta b/docs/manual/rewrite/rewrite_flags.xml.meta index 7d8345abb3..57b0a2c225 100644 --- a/docs/manual/rewrite/rewrite_flags.xml.meta +++ b/docs/manual/rewrite/rewrite_flags.xml.meta @@ -8,5 +8,6 @@ en + fr diff --git a/docs/manual/rewrite/rewrite_guide_advanced.html b/docs/manual/rewrite/rewrite_guide_advanced.html index d08ed10d2a..033c866218 100644 --- a/docs/manual/rewrite/rewrite_guide_advanced.html +++ b/docs/manual/rewrite/rewrite_guide_advanced.html @@ -3,3 +3,7 @@ URI: rewrite_guide_advanced.html.en Content-Language: en Content-type: text/html; charset=ISO-8859-1 + +URI: rewrite_guide_advanced.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 diff --git a/docs/manual/rewrite/rewrite_guide_advanced.html.fr b/docs/manual/rewrite/rewrite_guide_advanced.html.fr new file mode 100644 index 0000000000..652e3c4823 --- /dev/null +++ b/docs/manual/rewrite/rewrite_guide_advanced.html.fr @@ -0,0 +1,1379 @@ + + + +Guide de réécriture des URLs - Sujets avancés - Serveur Apache HTTP + + + + + +
<-
+
+Apache > Serveur HTTP > Documentation > Version 2.3 > Rewrite

Guide de réécriture des URLs - Sujets avancés

+
+

Langues Disponibles:  en  | + fr 

+
+ + +

Ce document complémente la + documentation de référence du + module mod_rewrite. Il décrit les différentes + manières d'utiliser le module d'Apache mod_rewrite + pour résoudre les problèmes d'URLs typiques auxquels sont souvent + confrontés les webmasters. Nous fournissons une description + détaillée de la résolution de chaque problème par la configuration + d'un jeu de règles de réécriture.

+ +
ATTENTION: il pourra s'avérer nécessaire de + modifier les exemples en fonction de la + configuration de votre serveur, par exemple en ajoutant le drapeau + [PT] si les modules mod_alias et + mod_userdir sont utilisés, etc... Les jeux de + règles devront également être adaptés pour passer d'un contexte de + serveur à un contexte de répertoire (fichiers + .htaccess). Essayez de toujours bien comprendre ce que + fait un jeu de règles avant de l'utiliser, ce qui pourra vous éviter + bien des problèmes.
+ +
+ +
top
+
+

Accès à une grappe de serveurs via un espace d'adressage + compatible

+ + + +
+
Description :
+ +
+

Comment créer un espace d'adressage homogène et compatible + avec + tous les serveurs WWW d'une grappe de serveurs d'un intranet ? + C'est à dire que toutes les URLs (par définition + locales à un + serveur et dépendant donc de celui-ci) deviennent + véritablement indépendantes du serveur ! Nous voulons + disposer, pour accéder à l'espace de nommage WWW, d'un seul + espace d'adressage compatible : aucune URL ne + doit inclure d'information quelconque à propos du serveur + cible physique. La grappe de serveurs doit elle-même nous + diriger automatiquement vers le bon serveur cible physique, + selon les besoins, et ceci de manière transparente.

+
+ +
Solution :
+ +
+

Tout d'abord, la connaissance des serveurs cibles est issue + de tables de correspondances externes (distribuées) qui + contiennent des informations sur la localisation de nos + utilisateurs, groupes et entités. Elles se présentent sous la + forme :

+ +
+utilisateur1  serveur_utilisateur1
+utilisateur2  serveur_utilisateur2
+:      :
+
+ +

On les enregistre sous forme de fichiers + map.xxx-vers-serveur. On doit ensuite faire + rediriger à tous les serveurs les URLs de la forme :

+ +
+/u/utilisateur/chemin
+/g/groupe/chemin
+/e/entité/chemin
+
+ +

vers

+ +
+http://serveur-physique/u/utilisateur/chemin
+http://serveur-physique/g/groupe/chemin
+http://serveur-physique/e/entité/chemin
+
+ +

si il n'est pas nécessaire que chaque chemin d'URL être valide sur chaque + serveur. Le jeu + de règles suivant le fait pour nous à l'aide des fichiers de + correspondance (en supposant que serveur0 soit un serveur par + défaut qui sera choisi si l'utilisateur ne possède aucune + entrée dans la table) :

+ +
+RewriteEngine on
+
+RewriteMap      utilisateur-vers-serveur   txt:/chemin/vers/map.utilisateur-vers-serveur
+RewriteMap     groupe-vers-serveur   txt:/chemin/vers/map.groupe-vers-serveur
+RewriteMap    entité-vers-serveur   txt:/chemin/vers/map.entité-vers-serveur
+
+RewriteRule   ^/u/([^/]+)/?(.*)
+http://${utilisateur-vers-serveur:$1|serveur0}/u/$1/$2
+RewriteRule   ^/g/([^/]+)/?(.*)
+http://${groupe-vers-serveur:$1|serveur0}/g/$1/$2
+RewriteRule   ^/e/([^/]+)/?(.*)
+http://${entité-vers-serveur:$1|serveur0}/e/$1/$2
+
+RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
+RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
+
+
+
+ +
top
+
+

Répertoires utilisateurs structurés

+ + + +
+
Description :
+ +
+

Certains sites possédant des milliers d'utilisateurs + organisent les répertoires home de manière + structurée, c'est à dire que chaque répertoire home + se situe dans un sous-répertoire dont le nom commence (par + exemple) par le premier caractère du nom de l'utilisateur. + Ainsi, /~foo/chemin est dans + /home/f/foo/.www/chemin, tandis + que /~bar/chemin est dans + /home/b/bar/.www/chemin.

+
+ +
Solution :
+ +
+

Le jeu de règles suivant permet de développer les URLs avec + tilde selon la représentation ci-dessus.

+ +
+RewriteEngine on
+RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
+
+
+
+ +
top
+
+

Réorganisation du système de fichiers

+ + + +
+
Description :
+ +
+

Voici un cas d'espèce : une application très efficace qui + fait un usage intensif de règles RewriteRule + dans le contexte du répertoire pour présenter un aspect + compréhensible sur le Web sans modifier la structure des + données. + Les coulisses de l'affaire : net.sw + rassemble mes archives de paquetages de logiciels Unix + librement accessibles, que j'ai commencé à collectionner en + 1992. Pour moi, c'est un passe-temps, mais aussi un travail, + car alors que j'étudie la science informatique, j'ai aussi + travaillé depuis de nombreuses années comme administrateur + système et réseau à mes heures perdues. Chaque semaine j'ai + besoin de tel ou tel logiciel, et j'ai donc créé une + arborescence très ramifiée de répertoires où je stocke les + paquetages :

+ +
+drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
+drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
+drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
+drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
+drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
+drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
+drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
+drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
+drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
+drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
+drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
+drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
+drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
+drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
+drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
+drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
+
+ +

J'ai décidé en 1996 de rendre cette archive disponible pour + le monde via une interface web agréable. "Agréable" signifie + que je voulais vous offrir une interface où vous pourriez + naviguer directement à travers la hiérarchie des archives. + Mais "agréable" signifie aussi que je ne voulais rien changer + dans cette hiérarchie - même pas en ajoutant queques scripts + CGI à son sommet. Pourquoi ? Parceque j'avais prévu de rendre + ultérieurement la structure ci-dessus accessible aussi via + FTP, et je ne voulais pas voir de fichiers CGI ou Web à ce + niveau.

+
+ +
Solution :
+ +
+

La solution comporte deux parties : la première consiste en + un ensemble de scripts CGI qui créent toutes les pages à tous + les niveaux de répertoires à la volée. Je les ai placés dans + /e/netsw/.www/ comme suit :

+ +
+-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
+drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
+-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
+-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
+-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
+-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
+-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
+-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
+drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
+-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
+-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
+-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
+-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
+
+ +

Le sous-répertoire DATA/ contient la structure + de répertoires proprement dite mentionnée plus haut, c'est + à dire les véritables ressources + net.sw et est mis à jour + automatiquement via rdist à intervalles de temps + réguliers. Reste la seconde partie du problème : comment + relier ces deux structures selon une arborescence d'URL + facile d'accès ? Il nous faut cacher le répertoire + DATA/ à l'utilisateur durant l'exécution des + scripts CGI appropriés aux différentes URLs. Voici comment : + tout d'abord, j'ajoute ces deux règles dans le fichier de + configuration du répertoire racine DocumentRoot du serveur afin de + réécrire le chemin d'URL public /net.sw/ vers le + chemin interne /e/netsw :

+ +
+RewriteRule  ^net.sw$       net.sw/        [R]
+RewriteRule  ^net.sw/(.*)$  e/netsw/$1
+
+ +

La première règle concerne les requêtes qui ne comportent + pas de slash de fin ! C'est la seconde règle qui fait le + véritable travail. Et maintenant vient la super configuration + qui se trouve dans le fichier de configuration de répertoire + /e/netsw/.www/.wwwacl :

+ +
+Options       ExecCGI FollowSymLinks Includes MultiViews
+
+RewriteEngine on
+
+#  l'accès s'effectue via le préfixe /net.sw/
+RewriteBase   /net.sw/
+
+#  tout d'abord, on réécrit le répertoire racine vers
+#  le script CGI qui lui est associé
+RewriteRule   ^$                       netsw-home.cgi     [L]
+RewriteRule   ^index\.html$            netsw-home.cgi     [L]
+
+#  on supprime les sous-répertoires lorsque
+#  le navigateur nous atteint depuis des pages de répertoire
+RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
+
+#  on stoppe maintenant la réécriture pour les fichiers locaux
+RewriteRule   ^netsw-home\.cgi.*       -                  [L]
+RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
+RewriteRule   ^netsw-search\.cgi.*     -                  [L]
+RewriteRule   ^netsw-tree\.cgi$        -                  [L]
+RewriteRule   ^netsw-about\.html$      -                  [L]
+RewriteRule   ^netsw-img/.*$           -                  [L]
+
+#  ce qui reste est un sous-répertoire qui peut être traité
+#  par un autre script CGI
+RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
+RewriteRule   (.*)                     netsw-lsdir.cgi/$1
+
+ +

Quelques indices pour l'interprétation :

+ +
    +
  1. Remarquez le drapeau L (last) et l'absence + de chaîne de substitution ('-') dans la + quatrième partie.
  2. + +
  3. Remarquez le caractère ! (not) et le + drapeau C (chain) dans la première règle de la + dernière partie.
  4. + +
  5. Remarquez le modèle qui correspond à tout dans la + dernière règle.
  6. +
+
+
+ +
top
+
+

Rediriger les URLs erronées vers un autre serveur Web

+ + + +
+
Description :
+ +
+

Une question typique de la FAQ à propos de la réécriture + revient souvent : comment rediriger vers un serveur B les + requêtes qui échouent sur un serveur A ? On s'acquitte en + général de cette tâche via des scripts CGI ErrorDocument en Perl, mais il + existe aussi une solution avec mod_rewrite. + Notez cependant que les performances sont moindres qu'avec + l'utilisation d'un script CGI ErrorDocument !

+
+ +
Solution :
+ +
+

La première solution possède des performances supérieures + mais moins de souplesse, et est moins sure :

+ +
+RewriteEngine on
+RewriteCond  %{DOCUMENT_ROOT/%{REQUEST_URI}  !-f
+RewriteRule   ^(.+)                             http://serveurB.dom/$1
+
+ +

Le problème réside dans le fait que seules les pages + situées dans la racine DocumentRoot seront redirigées. Mais + même si vous pouvez ajouter des conditions supplémentaires (par + exemple pour traiter aussi les répertoires home, etc...), il + existe une meilleure solution :

+ +
+RewriteEngine on
+RewriteCond   %{REQUEST_URI} !-U
+RewriteRule   ^(.+)          http://serveurB.dom/$1
+
+reprendre ici +

On utilise ici la fonctionnalité de prévision des URLs + futures de mod_rewrite. Et cette solution + fonctionne pour tous les types d'URLs et de manière sûre. Par + contre, cette méthode a un impact sur les performances du + serveur web, car chaque requête entraîne le traitement d'une + sous-requête interne supplémentaire. Par conséquent, vous + pouvez l'utiliser si votre serveur web s'exécute sur un CPU + puissant. Dans le cas d'une machine plus lente, utilisez la + première approche, ou mieux, un script CGI ErrorDocument.

+
+
+ +
top
+
+

Multiplexeur d'accès aux archives

+ + + +
+
Description :
+ +
+

Connaissez-vous la grande archive CPAN (Comprehensive Perl Archive + Network) située à http://www.perl.com/CPAN ? + CPAN redirige automatiquement les navigateurs vers un des + nombreux serveurs FTP répartis à travers le monde + (généralement un serveur assez proche du client) ; chaque + serveur héberge l'intégralité d'un miroir CPAN. Il s'agit ni + plus ni moins qu'un service d'accès FTP multiplexé. Alors que + le fonctionnement de l'archive CPAN repose sur des scripts + CGI, comment implémenter une approche similaire avec + mod_rewrite ?

+
+ +
Solution :
+ +
+

Premièrement, remarquons que depuis la version 3.0.0, + mod_rewrite accepte aussi le préfixe + "ftp:" dans les redirections. Et deuxièmement, + l'approximation de la localisation peut être effectuée par une + table de correspondances RewriteMap, en se basant sur + la racine du domaine du client. Un jeu de règles chaînées + astucieux nous permet d'utiliser cette racine du domaine comme + clé de recherche dans notre table de correspondances de + multiplexage.

+ +
+RewriteEngine on
+RewriteMap    multiplex                txt:/chemin/vers/map.cxan
+RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
+RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$
+${multiplex:$1|ftp.défaut.dom}$2  [R,L]
+
+ +
+##
+##  map.cxan -- Multiplexing Map for CxAN%{DOCUMENT_ROOT/%{REQUEST_URI}
+##
+
+de        ftp://ftp.cxan.de/CxAN/
+uk        ftp://ftp.cxan.uk/CxAN/
+com       ftp://ftp.cxan.com/CxAN/
+ :
+##EOF##
+
+
+
+ +
top
+
+

Contenu dépendant du navigateur

+ + + +
+
Description :
+ +
+

Il est parfois nécessaire, au moins pour les pages + principales, de fournir un contenu optimum adapté à chaque + type de navigateur, c'est à dire que l'on doit + fournir une version pour les navigateurs courants, une version + différente pour les navigateurs en mode texte du style de + Lynx, et une autre pour les autres navigateurs.

+
+ +
Solution :
%{DOCUMENT_ROOT/%{REQUEST_URI} + +
+

On ne peut pas utiliser la négociation de contenu car les + navigateurs ne fournissent pas leur type dans cette forme. + Nous devons nous baser sur l'en-tête HTTP "User-Agent". La + configuration ci-dessous effectue les actions suivantes : si + l'en-tête HTTP "User-Agent" commence par "Mozilla/3", la page + foo.html est réécrite en foo.NS.html + et la réécriture s'arrête. Si le navigateur est "Lynx" ou + "Mozilla" version 1 ou 2, la page + foo.html est réécrite en + foo.20.html. Tous les autres navigateurs + reçoivent la page foo.32.html. Voici le jeu de + règles :

+ +
+RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
+RewriteRule ^foo\.html$         foo.NS.html          [L]
+
+RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
+RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
+RewriteRule ^foo\.html$         foo.20.html          [L]
+
+RewriteRule ^foo\.html$         foo.32.html          [L]
+
+
+
+ +
top
+
+

Miroir dynamique

+ + + +
+
Description :
+ +
+

Supposons que nous voulions intégrer dans notre espace de + nommage de belles pages web situées sur un serveur distant. + Dans le cas d'un serveur FTP, nous aurions utilisé le + programme mirror qui maintient vraiment une copie + des données distantes mise à jour explicitement sur le serveur + local. Pour un serveur web, nous pourrions utiliser le + programme webcopy qui utilise le protocole HTTP. + Ces deux techniques présentent cependant un + inconvénient majeur : la copie locale n'est véritablement à + jour qu'au moment où nous avons lancé le programme. Plutôt qu' + un miroir statique devant être défini explicitement, il serait + préférable d'avoir un miroir dynamique dont le contenu serait + mis à jour automatiquement, à la demande, sur le(s) serveur(s) + distant(s).

+
+ +
Solution :
+ +
+

Pour y parvenir, on fait + correspondre la page web ou même l'ensemble du + répertoire web distants à notre espace de nommage en utilisant + la fonctionnalité Mandataire (drapeau + [P] ou [proxy]) :

+ +
+RewriteEngine  on
+RewriteBase    /~quux/
+RewriteRule    ^page-convoitée/(.*)$  http://www.tstimpreso.com/page-convoitée/$1  [P]
+
+ +
+RewriteEngine  on
+RewriteBase    /~quux/
+RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
+
+
+
+ +
top
+
+

Miroir dynamique inverse

+ + + +
+
Description :
+ +
...
+ +
Solution :
+ +
+
+RewriteEngine on
+RewriteCond   /miroir/du/site-distant/$1           -U
+RewriteRule   ^http://www\.site-distant\.com/(.*)$ /miroir/du/site-distant/$1
+
+
+
+ +
top
+
+

Récupérer des données manquantes depuis l'Intranet

+ + + +
+
Description :
+ +
+

C'est une méthode astucieuse permettant de faire + fonctionner virtuellement un serveur web d'entreprise + (www.quux-corp.dom) sur + l'Internet (extérieur à l'entreprise), tout en maintenant et + conservant dans la réalité ses données sur un serveur web + (www2.quux-corp.dom) de l'Intranet (interne à + l'entreprise) protégé par un pare-feu. L'astuce consiste, sur + le serveur web externe, à récupérer à la volée sur le serveur interne + les données demandées.

+
+ +
Solution :
+ +
+

Tout d'abord, nous devons nous assurer que notre pare-feu + protège bien le serveur web interne, et que seul le serveur + web externe est autorisé à y récupérer des données. Dans le + cas d'un filtrage par paquets, nous pourrions par exemple + définir un jeu de règles du pare-feu du style :

+ +
+ALLOW serveur www.quux-corp.dom Port >1024 -->
+serveur www2.quux-corp.dom Port 80
+DENY  serveur *                 Port *     -->
+serveur www2.quux-corp.dom Port 80
+
+ +

Il vous suffit d'adapter ces règles à la syntaxe de votre + pare-feu. Nous pouvons maintenant définir les règles de + mod_rewrite qui serviront à récupérer les + données manquantes en arrière-plan via la fonctionnalité de + mandataire :

+ +
+RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2 [C]
+# L'utilisation de REQUEST_FILENAME ci dessous est correcte dans cet
+# exemple de contexte au niveau serveur car la règle qui fait référence
+# à REQUEST_FILENAME est chaînée à une règle qui définit
+# REQUEST_FILENAME.
+RewriteCond %{REQUEST_FILENAME}       !-f
+RewriteCond %{REQUEST_FILENAME}       !-d
+RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
+
+
+
+ +
top
+
+

Répartition de charge

+ + + +
+
Description :
+ +
+

Supposons que nous voulions répartir la charge du trafic + vers www.example.com entre les serveurs + www[0-5].example.com (un total de 6 serveurs). + Comment y parvenir ?

+
+ +
Solution :
+ +
+

Il existe de nombreuses solutions à ce problème. Nous + décrirons tout d'abord une variante assez connue basée sur + DNS, puis une autre basée sur mod_rewrite + :

+ +
    +
  1. + Round-Robin (tourniquet) DNS + +

    La méthode de répartition de charge la plus simple + consiste à utiliser le "DNS round-robin" + (rotation d'adresses) de + BIND. Vous devez seulement enregistrer les + serveurs www[0-9].example.com de manière + habituelle dans votre DNS à l'aide d'enregistrements de + type A (adresse), comme suit :

    + +
    +www0   IN  A       1.2.3.1
    +www1   IN  A       1.2.3.2
    +www2   IN  A       1.2.3.3
    +www3   IN  A       1.2.3.4
    +www4   IN  A       1.2.3.5
    +www5   IN  A       1.2.3.6
    +
    + +

    Puis vous ajoutez les entrées suivantes :

    + +
    +www   IN  A       1.2.3.1
    +www   IN  A       1.2.3.2
    +www   IN  A       1.2.3.3
    +www   IN  A       1.2.3.4
    +www   IN  A       1.2.3.5
    +
    + +

    Maintenant, lors de la résolution de + www.example.com, BIND renvoie + www0-www5 - mais selon une permutation + différente à chaque fois. De cette façon, les clients sont + répartis entre les différents serveurs. Notez cependant + que cette méthode de répartition de charge n'est pas + parfaite, car les résolutions DNS sont mises en cache par + les clients et les autres serveurs DNS du réseau, si + bien que lorsqu'un client s'est vu résoudre + www.example.com en un des + wwwN.example.com, toutes ses requêtes ultérieures + continueront d'aller vers la même adresse IP (et donc le + même serveur), au lieu d'être réparties entre les autres + serveurs. Le résultat est cependant globalement + satisfaisant car les requêtes sont réparties + collectivement entre chacun des serveurs web.

    +
  2. + +
  3. + Répartition de charge basée sur DNS + +

    Une méthode de répartition de charge sophistiquée basée + sur DNS consiste à utiliser le programme + lbnamed que l'on peut trouver à + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + Associé à des outils auxiliaires, il s'agit d'un programme + en Perl 5 qui permet d'effectuer une véritable répartition + de charge basée sur DNS.

    +
  4. + +
  5. + Round-Robin basé sur la fonctionnalité de + mandataire + +

    Dans cette variante, nous utilisons + mod_rewrite et sa fonctionnalité de + mandataire. Tout d'abord, nous définissons + www0.example.com comme un autre nom de + www.example.com en ajoutant l'entrée

    + +
    +www    IN  CNAME   www0.example.com.
    +
    + +

    dans le DNS. Puis nous définissons + www0.example.com comme serveur mandataire + seulement, c'est à dire que nous configurons cette machine + de telle sorte que toutes les URLs qui lui arrivent soient + simplement transmises, via le mandataire interne, vers un + des 5 autres serveurs (www1-www5). Pour y + parvenir, nous définissons tout d'abord un jeu de règles + qui contacte un script de répartition de charge + lb.pl pour toutes les URLs.

    + +
    +RewriteEngine on
    +RewriteMap    lb      prg:/chemin/vers/lb.pl
    +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
    +
    + +

    Puis nous écrivons lb.pl :

    + +
    +#!/chemin/vers/perl
    +##
    +##  lb.pl -- script de répartition de charge
    +##
    +
    +$| = 1;
    +
    +$name   = "www";     # la base du nom du serveur
    +$first  = 1;         # le premier serveur (pas 0 ici, car 0 correspond à
    +		     # moi-même)
    +$last   = 5;         # le dernier serveur du tourniquet
    +$domain = "foo.dom"; # le nom de domaine
    +
    +$cnt = 0;
    +while (<STDIN>) {
    +    $cnt = (($cnt+1) % ($last+1-$first));
    +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
    +    print "http://$server/$_";
    +}
    +
    +##EOF##
    +
    + +
    Une dernière remarque : à quoi cela sert-il ? + www0.example.com, quant à lui, n'est-il pas + toujours surchargé ? La réponse est oui, il est surchargé, + mais seulement avec des requêtes de mandataire ! Tous les + traitements SSI, CGI, ePerl, etc... sont entièrement + effectués sur les autres machines. Ceci peut fonctionner + correctement pour un site complexe. Le plus grand risque + réside ici dans le fait que www0 est un passage obligé et + que s'il est hors service, les autres serveurs deviennent + inaccessibles.
    +
  6. + +
  7. + Répartiteur de charge dédié + +

    Il existe aussi des solutions plus sophistiquées. + Cisco, F5, et de nombreuses autres sociétés proposent + des répartiteurs de charge matériels (utilisés en général + en mode doublé à des fins de redondance), qui offrent une + répartition de charge sophistiquée et des fonctionnalités + de passage automatique en mode de fonctionnement par défaut + en cas de problème. Cependant, des solutions logicielles + offrent aussi des fonctionnalités similaires avec du + matériel standard. Si vos besoins correspondent et si vous + êtes assez riche, vous pouvez envisager ces solutions. La + liste de diffusion lb-l + est un bon point de départ pour vos recherches.

    +
  8. +
+
+
+ +
top
+
+

Nouveau type MIME, nouveau service

+ + + +
+
Description :
+ +
+

On trouve de nombreux programmes CGI attractifs sur le + réseau. Mais leur emploi est souvent rébarbatif, si bien que + de nombreux webmasters ne les utilisent pas. Même la + fonctionnalité de gestionnaire Action d'Apache pour les types + MIME ne convient que lorsque les programmes CGI ne nécessitent + pas d'URLs spéciales (réellement PATH_INFO et + QUERY_STRINGS) en entrée. Tout d'abord, + définissons un nouveau type de fichier ayant pour extension + .scgi (pour CGI sécurisé) qui sera associé pour + traitement au programme populaire cgiwrap. Le + problème est le suivant : par exemple, si on utilise un style + d'URL bien défini (voir ci-dessus), un fichier situé dans le + répertoire home de l'utilisateur pourra correspondre à l'URL + /u/user/foo/bar.scgi. Mais cgiwrap + nécessite des URLs de la forme + /~user/foo/bar.scgi/. La règle suivante apporte + la solution :

+ +
+RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
+... /interne/cgi/utilisateur/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
+
+ +

Ou considérons ces autres programmes attractifs : + wwwlog (qui affiche le journal des accès + access.log pour un sous répertoire correspondant + à une URL) et wwwidx (qui exécute Glimpse sur un + sous répertoire correspondant à une URL). Nous devons fournir + l'URL correspondante à ces programmes afin qu'ils sachent sur + quel répertoire ils doivent agir. Mais c'est en général + compliqué, car ils peuvent être appelés à nouveau + par la forme d'URL alternative, c'est à dire que typiquement, + nous exécuterions le programme swwidx depuis + /u/user/foo/ via un hyperlien vers

+ +
+/internal/cgi/user/swwidx?i=/u/user/foo/
+
+ +

ce qui n'est pas satisfaisant, car nous devons expliciter + à la fois la localisation du répertoire + et la localisation du programme CGI dans + l'hyperlien. Si nous devons nous réorganiser, il nous faudra + beaucoup de temps pour modifier tous les hyperliens.

+
+ +
Solution :
+ +
+

La solution consiste ici à fournir un nouveau format d'URL + qui redirige automatiquement vers la requête CGI appropriée. + Pour cela, on définit les règles suivantes :

+ +
+RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /interne/cgi/utilisateur/wwwidx?i=/$1/$2$3/
+RewriteRule   ^/([uge])/([^/]+)(/?.*):log /interne/cgi/utilisateur/wwwlog?f=/$1/$2$3
+
+ +

Et maintenant l'hyperlien qui renvoie vers + /u/user/foo/ se réduit à

+ +
+HREF="*"
+
+ +

qui est automatiquement transformé en interne en

+ +
+/internal/cgi/user/wwwidx?i=/u/user/foo/
+
+ +

Une approche similaire permet d'invoquer le programme CGI + du journal des accès lorsque l'hyperlien :log est + utilisé.

+
+
+ +
top
+
+

Régéneration de contenu à la volée

+ + + +
+
Description :
+ +
+

Voici une fonctionnalité vraiment ésotérique : des pages + générées dynamiquement mais servies statiquement, c'est à + dire que les pages doivent être servies comme des pages + purement statiques (lues depuis le système de fichiers et + servies en l'état), mais doivent être générées dynamiquement + par le serveur web si elles sont absentes. Ainsi, vous pouvez + avoir des pages générées par CGI qui sont servies statiquement + à moins qu'un administrateur (ou une tâche de + cron) ne supprime les + contenus statiques. Les contenus sont ensuite actualisés.

+
+ +
Solution :
+ +
+ A cet effet, on utilise le jeu de règles suivant : + +
+# Cet exemple n'est valable que dans un contexte de répertoire
+RewriteCond %{REQUEST_FILENAME}   !-s
+RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
+
+ +

Ainsi, une requête pour page.html entraîne + l'exécution interne de la page page.cgi + correspondante si page.html n'existe pas + ou possède une taille de fichier nulle. L'astuce réside ici + dans le fait que page.cgi est un script CGI + qui (en plus de STDOUT) écrit sa sortie dans le + fichier page.html. Une fois le script exécuté, le + serveur sert la page page.html fraîchement + générée. Si le webmaster + veut actualiser les contenus, il lui suffit de supprimer le + fichier page.html (le plus souvent via une tâche + de cron).

+
+
+ +
top
+
+

Actualisation automatique d'un document

+ + + +
+
Description :
+ +
+

Lorsque nous créons une page web complexe, ne serait-il pas + souhaitable que le navigateur web actualise automatiquement la + page chaque fois que nous en sauvegardons une nouvelle version + à partir de notre éditeur ? Impossible ?

+
+ +
Solution :
+ +
+

Non ! Nous allons pour cela combiner la fonctionnalité MIME + multipart, la fonctionnalité NPH du serveur web et la + puissance de mod_rewrite pour la manipulation + d'URLs. Tout d'abord, nous définissons une nouvelle + fonctionnalité pour les URLs : l'ajout de + :refresh à toute URL fait que la 'page' est + actualisée chaque fois que la ressource est mise à jour dans + le système de fichiers.

+ +
+RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /interne/cgi/apache/nph-refresh?f=$1
+
+ +

Nous appelons maintenant cette URL

+ +
+/u/foo/bar/page.html:refresh
+
+ +

ce qui entraîne en interne l'invocation de l'URL

+ +
+/interne/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
+
+ +

Il ne reste plus qu'à écrire le script CGI. Bien que l'on + écrive habituellement dans ces cas "laissé à la charge du + lecteur à titre d'exercice", ;-) je vous l'offre, aussi.

+ +
+#!/sw/bin/perl
+##
+##  nph-refresh -- script NPH/CGI pour l'actualisation automatique de
+##  pages
+##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
+##
+$| = 1;
+
+#   éclate la variable QUERY_STRING
+@pairs = split(/&/, $ENV{'QUERY_STRING'});
+foreach $pair (@pairs) {
+    ($name, $value) = split(/=/, $pair);
+    $name =~ tr/A-Z/a-z/;
+    $name = 'QS_' . $name;
+    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+    eval "\$$name = \"$value\"";
+}
+$QS_s = 1 if ($QS_s eq '');
+$QS_n = 3600 if ($QS_n eq '');
+if ($QS_f eq '') {
+    print "HTTP/1.0 200 OK\n";
+    print "Content-type: text/html\n\n";
+    print "&lt;b&gt;ERREUR&lt;/b&gt;: Aucun fichier fourni\n";
+    exit(0);
+}
+if (! -f $QS_f) {
+    print "HTTP/1.0 200 OK\n";
+    print "Content-type: text/html\n\n";
+    print "&lt;b&gt;ERREUR&lt;/b&gt;: Fichier $QS_f non trouvé\n";
+    exit(0);
+}
+
+sub print_http_headers_multipart_begin {
+    print "HTTP/1.0 200 OK\n";
+    $bound = "ThisRandomString12345";
+    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
+    &print_http_headers_multipart_next;
+}
+
+sub print_http_headers_multipart_next {
+    print "\n--$bound\n";
+}
+
+sub print_http_headers_multipart_end {
+    print "\n--$bound--\n";
+}
+
+sub displayhtml {
+    local($buffer) = @_;
+    $len = length($buffer);
+    print "Content-type: text/html\n";
+    print "Content-length: $len\n\n";
+    print $buffer;
+}
+
+sub readfile {
+    local($file) = @_;
+    local(*FP, $size, $buffer, $bytes);
+    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
+    $size = sprintf("%d", $size);
+    open(FP, "&lt;$file");
+    $bytes = sysread(FP, $buffer, $size);
+    close(FP);
+    return $buffer;
+}
+
+$buffer = &readfile($QS_f);
+&print_http_headers_multipart_begin;
+&displayhtml($buffer);
+
+sub mystat {
+    local($file) = $_[0];
+    local($time);
+
+    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
+    return $mtime;
+}
+
+$mtimeL = &mystat($QS_f);
+$mtime = $mtime;
+for ($n = 0; $n &lt; $QS_n; $n++) {
+    while (1) {
+        $mtime = &mystat($QS_f);
+        if ($mtime ne $mtimeL) {
+            $mtimeL = $mtime;
+            sleep(2);
+            $buffer = &readfile($QS_f);
+            &print_http_headers_multipart_next;
+            &displayhtml($buffer);
+            sleep(5);
+            $mtimeL = &mystat($QS_f);
+            last;
+        }
+        sleep($QS_s);
+    }
+}
+
+&print_http_headers_multipart_end;
+
+exit(0);
+
+##EOF##
+
+
+
+ +
top
+
+

Hébergement virtuel de masse

+ + + +
+
Description :
+ +
+

La fonctionnalité <VirtualHost> d'Apache est intéressante et + fonctionne de manière satisfaisante jusqu'à quelques + douzaines de serveurs virtuels. Par contre, si vous êtes un + FAI et devez héberger des centaines de serveurs virtuels, + cette méthode n'est pas optimale.

+
+ +
Solution :
+ +
+

Pour fournir cette fonctionnalité avec + mod_rewrite, on fait correspondre à notre espace de + nommage la page web ou même le répertoire complet distants en + utilisant la fonctionnalité Mandataire + (drapeau [P]) :

+ +
+##
+##  vhost.map
+##
+www.vhost1.dom:80  /chemin/vers/racine-doc/vhost1
+www.vhost2.dom:80  /chemin/vers/racine-doc/vhost2
+     :
+www.vhostN.dom:80  /chemin/vers/racine-doc/vhostN
+
+ +
+##
+##  httpd.conf
+##
+    :
+#   utilisation du nom d'hôte canonique pour les redirections, etc...
+UseCanonicalName on
+
+    :
+#   ajout du serveur virtuel en tête du format CLF
+CustomLog  /chemin/vers/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
+    :
+
+#   activation du moteur de réécriture pour le serveur principal
+RewriteEngine on
+
+#   définition de deux tables de correspondances : une première pour
+#   corriger les URLs et une seconde qui associe les serveurs virtuels
+#   disponibles avec leurs racines des documents correspondantes.
+RewriteMap    lowercase    int:tolower
+RewriteMap    vhost        txt:/chemin/vers/vhost.map
+
+#   et enfin sélection proprement dite du serveur virtuel approprié via
+#   une seule règle longue et complexe :
+#
+#   1. on s'assure de ne pas sélectionner un hôte virtuel pour les
+#   adresses communes
+
+RewriteCond   %{REQUEST_URI}  !^/adresse-commune1/.*
+RewriteCond   %{REQUEST_URI}  !^/adresse-commune2/.*
+    :
+RewriteCond   %{REQUEST_URI}  !^/adresse-communeN/.*
+#
+#   2. on vérifie que l'on dispose bien d'un en-tête Host, car
+#   actuellement, cette méthode ne peut faire de l'hébergement virtuel
+#   qu'avec cet en-tête
+RewriteCond   %{HTTP_HOST}  !^$
+#
+#   3. mise en minuscules du nom d'hôte
+RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
+#
+#   4. recherche ce ce nom d'hôte dans vhost.map et
+#      enregistrement de celui-ci seulement s'il s'agit d'un chemin
+#      (et non "NONE" en provenance de la condition précédente)
+RewriteCond   ${vhost:%1}  ^(/.*)$
+#
+#   5. nous pouvons enfin faire correspondre l'URL avec la racine des
+#   documents correspondant au serveur virtuel approprié et enregistrer
+#   ce dernier à des fins de journalisation
+RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
+    :
+
+
+
+ +
top
+
+

Interdiction d'hôtes

+ + + +
+
Description :
+ +
+

Comment interdire l'accès à notre serveur à une liste + d'hôtes ?

+
+ +
Solution :
+ +
+

Pour Apache >= 1.3b6 :

+ +
+RewriteEngine on
+RewriteMap    hôtes-interdits  txt:/chemin/vers/hôtes-interdits
+RewriteCond   ${hôtes-interdits:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
+RewriteCond   ${hôtes-interdits:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
+RewriteRule   ^/.*  -  [F]
+
+ +

Pour Apache <= 1.3b6 :

+ +
+RewriteEngine on
+RewriteMap    hôtes-interdits  txt:/chemin/vers/hôtes-interdits
+RewriteRule   ^/(.*)$ ${hôtes-interdits:%{REMOTE_HOST}|NOT-FOUND}/$1
+RewriteRule   !^NOT-FOUND/.* - [F]
+RewriteRule   ^NOT-FOUND/(.*)$ ${hôtes-interdits:%{REMOTE_ADDR}|NOT-FOUND}/$1
+RewriteRule   !^NOT-FOUND/.* - [F]
+RewriteRule   ^NOT-FOUND/(.*)$ /$1
+
+ +
+##
+##  hosts.deny
+##
+##  ATTENTION! Ceci est une table de correspondances, pas une liste,
+##  même si on l'utilise en tant que telle. mod_rewrite l'interprète
+##  comme un ensemble de paires clé/valeur ; chaque entrée doit donc
+##  au moins posséder une valeur fictive "-".
+##
+
+193.102.180.41 -
+bsdti1.sdm.de  -
+192.76.162.40  -
+
+
+
+ +
top
+
+

Interdiction du mandataire

+ + + +
+
Description :
+ +
+

Comment interdire l'utilisation du mandataire d'Apache pour + un certain hôte, ou même seulement pour un utilisateur + de cet hôte ?

+
+ +
Solution :
+ +
+

Nous devons tout d'abord nous assurer que + mod_rewrite arrive après(!) + mod_proxy dans le fichier de configuration + lors de la compilation du serveur web Apache. De cette façon, + il est appelé avant mod_proxy. Nous + pouvons ensuite définir cette règle pour une interdiction + dépendant de l'hôte :

+ +
+RewriteCond %{REMOTE_HOST} ^hôte-à-rejeter\.mon-domaine\.com$
+RewriteRule !^http://[^/.]\.mon-domaine.com.*  - [F]
+
+ +

...et celle-ci pour une interdiction dépendant de + utilisateur@hôte :

+ +
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^utilisateur-à-
+rejeter@hôte-à-rejeter\.mon-domaine\.com$
+RewriteRule !^http://[^/.]\.mon-domaine.com.*  - [F]
+
+
+
+ +
top
+
+

Variante particulière d'authentification

+ + + +
+
Description :
+ +
+

On a parfois besoin d'une authentification très + particulière, par exemple une authentification qui vérifie la + présence d'un utilisateur dans une liste explicitement + définie. Seuls ceux qui sont présents dans la liste se voient + accorder un accès, et ceci sans avoir à + s'identifier/authentifier (comme c'est le cas avec une + authentification de base via mod_auth).

+
+ +
Solution :
+ +
+

On définit une liste de conditions de réécriture pour + interdire l'accès à tout le monde, sauf aux utilisateurs + autorisés :

+ +
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami1@client1.quux-corp\.com$
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami2@client2.quux-corp\.com$
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami3@client3.quux-corp\.com$
+RewriteRule ^/~quux/seulement-pour-les-amis/      -                                 [F]
+
+
+
+ +
top
+
+

Redirection basée sur le référent

+ + + +
+
Description :
+ +
+

Comment écrire un programme souple qui redirige certaines + URLs en se basant sur l'en-tête HTTP "Referer", et peut être + configuré avec autant de pages de référence + que l'on veut ?

+
+ +
Solution :
+ +
+

On utilise le jeu de règles vraiment astucieux suivant :

+ +
+RewriteMap  deflector txt:/chemin/vers/deflector.map
+
+RewriteCond %{HTTP_REFERER} !=""
+RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
+RewriteRule ^.* %{HTTP_REFERER} [R,L]
+
+RewriteCond %{HTTP_REFERER} !=""
+RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
+RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
+
+ +

... en association avec la table de réécriture + correspondante :

+ +
+##
+##  deflector.map
+##
+
+http://www.mauvais-sujets.com/mauvais/index.html    -
+http://www.mauvais-sujets.com/mauvais/index2.html   -
+http://www.mauvais-sujets.com/mauvais/index3.html   http://quelque-part.com/
+
+ +

Les requêtes sont redirigées vers la page de référence + (lorsque la valeur correspondant à la clé extraite de la table + de correspondances est égale à "-"), ou vers une + URL spécifique (lorsqu'une URL est définie dans la table de + correspondances comme second argument).

+
+
+ +
+
+

Langues Disponibles:  en  | + fr 

+
+ \ No newline at end of file diff --git a/docs/manual/rewrite/rewrite_guide_advanced.xml.fr b/docs/manual/rewrite/rewrite_guide_advanced.xml.fr new file mode 100644 index 0000000000..42e8102cf8 --- /dev/null +++ b/docs/manual/rewrite/rewrite_guide_advanced.xml.fr @@ -0,0 +1,1374 @@ + + + + + + + + + + + Rewrite + + Guide de réécriture des URLs - Sujets avancés + + + +

Ce document complémente la + documentation de référence du + module mod_rewrite. Il décrit les différentes + manières d'utiliser le module d'Apache mod_rewrite + pour résoudre les problèmes d'URLs typiques auxquels sont souvent + confrontés les webmasters. Nous fournissons une description + détaillée de la résolution de chaque problème par la configuration + d'un jeu de règles de réécriture.

+ + ATTENTION: il pourra s'avérer nécessaire de + modifier les exemples en fonction de la + configuration de votre serveur, par exemple en ajoutant le drapeau + [PT] si les modules mod_alias et + mod_userdir sont utilisés, etc... Les jeux de + règles devront également être adaptés pour passer d'un contexte de + serveur à un contexte de répertoire (fichiers + .htaccess). Essayez de toujours bien comprendre ce que + fait un jeu de règles avant de l'utiliser, ce qui pourra vous éviter + bien des problèmes. + +
+Documentation du +module +Introduction à +mod_rewrite +Guide de réécriture - exemples +utiles +Détails techniques + + +
+ + Accès à une grappe de serveurs via un espace d'adressage + compatible + +
+
Description :
+ +
+

Comment créer un espace d'adressage homogène et compatible + avec + tous les serveurs WWW d'une grappe de serveurs d'un intranet ? + C'est à dire que toutes les URLs (par définition + locales à un + serveur et dépendant donc de celui-ci) deviennent + véritablement indépendantes du serveur ! Nous voulons + disposer, pour accéder à l'espace de nommage WWW, d'un seul + espace d'adressage compatible : aucune URL ne + doit inclure d'information quelconque à propos du serveur + cible physique. La grappe de serveurs doit elle-même nous + diriger automatiquement vers le bon serveur cible physique, + selon les besoins, et ceci de manière transparente.

+
+ +
Solution :
+ +
+

Tout d'abord, la connaissance des serveurs cibles est issue + de tables de correspondances externes (distribuées) qui + contiennent des informations sur la localisation de nos + utilisateurs, groupes et entités. Elles se présentent sous la + forme :

+ +
+utilisateur1  serveur_utilisateur1
+utilisateur2  serveur_utilisateur2
+:      :
+
+ +

On les enregistre sous forme de fichiers + map.xxx-vers-serveur. On doit ensuite faire + rediriger à tous les serveurs les URLs de la forme :

+ +
+/u/utilisateur/chemin
+/g/groupe/chemin
+/e/entité/chemin
+
+ +

vers

+ +
+http://serveur-physique/u/utilisateur/chemin
+http://serveur-physique/g/groupe/chemin
+http://serveur-physique/e/entité/chemin
+
+ +

si il n'est pas nécessaire que chaque chemin d'URL être valide sur chaque + serveur. Le jeu + de règles suivant le fait pour nous à l'aide des fichiers de + correspondance (en supposant que serveur0 soit un serveur par + défaut qui sera choisi si l'utilisateur ne possède aucune + entrée dans la table) :

+ +
+RewriteEngine on
+
+RewriteMap      utilisateur-vers-serveur   txt:/chemin/vers/map.utilisateur-vers-serveur
+RewriteMap     groupe-vers-serveur   txt:/chemin/vers/map.groupe-vers-serveur
+RewriteMap    entité-vers-serveur   txt:/chemin/vers/map.entité-vers-serveur
+
+RewriteRule   ^/u/([^/]+)/?(.*)
+http://${utilisateur-vers-serveur:$1|serveur0}/u/$1/$2
+RewriteRule   ^/g/([^/]+)/?(.*)
+http://${groupe-vers-serveur:$1|serveur0}/g/$1/$2
+RewriteRule   ^/e/([^/]+)/?(.*)
+http://${entité-vers-serveur:$1|serveur0}/e/$1/$2
+
+RewriteRule   ^/([uge])/([^/]+)/?$          /$1/$2/.www/
+RewriteRule   ^/([uge])/([^/]+)/([^.]+.+)   /$1/$2/.www/$3\
+
+
+
+ +
+ +
+ + Répertoires utilisateurs structurés + +
+
Description :
+ +
+

Certains sites possédant des milliers d'utilisateurs + organisent les répertoires home de manière + structurée, c'est à dire que chaque répertoire home + se situe dans un sous-répertoire dont le nom commence (par + exemple) par le premier caractère du nom de l'utilisateur. + Ainsi, /~foo/chemin est dans + /home/f/foo/.www/chemin, tandis + que /~bar/chemin est dans + /home/b/bar/.www/chemin.

+
+ +
Solution :
+ +
+

Le jeu de règles suivant permet de développer les URLs avec + tilde selon la représentation ci-dessus.

+ +
+RewriteEngine on
+RewriteRule   ^/~(([a-z])[a-z0-9]+)(.*)  /home/$2/$1/.www$3
+
+
+
+ +
+ +
+ + Réorganisation du système de fichiers + +
+
Description :
+ +
+

Voici un cas d'espèce : une application très efficace qui + fait un usage intensif de règles RewriteRule + dans le contexte du répertoire pour présenter un aspect + compréhensible sur le Web sans modifier la structure des + données. + Les coulisses de l'affaire : net.sw + rassemble mes archives de paquetages de logiciels Unix + librement accessibles, que j'ai commencé à collectionner en + 1992. Pour moi, c'est un passe-temps, mais aussi un travail, + car alors que j'étudie la science informatique, j'ai aussi + travaillé depuis de nombreuses années comme administrateur + système et réseau à mes heures perdues. Chaque semaine j'ai + besoin de tel ou tel logiciel, et j'ai donc créé une + arborescence très ramifiée de répertoires où je stocke les + paquetages :

+ +
+drwxrwxr-x   2 netsw  users    512 Aug  3 18:39 Audio/
+drwxrwxr-x   2 netsw  users    512 Jul  9 14:37 Benchmark/
+drwxrwxr-x  12 netsw  users    512 Jul  9 00:34 Crypto/
+drwxrwxr-x   5 netsw  users    512 Jul  9 00:41 Database/
+drwxrwxr-x   4 netsw  users    512 Jul 30 19:25 Dicts/
+drwxrwxr-x  10 netsw  users    512 Jul  9 01:54 Graphic/
+drwxrwxr-x   5 netsw  users    512 Jul  9 01:58 Hackers/
+drwxrwxr-x   8 netsw  users    512 Jul  9 03:19 InfoSys/
+drwxrwxr-x   3 netsw  users    512 Jul  9 03:21 Math/
+drwxrwxr-x   3 netsw  users    512 Jul  9 03:24 Misc/
+drwxrwxr-x   9 netsw  users    512 Aug  1 16:33 Network/
+drwxrwxr-x   2 netsw  users    512 Jul  9 05:53 Office/
+drwxrwxr-x   7 netsw  users    512 Jul  9 09:24 SoftEng/
+drwxrwxr-x   7 netsw  users    512 Jul  9 12:17 System/
+drwxrwxr-x  12 netsw  users    512 Aug  3 20:15 Typesetting/
+drwxrwxr-x  10 netsw  users    512 Jul  9 14:08 X11/
+
+ +

J'ai décidé en 1996 de rendre cette archive disponible pour + le monde via une interface web agréable. "Agréable" signifie + que je voulais vous offrir une interface où vous pourriez + naviguer directement à travers la hiérarchie des archives. + Mais "agréable" signifie aussi que je ne voulais rien changer + dans cette hiérarchie - même pas en ajoutant queques scripts + CGI à son sommet. Pourquoi ? Parceque j'avais prévu de rendre + ultérieurement la structure ci-dessus accessible aussi via + FTP, et je ne voulais pas voir de fichiers CGI ou Web à ce + niveau.

+
+ +
Solution :
+ +
+

La solution comporte deux parties : la première consiste en + un ensemble de scripts CGI qui créent toutes les pages à tous + les niveaux de répertoires à la volée. Je les ai placés dans + /e/netsw/.www/ comme suit :

+ +
+-rw-r--r--   1 netsw  users    1318 Aug  1 18:10 .wwwacl
+drwxr-xr-x  18 netsw  users     512 Aug  5 15:51 DATA/
+-rw-rw-rw-   1 netsw  users  372982 Aug  5 16:35 LOGFILE
+-rw-r--r--   1 netsw  users     659 Aug  4 09:27 TODO
+-rw-r--r--   1 netsw  users    5697 Aug  1 18:01 netsw-about.html
+-rwxr-xr-x   1 netsw  users     579 Aug  2 10:33 netsw-access.pl
+-rwxr-xr-x   1 netsw  users    1532 Aug  1 17:35 netsw-changes.cgi
+-rwxr-xr-x   1 netsw  users    2866 Aug  5 14:49 netsw-home.cgi
+drwxr-xr-x   2 netsw  users     512 Jul  8 23:47 netsw-img/
+-rwxr-xr-x   1 netsw  users   24050 Aug  5 15:49 netsw-lsdir.cgi
+-rwxr-xr-x   1 netsw  users    1589 Aug  3 18:43 netsw-search.cgi
+-rwxr-xr-x   1 netsw  users    1885 Aug  1 17:41 netsw-tree.cgi
+-rw-r--r--   1 netsw  users     234 Jul 30 16:35 netsw-unlimit.lst
+
+ +

Le sous-répertoire DATA/ contient la structure + de répertoires proprement dite mentionnée plus haut, c'est + à dire les véritables ressources + net.sw et est mis à jour + automatiquement via rdist à intervalles de temps + réguliers. Reste la seconde partie du problème : comment + relier ces deux structures selon une arborescence d'URL + facile d'accès ? Il nous faut cacher le répertoire + DATA/ à l'utilisateur durant l'exécution des + scripts CGI appropriés aux différentes URLs. Voici comment : + tout d'abord, j'ajoute ces deux règles dans le fichier de + configuration du répertoire racine DocumentRoot du serveur afin de + réécrire le chemin d'URL public /net.sw/ vers le + chemin interne /e/netsw :

+ +
+RewriteRule  ^net.sw$       net.sw/        [R]
+RewriteRule  ^net.sw/(.*)$  e/netsw/$1
+
+ +

La première règle concerne les requêtes qui ne comportent + pas de slash de fin ! C'est la seconde règle qui fait le + véritable travail. Et maintenant vient la super configuration + qui se trouve dans le fichier de configuration de répertoire + /e/netsw/.www/.wwwacl :

+ +
+Options       ExecCGI FollowSymLinks Includes MultiViews
+
+RewriteEngine on
+
+#  l'accès s'effectue via le préfixe /net.sw/
+RewriteBase   /net.sw/
+
+#  tout d'abord, on réécrit le répertoire racine vers
+#  le script CGI qui lui est associé
+RewriteRule   ^$                       netsw-home.cgi     [L]
+RewriteRule   ^index\.html$            netsw-home.cgi     [L]
+
+#  on supprime les sous-répertoires lorsque
+#  le navigateur nous atteint depuis des pages de répertoire
+RewriteRule   ^.+/(netsw-[^/]+/.+)$    $1                 [L]
+
+#  on stoppe maintenant la réécriture pour les fichiers locaux
+RewriteRule   ^netsw-home\.cgi.*       -                  [L]
+RewriteRule   ^netsw-changes\.cgi.*    -                  [L]
+RewriteRule   ^netsw-search\.cgi.*     -                  [L]
+RewriteRule   ^netsw-tree\.cgi$        -                  [L]
+RewriteRule   ^netsw-about\.html$      -                  [L]
+RewriteRule   ^netsw-img/.*$           -                  [L]
+
+#  ce qui reste est un sous-répertoire qui peut être traité
+#  par un autre script CGI
+RewriteRule   !^netsw-lsdir\.cgi.*     -                  [C]
+RewriteRule   (.*)                     netsw-lsdir.cgi/$1
+
+ +

Quelques indices pour l'interprétation :

+ +
    +
  1. Remarquez le drapeau L (last) et l'absence + de chaîne de substitution ('-') dans la + quatrième partie.
  2. + +
  3. Remarquez le caractère ! (not) et le + drapeau C (chain) dans la première règle de la + dernière partie.
  4. + +
  5. Remarquez le modèle qui correspond à tout dans la + dernière règle.
  6. +
+
+
+ +
+ +
+ + Rediriger les URLs erronées vers un autre serveur Web + +
+
Description :
+ +
+

Une question typique de la FAQ à propos de la réécriture + revient souvent : comment rediriger vers un serveur B les + requêtes qui échouent sur un serveur A ? On s'acquitte en + général de cette tâche via des scripts CGI ErrorDocument en Perl, mais il + existe aussi une solution avec mod_rewrite. + Notez cependant que les performances sont moindres qu'avec + l'utilisation d'un script CGI ErrorDocument !

+
+ +
Solution :
+ +
+

La première solution possède des performances supérieures + mais moins de souplesse, et est moins sure :

+ +
+RewriteEngine on
+RewriteCond  %{DOCUMENT_ROOT/%{REQUEST_URI}  !-f
+RewriteRule   ^(.+)                             http://serveurB.dom/$1
+
+ +

Le problème réside dans le fait que seules les pages + situées dans la racine DocumentRoot seront redirigées. Mais + même si vous pouvez ajouter des conditions supplémentaires (par + exemple pour traiter aussi les répertoires home, etc...), il + existe une meilleure solution :

+ +
+RewriteEngine on
+RewriteCond   %{REQUEST_URI} !-U
+RewriteRule   ^(.+)          http://serveurB.dom/$1
+
+reprendre ici +

On utilise ici la fonctionnalité de prévision des URLs + futures de mod_rewrite. Et cette solution + fonctionne pour tous les types d'URLs et de manière sûre. Par + contre, cette méthode a un impact sur les performances du + serveur web, car chaque requête entraîne le traitement d'une + sous-requête interne supplémentaire. Par conséquent, vous + pouvez l'utiliser si votre serveur web s'exécute sur un CPU + puissant. Dans le cas d'une machine plus lente, utilisez la + première approche, ou mieux, un script CGI ErrorDocument.

+
+
+ +
+ +
+ + Multiplexeur d'accès aux archives + +
+
Description :
+ +
+

Connaissez-vous la grande archive CPAN (Comprehensive Perl Archive + Network) située à http://www.perl.com/CPAN ? + CPAN redirige automatiquement les navigateurs vers un des + nombreux serveurs FTP répartis à travers le monde + (généralement un serveur assez proche du client) ; chaque + serveur héberge l'intégralité d'un miroir CPAN. Il s'agit ni + plus ni moins qu'un service d'accès FTP multiplexé. Alors que + le fonctionnement de l'archive CPAN repose sur des scripts + CGI, comment implémenter une approche similaire avec + mod_rewrite ?

+
+ +
Solution :
+ +
+

Premièrement, remarquons que depuis la version 3.0.0, + mod_rewrite accepte aussi le préfixe + "ftp:" dans les redirections. Et deuxièmement, + l'approximation de la localisation peut être effectuée par une + table de correspondances RewriteMap, en se basant sur + la racine du domaine du client. Un jeu de règles chaînées + astucieux nous permet d'utiliser cette racine du domaine comme + clé de recherche dans notre table de correspondances de + multiplexage.

+ +
+RewriteEngine on
+RewriteMap    multiplex                txt:/chemin/vers/map.cxan
+RewriteRule   ^/CxAN/(.*)              %{REMOTE_HOST}::$1                 [C]
+RewriteRule   ^.+\.([a-zA-Z]+)::(.*)$
+${multiplex:$1|ftp.défaut.dom}$2  [R,L]
+
+ +
+##
+##  map.cxan -- Multiplexing Map for CxAN%{DOCUMENT_ROOT/%{REQUEST_URI}
+##
+
+de        ftp://ftp.cxan.de/CxAN/
+uk        ftp://ftp.cxan.uk/CxAN/
+com       ftp://ftp.cxan.com/CxAN/
+ :
+##EOF##
+
+
+
+ +
+ +
+ + Contenu dépendant du navigateur + +
+
Description :
+ +
+

Il est parfois nécessaire, au moins pour les pages + principales, de fournir un contenu optimum adapté à chaque + type de navigateur, c'est à dire que l'on doit + fournir une version pour les navigateurs courants, une version + différente pour les navigateurs en mode texte du style de + Lynx, et une autre pour les autres navigateurs.

+
+ +
Solution :
%{DOCUMENT_ROOT/%{REQUEST_URI} + +
+

On ne peut pas utiliser la négociation de contenu car les + navigateurs ne fournissent pas leur type dans cette forme. + Nous devons nous baser sur l'en-tête HTTP "User-Agent". La + configuration ci-dessous effectue les actions suivantes : si + l'en-tête HTTP "User-Agent" commence par "Mozilla/3", la page + foo.html est réécrite en foo.NS.html + et la réécriture s'arrête. Si le navigateur est "Lynx" ou + "Mozilla" version 1 ou 2, la page + foo.html est réécrite en + foo.20.html. Tous les autres navigateurs + reçoivent la page foo.32.html. Voici le jeu de + règles :

+ +
+RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/3.*
+RewriteRule ^foo\.html$         foo.NS.html          [L]
+
+RewriteCond %{HTTP_USER_AGENT}  ^Lynx/.*         [OR]
+RewriteCond %{HTTP_USER_AGENT}  ^Mozilla/[12].*
+RewriteRule ^foo\.html$         foo.20.html          [L]
+
+RewriteRule ^foo\.html$         foo.32.html          [L]
+
+
+
+ +
+ +
+ + Miroir dynamique + +
+
Description :
+ +
+

Supposons que nous voulions intégrer dans notre espace de + nommage de belles pages web situées sur un serveur distant. + Dans le cas d'un serveur FTP, nous aurions utilisé le + programme mirror qui maintient vraiment une copie + des données distantes mise à jour explicitement sur le serveur + local. Pour un serveur web, nous pourrions utiliser le + programme webcopy qui utilise le protocole HTTP. + Ces deux techniques présentent cependant un + inconvénient majeur : la copie locale n'est véritablement à + jour qu'au moment où nous avons lancé le programme. Plutôt qu' + un miroir statique devant être défini explicitement, il serait + préférable d'avoir un miroir dynamique dont le contenu serait + mis à jour automatiquement, à la demande, sur le(s) serveur(s) + distant(s).

+
+ +
Solution :
+ +
+

Pour y parvenir, on fait + correspondre la page web ou même l'ensemble du + répertoire web distants à notre espace de nommage en utilisant + la fonctionnalité Mandataire (drapeau + [P] ou [proxy]) :

+ +
+RewriteEngine  on
+RewriteBase    /~quux/
+RewriteRule    ^page-convoitée/(.*)$  http://www.tstimpreso.com/page-convoitée/$1  [P]
+
+ +
+RewriteEngine  on
+RewriteBase    /~quux/
+RewriteRule    ^usa-news\.html$   http://www.quux-corp.com/news/index.html  [P]
+
+
+
+ +
+ +
+ + Miroir dynamique inverse + +
+
Description :
+ +
...
+ +
Solution :
+ +
+
+RewriteEngine on
+RewriteCond   /miroir/du/site-distant/$1           -U
+RewriteRule   ^http://www\.site-distant\.com/(.*)$ /miroir/du/site-distant/$1
+
+
+
+ +
+ +
+ + Récupérer des données manquantes depuis l'Intranet + +
+
Description :
+ +
+

C'est une méthode astucieuse permettant de faire + fonctionner virtuellement un serveur web d'entreprise + (www.quux-corp.dom) sur + l'Internet (extérieur à l'entreprise), tout en maintenant et + conservant dans la réalité ses données sur un serveur web + (www2.quux-corp.dom) de l'Intranet (interne à + l'entreprise) protégé par un pare-feu. L'astuce consiste, sur + le serveur web externe, à récupérer à la volée sur le serveur interne + les données demandées.

+
+ +
Solution :
+ +
+

Tout d'abord, nous devons nous assurer que notre pare-feu + protège bien le serveur web interne, et que seul le serveur + web externe est autorisé à y récupérer des données. Dans le + cas d'un filtrage par paquets, nous pourrions par exemple + définir un jeu de règles du pare-feu du style :

+ +
+ALLOW serveur www.quux-corp.dom Port >1024 -->
+serveur www2.quux-corp.dom Port 80
+DENY  serveur *                 Port *     -->
+serveur www2.quux-corp.dom Port 80
+
+ +

Il vous suffit d'adapter ces règles à la syntaxe de votre + pare-feu. Nous pouvons maintenant définir les règles de + mod_rewrite qui serviront à récupérer les + données manquantes en arrière-plan via la fonctionnalité de + mandataire :

+ +
+RewriteRule ^/~([^/]+)/?(.*)          /home/$1/.www/$2 [C]
+# L'utilisation de REQUEST_FILENAME ci dessous est correcte dans cet
+# exemple de contexte au niveau serveur car la règle qui fait référence
+# à REQUEST_FILENAME est chaînée à une règle qui définit
+# REQUEST_FILENAME.
+RewriteCond %{REQUEST_FILENAME}       !-f
+RewriteCond %{REQUEST_FILENAME}       !-d
+RewriteRule ^/home/([^/]+)/.www/?(.*) http://www2.quux-corp.dom/~$1/pub/$2 [P]
+
+
+
+ +
+ +
+ + Répartition de charge + +
+
Description :
+ +
+

Supposons que nous voulions répartir la charge du trafic + vers www.example.com entre les serveurs + www[0-5].example.com (un total de 6 serveurs). + Comment y parvenir ?

+
+ +
Solution :
+ +
+

Il existe de nombreuses solutions à ce problème. Nous + décrirons tout d'abord une variante assez connue basée sur + DNS, puis une autre basée sur mod_rewrite + :

+ +
    +
  1. + Round-Robin (tourniquet) DNS + +

    La méthode de répartition de charge la plus simple + consiste à utiliser le "DNS round-robin" + (rotation d'adresses) de + BIND. Vous devez seulement enregistrer les + serveurs www[0-9].example.com de manière + habituelle dans votre DNS à l'aide d'enregistrements de + type A (adresse), comme suit :

    + +
    +www0   IN  A       1.2.3.1
    +www1   IN  A       1.2.3.2
    +www2   IN  A       1.2.3.3
    +www3   IN  A       1.2.3.4
    +www4   IN  A       1.2.3.5
    +www5   IN  A       1.2.3.6
    +
    + +

    Puis vous ajoutez les entrées suivantes :

    + +
    +www   IN  A       1.2.3.1
    +www   IN  A       1.2.3.2
    +www   IN  A       1.2.3.3
    +www   IN  A       1.2.3.4
    +www   IN  A       1.2.3.5
    +
    + +

    Maintenant, lors de la résolution de + www.example.com, BIND renvoie + www0-www5 - mais selon une permutation + différente à chaque fois. De cette façon, les clients sont + répartis entre les différents serveurs. Notez cependant + que cette méthode de répartition de charge n'est pas + parfaite, car les résolutions DNS sont mises en cache par + les clients et les autres serveurs DNS du réseau, si + bien que lorsqu'un client s'est vu résoudre + www.example.com en un des + wwwN.example.com, toutes ses requêtes ultérieures + continueront d'aller vers la même adresse IP (et donc le + même serveur), au lieu d'être réparties entre les autres + serveurs. Le résultat est cependant globalement + satisfaisant car les requêtes sont réparties + collectivement entre chacun des serveurs web.

    +
  2. + +
  3. + Répartition de charge basée sur DNS + +

    Une méthode de répartition de charge sophistiquée basée + sur DNS consiste à utiliser le programme + lbnamed que l'on peut trouver à + http://www.stanford.edu/~schemers/docs/lbnamed/lbnamed.html. + Associé à des outils auxiliaires, il s'agit d'un programme + en Perl 5 qui permet d'effectuer une véritable répartition + de charge basée sur DNS.

    +
  4. + +
  5. + Round-Robin basé sur la fonctionnalité de + mandataire + +

    Dans cette variante, nous utilisons + mod_rewrite et sa fonctionnalité de + mandataire. Tout d'abord, nous définissons + www0.example.com comme un autre nom de + www.example.com en ajoutant l'entrée

    + +
    +www    IN  CNAME   www0.example.com.
    +
    + +

    dans le DNS. Puis nous définissons + www0.example.com comme serveur mandataire + seulement, c'est à dire que nous configurons cette machine + de telle sorte que toutes les URLs qui lui arrivent soient + simplement transmises, via le mandataire interne, vers un + des 5 autres serveurs (www1-www5). Pour y + parvenir, nous définissons tout d'abord un jeu de règles + qui contacte un script de répartition de charge + lb.pl pour toutes les URLs.

    + +
    +RewriteEngine on
    +RewriteMap    lb      prg:/chemin/vers/lb.pl
    +RewriteRule   ^/(.+)$ ${lb:$1}           [P,L]
    +
    + +

    Puis nous écrivons lb.pl :

    + +
    +#!/chemin/vers/perl
    +##
    +##  lb.pl -- script de répartition de charge
    +##
    +
    +$| = 1;
    +
    +$name   = "www";     # la base du nom du serveur
    +$first  = 1;         # le premier serveur (pas 0 ici, car 0 correspond à
    +		     # moi-même)
    +$last   = 5;         # le dernier serveur du tourniquet
    +$domain = "foo.dom"; # le nom de domaine
    +
    +$cnt = 0;
    +while (<STDIN>) {
    +    $cnt = (($cnt+1) % ($last+1-$first));
    +    $server = sprintf("%s%d.%s", $name, $cnt+$first, $domain);
    +    print "http://$server/$_";
    +}
    +
    +##EOF##
    +
    + + Une dernière remarque : à quoi cela sert-il ? + www0.example.com, quant à lui, n'est-il pas + toujours surchargé ? La réponse est oui, il est surchargé, + mais seulement avec des requêtes de mandataire ! Tous les + traitements SSI, CGI, ePerl, etc... sont entièrement + effectués sur les autres machines. Ceci peut fonctionner + correctement pour un site complexe. Le plus grand risque + réside ici dans le fait que www0 est un passage obligé et + que s'il est hors service, les autres serveurs deviennent + inaccessibles. +
  6. + +
  7. + Répartiteur de charge dédié + +

    Il existe aussi des solutions plus sophistiquées. + Cisco, F5, et de nombreuses autres sociétés proposent + des répartiteurs de charge matériels (utilisés en général + en mode doublé à des fins de redondance), qui offrent une + répartition de charge sophistiquée et des fonctionnalités + de passage automatique en mode de fonctionnement par défaut + en cas de problème. Cependant, des solutions logicielles + offrent aussi des fonctionnalités similaires avec du + matériel standard. Si vos besoins correspondent et si vous + êtes assez riche, vous pouvez envisager ces solutions. La + liste de diffusion lb-l + est un bon point de départ pour vos recherches.

    +
  8. +
+
+
+ +
+ +
+ + Nouveau type MIME, nouveau service + +
+
Description :
+ +
+

On trouve de nombreux programmes CGI attractifs sur le + réseau. Mais leur emploi est souvent rébarbatif, si bien que + de nombreux webmasters ne les utilisent pas. Même la + fonctionnalité de gestionnaire Action d'Apache pour les types + MIME ne convient que lorsque les programmes CGI ne nécessitent + pas d'URLs spéciales (réellement PATH_INFO et + QUERY_STRINGS) en entrée. Tout d'abord, + définissons un nouveau type de fichier ayant pour extension + .scgi (pour CGI sécurisé) qui sera associé pour + traitement au programme populaire cgiwrap. Le + problème est le suivant : par exemple, si on utilise un style + d'URL bien défini (voir ci-dessus), un fichier situé dans le + répertoire home de l'utilisateur pourra correspondre à l'URL + /u/user/foo/bar.scgi. Mais cgiwrap + nécessite des URLs de la forme + /~user/foo/bar.scgi/. La règle suivante apporte + la solution :

+ +
+RewriteRule ^/[uge]/([^/]+)/\.www/(.+)\.scgi(.*) ...
+... /interne/cgi/utilisateur/cgiwrap/~$1/$2.scgi$3  [NS,T=application/x-http-cgi]
+
+ +

Ou considérons ces autres programmes attractifs : + wwwlog (qui affiche le journal des accès + access.log pour un sous répertoire correspondant + à une URL) et wwwidx (qui exécute Glimpse sur un + sous répertoire correspondant à une URL). Nous devons fournir + l'URL correspondante à ces programmes afin qu'ils sachent sur + quel répertoire ils doivent agir. Mais c'est en général + compliqué, car ils peuvent être appelés à nouveau + par la forme d'URL alternative, c'est à dire que typiquement, + nous exécuterions le programme swwidx depuis + /u/user/foo/ via un hyperlien vers

+ +
+/internal/cgi/user/swwidx?i=/u/user/foo/
+
+ +

ce qui n'est pas satisfaisant, car nous devons expliciter + à la fois la localisation du répertoire + et la localisation du programme CGI dans + l'hyperlien. Si nous devons nous réorganiser, il nous faudra + beaucoup de temps pour modifier tous les hyperliens.

+
+ +
Solution :
+ +
+

La solution consiste ici à fournir un nouveau format d'URL + qui redirige automatiquement vers la requête CGI appropriée. + Pour cela, on définit les règles suivantes :

+ +
+RewriteRule   ^/([uge])/([^/]+)(/?.*)/\*  /interne/cgi/utilisateur/wwwidx?i=/$1/$2$3/
+RewriteRule   ^/([uge])/([^/]+)(/?.*):log /interne/cgi/utilisateur/wwwlog?f=/$1/$2$3
+
+ +

Et maintenant l'hyperlien qui renvoie vers + /u/user/foo/ se réduit à

+ +
+HREF="*"
+
+ +

qui est automatiquement transformé en interne en

+ +
+/internal/cgi/user/wwwidx?i=/u/user/foo/
+
+ +

Une approche similaire permet d'invoquer le programme CGI + du journal des accès lorsque l'hyperlien :log est + utilisé.

+
+
+ +
+ +
+ + Régéneration de contenu à la volée + +
+
Description :
+ +
+

Voici une fonctionnalité vraiment ésotérique : des pages + générées dynamiquement mais servies statiquement, c'est à + dire que les pages doivent être servies comme des pages + purement statiques (lues depuis le système de fichiers et + servies en l'état), mais doivent être générées dynamiquement + par le serveur web si elles sont absentes. Ainsi, vous pouvez + avoir des pages générées par CGI qui sont servies statiquement + à moins qu'un administrateur (ou une tâche de + cron) ne supprime les + contenus statiques. Les contenus sont ensuite actualisés.

+
+ +
Solution :
+ +
+ A cet effet, on utilise le jeu de règles suivant : + +
+# Cet exemple n'est valable que dans un contexte de répertoire
+RewriteCond %{REQUEST_FILENAME}   !-s
+RewriteRule ^page\.html$          page.cgi   [T=application/x-httpd-cgi,L]
+
+ +

Ainsi, une requête pour page.html entraîne + l'exécution interne de la page page.cgi + correspondante si page.html n'existe pas + ou possède une taille de fichier nulle. L'astuce réside ici + dans le fait que page.cgi est un script CGI + qui (en plus de STDOUT) écrit sa sortie dans le + fichier page.html. Une fois le script exécuté, le + serveur sert la page page.html fraîchement + générée. Si le webmaster + veut actualiser les contenus, il lui suffit de supprimer le + fichier page.html (le plus souvent via une tâche + de cron).

+
+
+ +
+ +
+ + Actualisation automatique d'un document + +
+
Description :
+ +
+

Lorsque nous créons une page web complexe, ne serait-il pas + souhaitable que le navigateur web actualise automatiquement la + page chaque fois que nous en sauvegardons une nouvelle version + à partir de notre éditeur ? Impossible ?

+
+ +
Solution :
+ +
+

Non ! Nous allons pour cela combiner la fonctionnalité MIME + multipart, la fonctionnalité NPH du serveur web et la + puissance de mod_rewrite pour la manipulation + d'URLs. Tout d'abord, nous définissons une nouvelle + fonctionnalité pour les URLs : l'ajout de + :refresh à toute URL fait que la 'page' est + actualisée chaque fois que la ressource est mise à jour dans + le système de fichiers.

+ +
+RewriteRule   ^(/[uge]/[^/]+/?.*):refresh  /interne/cgi/apache/nph-refresh?f=$1
+
+ +

Nous appelons maintenant cette URL

+ +
+/u/foo/bar/page.html:refresh
+
+ +

ce qui entraîne en interne l'invocation de l'URL

+ +
+/interne/cgi/apache/nph-refresh?f=/u/foo/bar/page.html
+
+ +

Il ne reste plus qu'à écrire le script CGI. Bien que l'on + écrive habituellement dans ces cas "laissé à la charge du + lecteur à titre d'exercice", ;-) je vous l'offre, aussi.

+ +
+#!/sw/bin/perl
+##
+##  nph-refresh -- script NPH/CGI pour l'actualisation automatique de
+##  pages
+##  Copyright (c) 1997 Ralf S. Engelschall, All Rights Reserved.
+##
+$| = 1;
+
+#   éclate la variable QUERY_STRING
+@pairs = split(/&/, $ENV{'QUERY_STRING'});
+foreach $pair (@pairs) {
+    ($name, $value) = split(/=/, $pair);
+    $name =~ tr/A-Z/a-z/;
+    $name = 'QS_' . $name;
+    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+    eval "\$$name = \"$value\"";
+}
+$QS_s = 1 if ($QS_s eq '');
+$QS_n = 3600 if ($QS_n eq '');
+if ($QS_f eq '') {
+    print "HTTP/1.0 200 OK\n";
+    print "Content-type: text/html\n\n";
+    print "&lt;b&gt;ERREUR&lt;/b&gt;: Aucun fichier fourni\n";
+    exit(0);
+}
+if (! -f $QS_f) {
+    print "HTTP/1.0 200 OK\n";
+    print "Content-type: text/html\n\n";
+    print "&lt;b&gt;ERREUR&lt;/b&gt;: Fichier $QS_f non trouvé\n";
+    exit(0);
+}
+
+sub print_http_headers_multipart_begin {
+    print "HTTP/1.0 200 OK\n";
+    $bound = "ThisRandomString12345";
+    print "Content-type: multipart/x-mixed-replace;boundary=$bound\n";
+    &print_http_headers_multipart_next;
+}
+
+sub print_http_headers_multipart_next {
+    print "\n--$bound\n";
+}
+
+sub print_http_headers_multipart_end {
+    print "\n--$bound--\n";
+}
+
+sub displayhtml {
+    local($buffer) = @_;
+    $len = length($buffer);
+    print "Content-type: text/html\n";
+    print "Content-length: $len\n\n";
+    print $buffer;
+}
+
+sub readfile {
+    local($file) = @_;
+    local(*FP, $size, $buffer, $bytes);
+    ($x, $x, $x, $x, $x, $x, $x, $size) = stat($file);
+    $size = sprintf("%d", $size);
+    open(FP, "&lt;$file");
+    $bytes = sysread(FP, $buffer, $size);
+    close(FP);
+    return $buffer;
+}
+
+$buffer = &readfile($QS_f);
+&print_http_headers_multipart_begin;
+&displayhtml($buffer);
+
+sub mystat {
+    local($file) = $_[0];
+    local($time);
+
+    ($x, $x, $x, $x, $x, $x, $x, $x, $x, $mtime) = stat($file);
+    return $mtime;
+}
+
+$mtimeL = &mystat($QS_f);
+$mtime = $mtime;
+for ($n = 0; $n &lt; $QS_n; $n++) {
+    while (1) {
+        $mtime = &mystat($QS_f);
+        if ($mtime ne $mtimeL) {
+            $mtimeL = $mtime;
+            sleep(2);
+            $buffer = &readfile($QS_f);
+            &print_http_headers_multipart_next;
+            &displayhtml($buffer);
+            sleep(5);
+            $mtimeL = &mystat($QS_f);
+            last;
+        }
+        sleep($QS_s);
+    }
+}
+
+&print_http_headers_multipart_end;
+
+exit(0);
+
+##EOF##
+
+
+
+ +
+ +
+ + Hébergement virtuel de masse + +
+
Description :
+ +
+

La fonctionnalité VirtualHost d'Apache est intéressante et + fonctionne de manière satisfaisante jusqu'à quelques + douzaines de serveurs virtuels. Par contre, si vous êtes un + FAI et devez héberger des centaines de serveurs virtuels, + cette méthode n'est pas optimale.

+
+ +
Solution :
+ +
+

Pour fournir cette fonctionnalité avec + mod_rewrite, on fait correspondre à notre espace de + nommage la page web ou même le répertoire complet distants en + utilisant la fonctionnalité Mandataire + (drapeau [P]) :

+ +
+##
+##  vhost.map
+##
+www.vhost1.dom:80  /chemin/vers/racine-doc/vhost1
+www.vhost2.dom:80  /chemin/vers/racine-doc/vhost2
+     :
+www.vhostN.dom:80  /chemin/vers/racine-doc/vhostN
+
+ +
+##
+##  httpd.conf
+##
+    :
+#   utilisation du nom d'hôte canonique pour les redirections, etc...
+UseCanonicalName on
+
+    :
+#   ajout du serveur virtuel en tête du format CLF
+CustomLog  /chemin/vers/access_log  "%{VHOST}e %h %l %u %t \"%r\" %>s %b"
+    :
+
+#   activation du moteur de réécriture pour le serveur principal
+RewriteEngine on
+
+#   définition de deux tables de correspondances : une première pour
+#   corriger les URLs et une seconde qui associe les serveurs virtuels
+#   disponibles avec leurs racines des documents correspondantes.
+RewriteMap    lowercase    int:tolower
+RewriteMap    vhost        txt:/chemin/vers/vhost.map
+
+#   et enfin sélection proprement dite du serveur virtuel approprié via
+#   une seule règle longue et complexe :
+#
+#   1. on s'assure de ne pas sélectionner un hôte virtuel pour les
+#   adresses communes
+
+RewriteCond   %{REQUEST_URI}  !^/adresse-commune1/.*
+RewriteCond   %{REQUEST_URI}  !^/adresse-commune2/.*
+    :
+RewriteCond   %{REQUEST_URI}  !^/adresse-communeN/.*
+#
+#   2. on vérifie que l'on dispose bien d'un en-tête Host, car
+#   actuellement, cette méthode ne peut faire de l'hébergement virtuel
+#   qu'avec cet en-tête
+RewriteCond   %{HTTP_HOST}  !^$
+#
+#   3. mise en minuscules du nom d'hôte
+RewriteCond   ${lowercase:%{HTTP_HOST}|NONE}  ^(.+)$
+#
+#   4. recherche ce ce nom d'hôte dans vhost.map et
+#      enregistrement de celui-ci seulement s'il s'agit d'un chemin
+#      (et non "NONE" en provenance de la condition précédente)
+RewriteCond   ${vhost:%1}  ^(/.*)$
+#
+#   5. nous pouvons enfin faire correspondre l'URL avec la racine des
+#   documents correspondant au serveur virtuel approprié et enregistrer
+#   ce dernier à des fins de journalisation
+RewriteRule   ^/(.*)$   %1/$1  [E=VHOST:${lowercase:%{HTTP_HOST}}]
+    :
+
+
+
+ +
+ +
+ + Interdiction d'hôtes + +
+
Description :
+ +
+

Comment interdire l'accès à notre serveur à une liste + d'hôtes ?

+
+ +
Solution :
+ +
+

Pour Apache >= 1.3b6 :

+ +
+RewriteEngine on
+RewriteMap    hôtes-interdits  txt:/chemin/vers/hôtes-interdits
+RewriteCond   ${hôtes-interdits:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
+RewriteCond   ${hôtes-interdits:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
+RewriteRule   ^/.*  -  [F]
+
+ +

Pour Apache <= 1.3b6 :

+ +
+RewriteEngine on
+RewriteMap    hôtes-interdits  txt:/chemin/vers/hôtes-interdits
+RewriteRule   ^/(.*)$ ${hôtes-interdits:%{REMOTE_HOST}|NOT-FOUND}/$1
+RewriteRule   !^NOT-FOUND/.* - [F]
+RewriteRule   ^NOT-FOUND/(.*)$ ${hôtes-interdits:%{REMOTE_ADDR}|NOT-FOUND}/$1
+RewriteRule   !^NOT-FOUND/.* - [F]
+RewriteRule   ^NOT-FOUND/(.*)$ /$1
+
+ +
+##
+##  hosts.deny
+##
+##  ATTENTION! Ceci est une table de correspondances, pas une liste,
+##  même si on l'utilise en tant que telle. mod_rewrite l'interprète
+##  comme un ensemble de paires clé/valeur ; chaque entrée doit donc
+##  au moins posséder une valeur fictive "-".
+##
+
+193.102.180.41 -
+bsdti1.sdm.de  -
+192.76.162.40  -
+
+
+
+ +
+ +
+ + Interdiction du mandataire + +
+
Description :
+ +
+

Comment interdire l'utilisation du mandataire d'Apache pour + un certain hôte, ou même seulement pour un utilisateur + de cet hôte ?

+
+ +
Solution :
+ +
+

Nous devons tout d'abord nous assurer que + mod_rewrite arrive après(!) + mod_proxy dans le fichier de configuration + lors de la compilation du serveur web Apache. De cette façon, + il est appelé avant mod_proxy. Nous + pouvons ensuite définir cette règle pour une interdiction + dépendant de l'hôte :

+ +
+RewriteCond %{REMOTE_HOST} ^hôte-à-rejeter\.mon-domaine\.com$
+RewriteRule !^http://[^/.]\.mon-domaine.com.*  - [F]
+
+ +

...et celle-ci pour une interdiction dépendant de + utilisateur@hôte :

+ +
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST}  ^utilisateur-à-
+rejeter@hôte-à-rejeter\.mon-domaine\.com$
+RewriteRule !^http://[^/.]\.mon-domaine.com.*  - [F]
+
+
+
+ +
+ +
+ + Variante particulière d'authentification + +
+
Description :
+ +
+

On a parfois besoin d'une authentification très + particulière, par exemple une authentification qui vérifie la + présence d'un utilisateur dans une liste explicitement + définie. Seuls ceux qui sont présents dans la liste se voient + accorder un accès, et ceci sans avoir à + s'identifier/authentifier (comme c'est le cas avec une + authentification de base via mod_auth).

+
+ +
Solution :
+ +
+

On définit une liste de conditions de réécriture pour + interdire l'accès à tout le monde, sauf aux utilisateurs + autorisés :

+ +
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami1@client1.quux-corp\.com$
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami2@client2.quux-corp\.com$
+RewriteCond %{REMOTE_IDENT}@%{REMOTE_HOST} !^ami3@client3.quux-corp\.com$
+RewriteRule ^/~quux/seulement-pour-les-amis/      -                                 [F]
+
+
+
+ +
+ +
+ + Redirection basée sur le référent + +
+
Description :
+ +
+

Comment écrire un programme souple qui redirige certaines + URLs en se basant sur l'en-tête HTTP "Referer", et peut être + configuré avec autant de pages de référence + que l'on veut ?

+
+ +
Solution :
+ +
+

On utilise le jeu de règles vraiment astucieux suivant :

+ +
+RewriteMap  deflector txt:/chemin/vers/deflector.map
+
+RewriteCond %{HTTP_REFERER} !=""
+RewriteCond ${deflector:%{HTTP_REFERER}} ^-$
+RewriteRule ^.* %{HTTP_REFERER} [R,L]
+
+RewriteCond %{HTTP_REFERER} !=""
+RewriteCond ${deflector:%{HTTP_REFERER}|NOT-FOUND} !=NOT-FOUND
+RewriteRule ^.* ${deflector:%{HTTP_REFERER}} [R,L]
+
+ +

... en association avec la table de réécriture + correspondante :

+ +
+##
+##  deflector.map
+##
+
+http://www.mauvais-sujets.com/mauvais/index.html    -
+http://www.mauvais-sujets.com/mauvais/index2.html   -
+http://www.mauvais-sujets.com/mauvais/index3.html   http://quelque-part.com/
+
+ +

Les requêtes sont redirigées vers la page de référence + (lorsque la valeur correspondant à la clé extraite de la table + de correspondances est égale à "-"), ou vers une + URL spécifique (lorsqu'une URL est définie dans la table de + correspondances comme second argument).

+
+
+ +
+ +
+ diff --git a/docs/manual/rewrite/rewrite_guide_advanced.xml.meta b/docs/manual/rewrite/rewrite_guide_advanced.xml.meta index 009d0377bd..ce654fe7b3 100644 --- a/docs/manual/rewrite/rewrite_guide_advanced.xml.meta +++ b/docs/manual/rewrite/rewrite_guide_advanced.xml.meta @@ -8,5 +8,6 @@ en + fr diff --git a/docs/manual/rewrite/rewrite_tech.html b/docs/manual/rewrite/rewrite_tech.html index 18b37ed76d..39712080e7 100644 --- a/docs/manual/rewrite/rewrite_tech.html +++ b/docs/manual/rewrite/rewrite_tech.html @@ -3,3 +3,7 @@ URI: rewrite_tech.html.en Content-Language: en Content-type: text/html; charset=ISO-8859-1 + +URI: rewrite_tech.html.fr +Content-Language: fr +Content-type: text/html; charset=ISO-8859-1 diff --git a/docs/manual/rewrite/rewrite_tech.html.fr b/docs/manual/rewrite/rewrite_tech.html.fr new file mode 100644 index 0000000000..b3f9f658b9 --- /dev/null +++ b/docs/manual/rewrite/rewrite_tech.html.fr @@ -0,0 +1,179 @@ + + + +Détails techniques sur le module Apache mod_rewrite - Serveur Apache HTTP + + + + + +
<-
+
+Apache > Serveur HTTP > Documentation > Version 2.3 > Rewrite

Détails techniques sur le module Apache mod_rewrite

+
+

Langues Disponibles:  en  | + fr 

+
+ +

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

+
+ +
top
+
+

Fonctionnement interne

+ +

Le fonctionnement interne de ce module est très complexe, mais + il est nécessaire de l'expliquer, même à l'utilisateur "standard", + afin d'éviter les erreurs courantes et de pouvoir exploiter toutes + ses fonctionnalités.

+
top
+
+

Phases de l'API

+ +

Il faut tout d'abord bien comprendre que le traitement d'une + requête HTTP par Apache s'effectue en plusieurs phases. L'API + d'Apache fournit un point d'accroche (hook) pour chacune de ces + phases. Mod_rewrite utilise deux de ces hooks : le hook de + conversion des URLs en noms de fichiers qui est utilisé quand la + requête HTTP a été lue mais avant le démarrage de tout processus + d'autorisation, et le hook "Fixup" qui est déclenché après les + phases d'autorisation et après la lecture des fichiers de + configuration niveau répertoire (.htaccess), mais + avant que le gestionnaire de contenu soit activé.

+ +

Donc, lorsqu'une requête arrive et quand Apache a déterminé le + serveur correspondant (ou le serveur virtuel), le moteur de + réécriture commence le traitement de toutes les directives de + mod_rewrite de la configuration du serveur principal dans la phase + de conversion URL vers nom de fichier. Une fois ces étapes + franchies, lorsque les repertoires de données finaux ont été + trouvés, les directives de configuration de mod_rewrite au niveau + répertoire sont éxécutées dans la phase Fixup. Dans les deux cas, + mod_rewrite réécrit les URLs soit en nouvelles URLs, soit en noms + de fichiers, bien que la distinction entre les deux ne soit pas + évidente. Cette utilisation de l'API n'était pas sensée s'opérer + de cette manière lorsque l'API fut conçue, mais depuis Apache 1.x, + c'est le seul mode opératoire possible pour mod_rewrite. Afin de + rendre les choses plus claires, souvenez-vous de ces deux points :

+ +
    +
  1. Bien que mod_rewrite réécrive les URLs en URLs, les URLs en + noms de fichiers et même des noms de fichiers en d'autres noms + de fichiers, l'API ne propose actuellement qu'un hook URL vers + nom de fichier. Les deux hooks manquants seront ajoutés dans + Apache à partir de la version 2.0 afin de rendre le processus + plus clair. Mais ce point ne présente pas d'inconvénient pour + l'utilisateur, il s'agit simplement d'un fait que vous devez + garder à l'esprit : Apache en fait plus avec le hook URL vers + nom de fichier que l'API n'a la prétention d'en faire.
  2. + +
  3. + Paradoxalement, mod_rewrite permet la manipulation d'URLs dans + un contexte de répertoire, c'est à dire dans les + fichiers .htaccess, bien que ces derniers + soient traités bien longtemps après que les URLs n'aient été + traduites en noms de fichiers. Les choses doivent se dérouler + ainsi car les fichiers .htaccess résident dans le + système de fichiers, et le traitement a déjà atteint + cette étape. Autrement dit, en accord avec les phases de + l'API, à ce point du traitement, il est trop tard pour + effectuer des manipulations d'URLs. Pour résoudre ce problème + d'antériorité, mod_rewrite utilise une astuce : pour effectuer + une manipulation URL/nom de fichier dans un contexte de + répertoire, mod_rewrite réécrit tout d'abord le nom de fichier + en son URL d'origine (ce qui est normalement impossible, mais + voir ci-dessous l'astuce utilisée par la directive + RewriteBase pour y parvenir), puis + initialise une nouvelle sous-requête interne avec la nouvelle + URL ; ce qui a pour effet de redémarrer le processus des + phases de l'API. + +

    Encore une fois, mod_rewrite fait tout ce qui est en son + pouvoir pour rendre la complexité de cette étape complètement + transparente à l'utilisateur, mais vous devez garder ceci à + l'esprit : alors que les manipulations d'URLs dans le contexte + du serveur sont vraiment rapides et efficaces, les réécritures + dans un contexte de répertoire sont lentes et inefficaces à + cause du problème d'antériorité précité. Cependant, c'est la + seule manière dont mod_rewrite peut proposer des manipulations + d'URLs (limitées à une branche du système de fichiers) à + l'utilisateur standard.

    +
  4. +
+ +

Ne perdez pas de vue ces deux points!

+
top
+
+

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.

+

+ [Nécessite le mode graphique pour     l'affichage]
+ Figure 1:Déroulement du contrôle à travers le jeu de + règles de réécriture +

+

Comme vous pouvez le voir, 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. S'il n'y en a pas, mod_rewrite remplace + simplement 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.

+ +
+
+

Langues Disponibles:  en  | + fr 

+
+ \ No newline at end of file diff --git a/docs/manual/rewrite/rewrite_tech.xml.fr b/docs/manual/rewrite/rewrite_tech.xml.fr new file mode 100644 index 0000000000..80be3b07ca --- /dev/null +++ b/docs/manual/rewrite/rewrite_tech.xml.fr @@ -0,0 +1,184 @@ + + + + + + + + + + +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 +Introduction à mod_rewrite +Guide de réécriture - exemples +utiles +Guide de réécriture +avancée - exemples utiles avancés + +
Fonctionnement interne + +

Le fonctionnement interne de ce module est très complexe, mais + il est nécessaire de l'expliquer, même à l'utilisateur "standard", + afin d'éviter les erreurs courantes et de pouvoir exploiter toutes + ses fonctionnalités.

+
+ +
Phases de l'API + +

Il faut tout d'abord bien comprendre que le traitement d'une + requête HTTP par Apache s'effectue en plusieurs phases. L'API + d'Apache fournit un point d'accroche (hook) pour chacune de ces + phases. Mod_rewrite utilise deux de ces hooks : le hook de + conversion des URLs en noms de fichiers qui est utilisé quand la + requête HTTP a été lue mais avant le démarrage de tout processus + d'autorisation, et le hook "Fixup" qui est déclenché après les + phases d'autorisation et après la lecture des fichiers de + configuration niveau répertoire (.htaccess), mais + avant que le gestionnaire de contenu soit activé.

+ +

Donc, lorsqu'une requête arrive et quand Apache a déterminé le + serveur correspondant (ou le serveur virtuel), le moteur de + réécriture commence le traitement de toutes les directives de + mod_rewrite de la configuration du serveur principal dans la phase + de conversion URL vers nom de fichier. Une fois ces étapes + franchies, lorsque les repertoires de données finaux ont été + trouvés, les directives de configuration de mod_rewrite au niveau + répertoire sont éxécutées dans la phase Fixup. Dans les deux cas, + mod_rewrite réécrit les URLs soit en nouvelles URLs, soit en noms + de fichiers, bien que la distinction entre les deux ne soit pas + évidente. Cette utilisation de l'API n'était pas sensée s'opérer + de cette manière lorsque l'API fut conçue, mais depuis Apache 1.x, + c'est le seul mode opératoire possible pour mod_rewrite. Afin de + rendre les choses plus claires, souvenez-vous de ces deux points :

+ +
    +
  1. Bien que mod_rewrite réécrive les URLs en URLs, les URLs en + noms de fichiers et même des noms de fichiers en d'autres noms + de fichiers, l'API ne propose actuellement qu'un hook URL vers + nom de fichier. Les deux hooks manquants seront ajoutés dans + Apache à partir de la version 2.0 afin de rendre le processus + plus clair. Mais ce point ne présente pas d'inconvénient pour + l'utilisateur, il s'agit simplement d'un fait que vous devez + garder à l'esprit : Apache en fait plus avec le hook URL vers + nom de fichier que l'API n'a la prétention d'en faire.
  2. + +
  3. + Paradoxalement, mod_rewrite permet la manipulation d'URLs dans + un contexte de répertoire, c'est à dire dans les + fichiers .htaccess, bien que ces derniers + soient traités bien longtemps après que les URLs n'aient été + traduites en noms de fichiers. Les choses doivent se dérouler + ainsi car les fichiers .htaccess résident dans le + système de fichiers, et le traitement a déjà atteint + cette étape. Autrement dit, en accord avec les phases de + l'API, à ce point du traitement, il est trop tard pour + effectuer des manipulations d'URLs. Pour résoudre ce problème + d'antériorité, mod_rewrite utilise une astuce : pour effectuer + une manipulation URL/nom de fichier dans un contexte de + répertoire, mod_rewrite réécrit tout d'abord le nom de fichier + en son URL d'origine (ce qui est normalement impossible, mais + voir ci-dessous l'astuce utilisée par la directive + RewriteBase pour y parvenir), puis + initialise une nouvelle sous-requête interne avec la nouvelle + URL ; ce qui a pour effet de redémarrer le processus des + phases de l'API. + +

    Encore une fois, mod_rewrite fait tout ce qui est en son + pouvoir pour rendre la complexité de cette étape complètement + transparente à l'utilisateur, mais vous devez garder ceci à + l'esprit : alors que les manipulations d'URLs dans le contexte + du serveur sont vraiment rapides et efficaces, les réécritures + dans un contexte de répertoire sont lentes et inefficaces à + cause du problème d'antériorité précité. Cependant, c'est la + seule manière dont mod_rewrite peut proposer des manipulations + d'URLs (limitées à une branche du système de fichiers) à + l'utilisateur standard.

    +
  4. +
+ +

Ne perdez pas de vue ces deux points!

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

+

+ [Nécessite le mode graphique pour
+	   l'affichage]
+ Figure 1:Déroulement du contrôle à travers le jeu de + règles de réécriture +

+

Comme vous pouvez le voir, 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. S'il n'y en a pas, mod_rewrite remplace + simplement 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.

+ +
+ + +
+ diff --git a/docs/manual/rewrite/rewrite_tech.xml.meta b/docs/manual/rewrite/rewrite_tech.xml.meta index 42649f6b69..59560c6263 100644 --- a/docs/manual/rewrite/rewrite_tech.xml.meta +++ b/docs/manual/rewrite/rewrite_tech.xml.meta @@ -8,5 +8,6 @@ en + fr