Serveur HTTP Apache Version 2.5
Ce document est un complément à la documentation de référence du
module mod_rewrite
. Il décrit l'utilisation de la
directive RewriteMap
, et
fournit des exemples pour chacun des différents types de
RewriteMap
.
La directive RewriteMap
définit une fonction externe qui peut être appelée depuis une
directive RewriteRule
ou
RewriteCond
pour
accomplir une réécriture trop compliquée, ou trop spécialisée pour
être effectuée à partir d'expressions rationnelles. Vous trouverez
ci-dessous les différents types disponibles pour la source de
données, ceux-ci étant par ailleurs énumérés dans la documentation de
référence de RewriteMap
.
La syntaxe de la directive RewriteMap
est la suivante :
RewriteMap MapName MapType:MapSource
L'argument MapName est un nom arbitraire que vous associez à la table de correspondances, et que vous pourrez utilisez par la suite dans les directives de réécriture. Les recherches dans la table de correspondance s'effectuent en respectant cette syntaxe :
${
nom-map :
clé-recherche
}
${
nom-map :
clé-recherche |
DefaultValue }
Lorsque cette syntaxe est employée, la table de correspondances nom-map est consultée et la clé clé-recherche recherchée. Si la clé est trouvée, la fonction de recherche dans la table de correspondance est remplacée par SubstValue, ou par DefaultValue dans le cas contraire, ou par la chaîne vide si aucune DefaultValue n'a été spécifiée.
Par exemple, vous pouvez définir une directive
RewriteMap
comme suit :
RewriteMap examplemap "txt:/path/to/file/map.txt"
Vous pourrez par la suite utiliser cette table de correspondances
dans une directive RewriteRule
comme suit :
RewriteRule "^/ex/(.*)" "${examplemap:$1}"
Il est possible de spécifier une valeur par défaut qui sera utilisée si la recherche dans la table de correspondances est infructueuse :
RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"
Vous ne pouvez utilisez la directive RewriteMap
ni dans
les sections <Directory>
, ni dans les fichiers
.htaccess
. Vous devez déclarer la table de correspondances
au niveau du serveur principal ou dans un contexte de serveur virtuel.
Par contre, si vous ne pouvez pas déclarer la table dans une section
<Directory> ou dans un fichier .htaccess
, vous
pourrez y faire référence dans ces contextes, une fois cette table
créée.
Les sections suivantes décrivent les différents types de tables de correspondances type-map disponibles, et fournissent des exemples pour chacun d'entre eux.
Quand le type de table int
est spécifié, la
correspondance s'effectue via une des fonctions internes RewriteMap
disponibles. Les
développeurs de modules peuvent fournir des fonctions internes
supplémentaires en les enregistrant via l'API
ap_register_rewrite_mapfunc
. Les fonctions fournies par
défaut sont :
Pour utiliser une de ces fonctions, créez une
RewriteMap
qui référence la
fonction interne, et insérez-la dans votre RewriteRule
:
Redirection d'un URI vers une version en minuscules d'elle-même
RewriteMap lc int:tolower RewriteRule "(.*)" "${lc:$1}" [R]
Notez que cet exemple n'est présenté ici qu'à titre
d'illustration et ne constitue pas une recommandation. Si vous
voulez rendre les URLs insensibles à la casse, utiliser plutôt le
module mod_speling
.
Lorsqu'un type-map txt
est utilisé, la source-map
est un chemin du système de fichiers vers un fichier de
correspondances au format texte, contenant sur chaque ligne une
paire clé/valeur séparées par un espace. Il est possible d'insérer
des commentaires sous la forme de chaînes commençant par le caractère
'#'.
Un fichier de correspondances au format texte valide possèdera la syntaxe suivante :
# Ligne de commentaires
clé valeur-substitution
clé valeur-substitution # commentaire
Lorsque la table de correspondance fait l'objet d'une recherche, la valeur spécifiée est recherchée dans le premier champ, et si elle est trouvée, la valeur de substitution est renvoyée.
Par exemple, nous pourrions utiliser un fichier de correspondances pour traduire des noms de produits en identifiants produits pour obtenir des URLs plus simples à mémoriser, en utilisant la recette suivante :
Product to ID configuration
RewriteMap product2id "txt:/etc/apache2/productmap.txt" RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
Nous supposons ici que le script prods.php
sait quoi
faire lorsqu'il reçoit un argument id=NON-TROUVE
, dans
le cas où le produit ne se trouve pas dans la table de
correspondances.
Le fichier /etc/apache2/map-produit.txt
contient ce
qui suit :
##
## map-produit.txt - Fichier de correspondances Produit - Identifiant
##
TELEVISION 993
STEREO 198
CANNE-A-PECHE 043
BALLON-BASKET 418
TELEPHONE 328
Ainsi, lorsqu'une requête pour
http://example.com/produit/TELEVISION
arrive, la directive
RewriteRule
s'applique, et la
requête est transformée en interne en /prods.php?id=993
.
.htaccess
, vous devrez supprimer le
slash de début dans le modèle de réécriture afin que ce dernier
puisse correspondre à toute URL :
RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
Les clés de recherche sont mises en cache par httpd jusqu'à ce que
le mtime
(date de modification) du fichier de
correspondances soit modifié, ou que le serveur httpd soit
redémarré, ce qui améliore les performances pour les tables de
correspondances consultées par de nombreuses requêtes.
Lorsque le type-map spécifié est rnd
, la source est
un chemin du système de fichiers vers un fichier de correspondances
au format texte dont chaque ligne contient une clé, et une ou
plusieurs valeurs séparées par le caractère |
. Si une
clé convient, une des valeurs correspondantes sera choisie de
manière aléatoire.
Par exemple, vous pouvez utiliser le fichier de correspondances et les directives suivants pour implémenter une répartition de charge aléatoire entre plusieurs serveurs d'arrière-plan, par l'intermédiaire d'un mandataire inverse. Les images sont envoyées vers un des serveurs de l'ensemble 'statique', tandis que tout le reste est envoyé vers un des serveurs de l'ensemble 'dynamique'.
##
## map.txt -- table de réécriture
##
statique www1|www2|www3|www4
dynamique www5|www6
Configuration directives
RewriteMap servers "rnd:/path/to/file/map.txt" RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1" [NC,P,L] RewriteRule "^/(.*)" "http://${servers:dynamic}/$1" [P,L]
Ainsi, lorsqu'une image est demandée et que la première règle
convient, RewriteMap
recherche la chaîne
statique
dans le fichier de correspondances qui
renvoie un des noms de serveurs spécifiés de manière aléatoire,
ce dernier étant utilisé dans la cible de la règle
RewriteRule
.
Si vous voulez qu'un des serveurs soit plus souvent sollicité que les autres (par exemple s'il possède plus de mémoire, et peut donc traiter d'avantage de requêtes), spécifiez-le plusieurs fois dans la liste des serveurs.
statique www1|www1|www2|www3|www4
Lorsque le type-map dbm
est utilisé, la source est
un chemin du système de fichiers vers un fichier de données DBM
contenant des paires clé/valeur permettant d'effectuer la
correspondance. Le fonctionnement est identique à celui du type-map
txt
, mais beaucoup plus rapide car un fichier DBM est
indexé, alors qu'un fichier texte ne l'est pas. L'accès à la clé
recherchée est donc plus rapide.
Vous pouvez éventuellement spécifier un type dbm particulier :
RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"
Ce type peut être choisi parmi sdbm
, gdbm
,
ndbm
ou db
. Il est
cependant recommandé d'utiliser l'utilitaire httxt2dbm fourni avec le
serveur HTTP Apache, car il utilise la bibliothèque DBM appropriée,
à savoir celle qui a été utilisée lors de la compilation de httpd.
Pour créer un fichier dbm, créez tout d'abord un fichier de
correspondances au format texte comme décrit dans la section txt. Traitez ensuite ce fichier avec
httxt2dbm
:
$ httxt2dbm -i fichier-map.txt -o fichier-map.map
Vous pouvez alors faire référence au fichier obtenu dans votre
directive RewriteMap
:
RewriteMap mapname "dbm:/etc/apache/mapfile.map"
Notez qu'avec certains types dbm, plusieurs fichiers possédant le
même nom de base sont créés. Par exemple, vous pouvez obtenir deux
fichiers nommés fichier-map.map.dir
et
fichier-map.map.pag
. Ceci est tout à fait normal, et vous
ne devez utiliser que le nom de base fichier-map.map
dans votre
directive RewriteMap
.
Les clés de recherche sont mises en cache par httpd jusqu'à ce que
le mtime
(date de modification) du fichier de
correspondances soit modifié, ou que le serveur httpd soit
redémarré, ce qui améliore les performances pour les tables de
correspondances consultées par de nombreuses requêtes.
Lorque le type-map prg
est spécifié, la source est
un chemin du système de fichiers vers un programme exécutable
destiné à effectuer la mise en correspondance. Il peut s'agir d'un
fichier binaire compilé, ou d'un programme en langage interprété
comme Perl ou Python.
Ce programme est lancé une fois au démarrage du serveur HTTP
Apache, puis communique avec le moteur de réécriture via
STDIN
et STDOUT
. En d'autres termes, pour
chaque recherche de correspondance, il reçoit un argument via
STDIN
, et doit renvoyer en guise de réponse une chaîne
terminée par un caractère nouvelle-ligne sur STDOUT
. Si
la recherche de correspondance est infructueuse, le programme doit
l'indiquer en retournant la chaîne de quatre caractères
"NULL
".
Les programmes de réécriture externes ne sont pas lancés s'il
n'ont pas été définis dans un contexte où la directive RewriteEngine
est définie à
on
.
Par défaut, les programmes de réécriture externes s'exécutent sous
l'utilisateur/groupe qui a démarré httpd. Pour en changer, il est possible
sur les systèmes de style Unix de spécifier un autre couple
utilisateur/groupe via le troisième argument de la directive RewriteMap
, et ceci au format
utilisateur:groupe
.
Cette fonctionnalité utilise le mutex rewrite-map
nécessaire à la fiabilité des communications avec le programme. Le
mécanisme de mutex et le fichier verrou peuvent être définis via la
directive Mutex
.
Voici un exemple simple qui remplace tous les tirets par des caractères de soulignement dans l'URI de la requête.
Configuration de la réécriture
RewriteMap d2u "prg:/www/bin/dash2under.pl" apache:apache RewriteRule "-" "${d2u:%{REQUEST_URI}}"
dash2under.pl
#!/usr/bin/perl $| = 1; # Turn off I/O buffering while (<STDIN>) { s/-/_/g; # Remplace tous les tirets par des caractères de soulignement print $_; }
$| = 1;
- La syntaxe sera bien entendu
différente dans
d'autres langages. Si les entrées/sorties sont mises en tampon, httpd va
attendre une sortie, et va par conséquent se bloquer.Lorsque le type-map dbd
ou fastdbd
est
spécifié, la source est une requête SQL SELECT qui reçoit un
argument et renvoie une seule valeur.
Pour que cette requête puisse être exécutée,
mod_dbd
doit être configuré pour attaquer la base
de données concernée.
Ce type-map existe sous deux formes. Avec le type-map
dbd
, la requête est exécutée à chaque demande, tandis
qu'avec le type-map fastdbd
, les recherches dans la
base de données sont mises en cache en interne. fastdbd
est donc plus efficace et donc plus rapide ; par contre, il ne
tiendra pas compte des modifications apportées à la base de données
jusqu'à ce que le serveur soit redémarré.
Si une requête renvoie plusieurs enregistrements, un de ceux-ci sera sélectionné aléatoirement.
RewriteMap ma-requete "fastdbd:SELECT destination FROM rewrite WHERE source = %s"
Le nom de la requête est transmis au pilote de base de données en tant que label pour une requête SQL préparée, et doit donc respecter toutes les règles imposées par votre base de données (comme la sensibilité à la casse).
La directive RewriteMap
peut apparaître
plusieurs fois. Utilisez une directive
RewriteMap
pour chaque fonction de mise en
correspondance pour déclarer son fichier de correspondances.
Bien que l'on ne puisse pas déclarer de fonction
de mise en correspondance dans un contexte de répertoire (fichier
.htaccess
ou section <Directory>
), il est
possible d'utiliser cette fonction dans un tel contexte.