Serveur Apache HTTP Version 2.4
Ce document est un compl�ment � la Documentation de r�f�rence de
mod_rewrite
. Il montre comment utiliser
mod_rewrite
pour rediriger et remettre en
correspondance une requ�te. Il contient de
nombreux exemples d'utilisation courante de mod_rewrite avec une
description d�taill�e de leur fonctionnement.
DocumentRoot
Supposons que nous ayons r�cemment renomm� la page
foo.html
en bar.html
, et voulions
maintenant que l'ancienne URL soit toujours valide � des fins
de compatibilit� ascendante. En fait, on voudrait que le
changement de nom soit transparent aux utilisateurs de
l'ancienne URL.
On r��crit l'ancienne URL en interne vers la nouvelle via la r�gle suivante :
RewriteEngine on RewriteRule ^/foo\.html$ /bar.html [PT]
Supposons toujours que nous ayons r�cemment renomm� la page
foo.html
en bar.html
, et voulions
maintenant que l'ancienne URL soit toujours valide � des fins
de compatibilit� ascendante. En revanche, nous voulons cette
fois que la nouvelle URL soit sugg�r�e aux utilisateurs de
l'ancienne URL, c'est � dire que l'adresse vue depuis leur
navigateur doit �galement �tre modifi�e.
On force une redirection HTTP vers la nouvelle URL, ce qui entra�ne une modification de celle du navigateur et aussi de ce que voit l'utilisateur :
RewriteEngine on RewriteRule ^foo\.html$ bar.html [R]
Dans l'exemple interne, on a utilis� mod_rewrite afin de dissimuler la redirection au client. Dans cet exemple, en revanche, on aurait pu se contenter d'une directive Redirect :
Redirect /foo.html /bar.html
Si une ressource a �t� d�plac�e vers un autre serveur, vous pouvez faire en sorte que les URLs de l'ancien serveur continuent de fonctionner pendant un certain temps, afin de laisser au utilisateurs le temps de modifier leurs favoris.
Vous pouvez utiliser mod_rewrite
pour
rediriger ces URLs vers le nouveau serveur, mais vous pouvez aussi
utiliser les directives Redirect ou RedirectMatch.
#Avec mod_rewrite RewriteEngine on RewriteRule ^/docs/(.+) http://nouveau.example.com/docs/$1 [R,L]
#Avec RedirectMatch RedirectMatch ^/docs/(.*) http://nouveau.example.com/docs/$1
#Avec Redirect Redirect /docs/ http://nouveau.example.com/docs/
Comment transformer une page statique foo.html
en sa variante dynamique foo.cgi
de mani�re
transparente, c'est � dire sans en avertir le
navigateur/utilisateur.
On r��crit simplement l'URL en script CGI et force le
gestionnaire de contenu � cgi-script de fa�on
� ce que le script s'ex�cute en tant que programme CGI.
Ainsi, une requ�te vers /~quux/foo.html
conduit
en interne � l'invocation de
/~quux/foo.cgi
.
RewriteEngine on RewriteBase /~quux/ RewriteRule ^foo\.html$ foo.cgi � [H=cgi-script]
Comment conf�rer une compatibilit� ascendante aux URLs
(existant encore virtuellement) apr�s avoir migr�
document.YYYY
vers document.XXXX
,
c'est � dire apr�s avoir par exemple traduit un lot de
fichiers .html
en fichiers .php
?
On r��crit simplement le nom du fichier en son nom de base et v�rifie s'il existe aussi avec la nouvelle extension. Si c'est le cas, on utilise ce nom, sinon on r��crit l'URL sous sa forme originale.
# jeu de r�gles assurant une compatibilit� ascendante en r��crivant
# document.html en document.php si et seulement si document.php
# existe <Directory /var/www/htdocs> RewriteEngine on RewriteBase /var/www/htdocs RewriteCond $1.php -f RewriteCond $1.html !-f RewriteRule ^(.*).html$ $1.php </Directory>
Cet exemple utilise une fonctionnalit� souvent m�connue de
mod_rewrite, en tirant avantage de l'ordre d'ex�cution du jeu de
r�gles. En particulier, mod_rewrite �value la partie gauche des
r�gles de r��criture avant d'�valuer les directives RewriteCond. En
cons�quence, $1 est d�j� d�fini au moment o� les directives
RewriteCond sont �valu�es. Ceci nous permet de tester l'existence du
fichier original (document.html
) et du fichier cible
(document.php
) en utilisant le m�me nom de base.
Ce jeu de r�gles est con�u pour une utilisation dans un contexte
de r�pertoire (au sein d'une section <Directory> ou d'un
fichier .htaccess), de fa�on � ce que les v�rifications
-f
effectuent leurs recherches dans le bon r�pertoire.
Vous serez peut-�tre amen� � d�finir une directive RewriteBase
pour sp�cifier le
r�pertoire de base � partir duquel vous travaillez.
Pour y parvenir, il vaut mieux se passer de mod_rewrite, et utiliser
plut�t la directive Redirect
dans
une section de serveur virtuel pour le/les noms d'h�te non canoniques.
<VirtualHost *:80> ServerName undesired.example.com ServerAlias example.com notthis.example.com Redirect / http://www.example.com/ </VirtualHost> <VirtualHost *:80> ServerName www.example.com </VirtualHost>
Vous pouvez aussi utiliser la directive <If>
:
<If "%{HTTP_HOST} != 'www.example.com'"> Redirect / http://www.example.com/ </If>
Ou, par exemple, pour rediriger une portion de votre site vers HTTPS :
<If "%{SERVER_PROTOCOL} != 'HTTPS'"> Redirect /admin/ https://www.example.com/admin/ </If>
Si, pour une raison particuli�re, vous voulez tout de m�me utiliser
mod_rewrite
- dans le cas, par exemple, o� vous avez besoin
d'un jeu plus important de r�gles de r��critures - vous pouvez utiliser
la recette suivante :
Pour les sites �coutant sur un port autre que 80:
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC] RewriteCond %{HTTP_HOST} !^$ RewriteCond %{SERVER_PORT} !^80$ RewriteRule ^/?(.*) http://www.example.com:%{SERVER_PORT}/$1 [L,R,NE]
Et pour un site �coutant sur le port 80
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/?(.*) http://www.example.com/$1 [L,R,NE]
Si vous souhaitez que cette r�gle s'applique � tous les noms de domaine - en d'autres termes, si vous voulez rediriger example.com vers www.example.com pour toutes les valeurs possibles de example.com, vous pouvez utiliser le jeu de r�gles suivants :
RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/?(.*) http://www.%{HTTP_HOST}/$1 [L,R,NE]
Vous pouvez utiliser ce jeu de r�gles aussi bien dans le fichier
de configuration de votre serveur principal que dans un fichier
.htaccess
plac� dans le r�pertoire d�fini par la
directive DocumentRoot
du serveur.
Une ressource peut exister dans plusieurs r�pertoires, et nous voulons rechercher cette ressource dans ces r�pertoires lorsqu'elle fait l'objet d'une requ�te. Il est possible que nous ayons r�cemment r�organis� la structure de notre site en r�partissant son contenu dans plusieurs r�pertoires.
Le jeu de r�gles suivant recherche la ressource dans deux r�pertoires, et s'il ne la trouve dans aucun des deux, il tentera simplement de la servir � partir de l'adresse fournie dans la requ�te.
RewriteEngine on # on cherche tout d'abord dans dir1/... # ... et si on trouve, on est content et on arr�te : RewriteCond %{DOCUMENT_ROOT}/dir1/%{REQUEST_URI} -f RewriteRule ^(.+) %{DOCUMENT_ROOT}/dir1/$1 [L] # on cherche ensuite dans dir2/... # ... et si on trouve, on est content et on arr�te : RewriteCond %{DOCUMENT_ROOT}/dir2/%{REQUEST_URI} -f RewriteRule ^(.+) %{DOCUMENT_ROOT}/dir2/$1 [L] # sinon, on continue la recherche avec d'autres directives Alias # ou ScriptAlias, etc... RewriteRule ^ - [PT]
Notre site web poss�de de nombreux miroirs, et nous voulons rediriger les utilisateurs vers celui qui se situe dans le pays o� ils se trouvent.
En consultant le nom d'h�te du client demandeur, on d�termine le pays dans lequel il se trouve. S'il est impossible d'effectuer une recherche sur leur adresse IP, on se rabat sur un serveur par d�faut.
Nous allons utiliser une directive RewriteMap
afin de construire une
liste des serveurs que nous voulons utiliser.
HostnameLookups on RewriteEngine on RewriteMap multiplex txt:/path/to/map.mirrors RewriteCond %{REMOTE_HOST} ([a-z]+)$ [NC] RewriteRule ^/(.*)$ ${multiplex:%1|http://www.example.com/}$1 [R,L]
## liste_miroirs -- Table de correspondance pays - serveurs
de http://www.exemple.de/
uk http://www.exemple.uk/
com http://www.example.com/
##EOF##
on
de la directive HostNameLookups
, ce qui peut induire une
baisse de performance significative.La directive RewriteCond
extrait la derni�re
partie du nom d'h�te du client demandeur - le code du pays - et la
r�gle de r��criture qui suit utilise cette valeur pour rechercher le
serveur miroir appropri� dans le fichier de correspondances.
Nous voulons fournir des contenus diff�rents en fonction du navigateur (user-agent) qui effectue la requ�te.
Nous devons d�terminer quel contenu servir, en nous basant
sur l'en-t�te HTTP "User-Agent". La
configuration suivante effectue ceci : si l'en-t�te HTTP
"User-Agent" commence par "Mozilla/3", le nom de la page
foo.html
est r��crit en foo.NS.html
et la r��criture s'arr�te. Si le navigateur est "Lynx" ou
"Mozilla" version 1 ou 2, l'URL devient
foo.20.html
. Tous les autres navigateurs
re�oivent la page foo.32.html
. Tout ceci est
effectu� par le jeu de r�gles suivant :
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]
Sur certains serveurs, une ressource peut poss�der plusieurs URLs. Il y a en g�n�ral les URLs canoniques (celles qui sont r�ellement distribu�es et utilis�es), et celles qui correspondent � des raccourcis, les URLs internes, etc... Quelle que soit l'adresse que l'utilisateur fournit dans la requ�te, il devrait finalement voir l'URL canonique dans la barre d'adresse de son navigateur.
Nous effectuons une redirection HTTP externe pour toutes les
URLs non canoniques afin de les corriger dans la barre d'adresse
du navigateur, et ceci pour toutes les requ�tes futures. Dans le
jeu de r�gles suivant, nous rempla�ons /matous
et
/minettes
par le canonique /chats
.
RewriteRule ^/(matous|minettes)/(.*) /chats/$2 [R]
RedirectMatch ^/(matous|minettes)/(.*) /chats/$2
DocumentRoot
En g�n�ral, le r�pertoire DocumentRoot
du serveur web correspond � l'URL
"/
". Ce r�pertoire ne contient cependant pas forc�ment des
ressources de premi�re importance pour l'utilisateur. Par exemple, vous
pr�f�rerez peut-�tre que le r�pertoire d'accueil d'un visiteur acc�dant
pour la premi�re fois � votre site soit un r�pertoire particulier
/a-propos-de/
. Pour y parvenir, utilisez le jeu de r�gles
suivant :
On redirige l'URL /
vers
/a-propos-de/
:
RewriteEngine on RewriteRule ^/$ /a-propos-de/ [R]
Notez que l'on peut aussi y parvenir en utilisant la directive
RedirectMatch
:
RedirectMatch ^/$ http://example.com/a-propos-de/
Notez aussi que cet exemple ne r��crit que l'URL racine. En d'autres
termes, il r��crit une requ�te pour http://example.com/
,
mais pas pour une requ�te http://example.com/page.html
. Si
vous avez effectivement modifi� la racine de vos documents - c'est � dire
si tous vos contenus se trouvent dans un
sous-r�pertoire, il est largement pr�f�rable de modifier simplement
votre directive DocumentRoot
, ou de
d�placer l'ensemble du contenu vers le r�pertoire sup�rieur, plut�t que
de r��crire les URLs.
Depuis la version 2.2.16, vous pouvez y parvenir via la directive
FallbackResource
:
<Directory /var/www/my_blog> FallbackResource index.php </Directory>
Cependant, si vos besoins �taient plus complexes, vous pouviez, dans les versions plus anciennes d'Apache, utiliser un jeu de r�gles du style :
<Directory /var/www/my_blog> RewriteBase /my_blog RewriteCond /var/www/my_blog/%{REQUEST_FILENAME} !-f RewriteCond /var/www/my_blog/%{REQUEST_FILENAME} !-d RewriteRule ^ index.php [PT] </Directory>
D'autre part, si vous voulez transmettre l'URI de la requ�te en tant que cha�ne de param�tres � index.php, vous pouvez remplacer cette r�gle de r��criture par :
RewriteRule (.*) index.php?$1 [PT,QSA]
Notez que l'on peut utiliser ces jeux de r�gles aussi bien dans un
fichier .htaccess
que dans une section
<Directory>.