Rappels d’utilisation

Directive RewriteRule

Syntaxe générale de la règle d’écriture :

RewriteRule Modèle Substitution [drapeaux]

Modèle (qui peut être une expression régulière) est comparé à une chaîne de caractère qui dépend du contexte :

  • dans un contexte Virtual Host, il s’agit de la portion de l’URL située entre le nom d’hôte (éventuellement accompagné du port), et la chaîne de paramètres (exemple, pour une requête « https://www.nicolas-petitjean.com/blog/source.html » => « blog/source.html »)
  • dans un contexte de répertoire (sections Directory et fichiers .htaccess), il s’agit d’une partie du chemin. Exemple pour une requête « https://www.nicolas-petitjean.com/blog/source.html » => « blog/source.html ». Par contre si la directive est dans le répertoire « blog », le nom du répertoire est substitué (ce qui donne « source.html »)

Exemple, on veut interdire tous les exécutables :

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

Directive RewriteCond

Si vous voulez comparez avec autre chose que cette portion d’url, utilisez la directive RewriteCond :

RewriteCond chaîne_de_test expression_de_comparaison

Ici chaîne_de_test prend la forme de variables, ce qui permet de tester toutes sortes de choses. expression_de_comparaison peut aussi être une expression régulière. Par exemple, pour savoir si la requête utilise le protocole SSL :

RewriteCond %{HTTPS} off

Ce qui permet par exemple de faire une redirection http vers https proprement :

RewriteCond %{HTTPS} off
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

%{SERVER_NAME} est une variable serveur (voir plus bas pour sa signification).

Une directive RewriteCond ne s’applique qu’à la règle RewriteRule située immédiatement après. Il est possible de cumuler les directives RewriteCond pour une même directive RewriteRule.

Syntaxe « tiret » de réécriture

Une façon simple de ne pas réécrire l’URI (aucune substitution) est d’utiliser la syntaxe « tiret » :

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

Ici on interdit le téléchargement des exécutables. Inutile donc de réécrire quoi que ce soit.

Références arrières

Comme on utilise des expressions régulières avec RewriteRule et RewriteCond, on va pouvoir capturer des portions de chaines pour les réutiliser.

  • référence arrière de condition : %N (1<=N<=9) contient les parenthèses capturantes de la directive RewriteCond précédente. %0 contient la chaine entière (chaîne_de_test donc)
  • références arrières de réécriture : $N (1<=N<=9) contient les parenthèses capturantes de la directive RewriteRule courante. $0 contient la chaine entière (la chaine de caractère comparée à Modèle).

Deux façons d’obtenir la même redirection :

RewriteCond %{REQUEST_URI} category/(.*)$
RewriteRule . /freestyle-blog/?cat=%1 [L,R=301]

RewriteRule ^category/(.*)$ /freestyle-blog/?cat=$1 [L,R=301]

Liste des variables

On peut utiliser certaines variables dans la directive RewriteCond. Il faut utiliser la syntaxe suivante : %{VAR}.

Variable Description Exemple
DOCUMENT_ROOT La racine du serveur (définie par la directive DocumentRoot). /var/www/html/
HTTP_COOKIE Cookies envoyé par le client. 90plan=R3276214363; _gid=GA1.2.1163156300.1539840846; _gat_gtag_UA_12961733_1=1
HTTP_HOST Nom du serveur demandé. www.nicolas-petitjean.com
HTTPS on si la requête utilise https, sinon off. on
HTTP_REFERER Lien référant si existant. Non fiable. www.google.com/?q=fancy
HTTP_USER_AGENT Identifiant du client. Non fiable Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:62.0) Gecko/20100101 Firefox/62.0
QUERY_STRING Paramètres passées dans l’url. ?page=3&order=asc
REQUEST_FILENAME Identique à SCRIPT_FILENAME. /home/nicolas/www/index.php
REQUEST_METHOD La méthode HTTP de la requête entrante. GET, POST, PATCH etc
REQUEST_SCHEME Protocole de la requête. http, https
REQUEST_URI Ressource demandée. /blog/apache
SCRIPT_FILENAME Chemin absolu de la ressource demandée. /home/nicolas/www/index.php
THE_REQUEST La requête complète. GET /index.php HTTP/1.1

Les drapeaux (flags)

Petite liste des drapeaux les plus courants :

Drapeau Description
C|chain Indique que la règle est chainée avec la suivante. Si la règle ne s’appliqe pas, la chaîne s’interrompt.
CO|cookie Crée un cookie quand la règle s’applique. Peu connu mais très efficace. Retrouvez la syntaxe complète sur la doc Apache.
E|env Définit la valeur d’une variable d’environnement si la règle s’applique.

RewriteRule "\.(png|gif|jpg)" "-" [E=image:1]

Notez l’utilisation de la syntaxe « tiret ».

F|forbidden Renvoi un status 403 si la règle s’applique.

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

Notez l’utilisation de la syntaxe « tiret ».

H|handler Spécifie un gestionnaire à utiliser si la règle s’applique. Par exemple, pour utiliser php avec toutes les fichiers portant l’extension php :

RewriteRule "\.php$" "-" [H=application/x-httpd-php]
L|last Si la règle s’applique, aucune autre règle ne sera traitée. En d’autres termes, il s’agit de la dernière redirection.
N|next Recommence le traitement des règles depuis le début. Ce drapeau peut être vu comme un while. Attention donc aux boucles infinies.

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

Depuis Apache 2.4.8, le nombre d’itérations est limité à 32000, sauf mention contraire dans le drapeau :

RewriteRule "(.*)A(.*)" "$1B$2" [N=40000]
NC|nocase Comparasion insensible à la casse. Intéressant pour s’affranchir du problème de majuscules dans les extensions :

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

Depuis Apache 2.4.8, le nombre d’itérations est limité à 32000, sauf mention contraire dans le drapeau :

RewriteRule "(.*)A(.*)" "$1B$2" [N=40000]
R|redirect Envoi une redirection au navigateur. Quasiment toujours employé avec le drapeau L (last) :

RewriteRule ^category/(.*)$ /freestyle-blog/?cat=$0 [L,R=301]
S|skip Permet de sauter des règles si la règle RewriteRule s’applique. Pour sauter deux règles :

RewriteRule "(.*\.(jpg|gif|png))$" "http://images.example.com$1" [S=2]

Références externes