1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
|
<?xml version="1.0" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
<!-- English Revision: 1866233:1906637 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manualpage metafile="intro.xml.meta">
<parentdocument href="./">Rewrite</parentdocument>
<title>Introduction au module Apache mod_rewrite</title>
<summary>
<p>Ce document est un complément à la <a
href="../mod/mod_rewrite.html">documentation de référence</a> du module
<module>mod_rewrite</module>. Il décrit les concepts de base dont la
connaissance est nécessaire pour l'utilisation de
<module>mod_rewrite</module>. D'autres documents entrent d'avantage dans
les détails, mais celui-ci devrait aider le débutant à se mouiller les
pieds.
</p>
</summary>
<seealso><a href="../mod/mod_rewrite.html">Documentation du
module mod_rewrite</a></seealso>
<!-- <seealso><a href="intro.html">Introduction à mod_rewrite</a></seealso> -->
<seealso><a href="remapping.html">Redirection and remise en
correspondance</a></seealso>
<seealso><a href="access.html">Contrôle d'accès</a></seealso>
<seealso><a href="vhosts.html">Serveurs virtuels</a></seealso>
<seealso><a href="proxy.html">Mise en cache</a></seealso>
<seealso><a href="rewritemap.html">Utilisation de RewriteMap</a></seealso>
<seealso><a href="advanced.html">Techniques avancées</a></seealso>
<seealso><a href="avoid.html">Quand ne pas utiliser mod_rewrite</a></seealso>
<section id="introduction"><title>Introduction</title>
<p>Le module Apache <module>mod_rewrite</module> est un module puissant
et sophistiqué qui permet la réécriture des URLs. Grâce à lui, vous
pouvez effectuer quasiment tous les types de réécriture d'URLs dont vous
avez besoin. Il est cependant assez complexe, et peut paraître
intimidant au débutant. Certains ont aussi tendance à traiter les
règles de réécriture comme des incantations magiques, et à les utiliser
sans vraiment comprendre leur manière d'agir.</p>
<p>Ce document a pour ambition d'être suffisamment explicite pour
permettre la compréhension, et non la copie en aveugle, de ce qui suit.
</p>
<p>Gardez à l'esprit que de nombreuses tâches de manipulation d'URLs
courantes n'ont pas besoin de la puissance et de la complexité de
<module>mod_rewrite</module>. Pour les tâches simples, voir
<module>mod_alias</module> et la documentation sur la <a
href="../urlmapping.html">Mise en correspondance des URLs avec le
système de fichiers</a>.</p>
<p>Enfin, avant de procéder, assurez-vous d'avoir configuré le niveau de
journalisation de <module>mod_rewrite</module> à un des niveaux de trace
via la directive <directive module="core">LogLevel</directive>. Bien que
ceci risque de vous submerger sous une énorme quantité d'informations,
le débogage des problèmes avec la configuration de
<module>mod_rewrite</module> est à ce prix car vous verrez alors
exactement comment chaque règle est traitée.</p>
</section>
<section id="regex"><title>Expressions rationnelles</title>
<p>mod_rewrite utilise le vocabulaire des <a
href="http://pcre.org/">Expressions rationnelles compatibles Perl</a>.
Ce document n'a pas pour prétention d'être une référence détaillée des
expressions rationnelles. A cet effet, nous recommandons les <a
href="http://pcre.org/pcre.txt">pages de manuel de PCRE</a>, la <a
href="http://perldoc.perl.org/perlre.html">page de manuel des
expressions rationnelles Perl</a>, et l'ouvrage <a
href="http://shop.oreilly.com/product/9780596528126.do">Mastering
Regular Expressions, by Jeffrey Friedl</a>.</p>
<p>Dans ce document, nous avons pour but de vous fournir suffisamment de
vocabulaire des expressions rationnelles pour vous mettre le pied à
l'étrier, sans être dépassé, en espérant que les directives <directive
module="mod_rewrite">RewriteRule</directive> vous apparaîtront comme des
formules scientifiques, plutôt que comme des incantations magiques.</p>
<section id="regexvocab"><title>Vocabulaire des expressions rationnelles</title>
<p>Vous trouverez dans ce qui suit le minimum à connaître pour être en
mesure d'écrire des expressions rationnelles et des règles <directive
module="mod_rewrite">RewriteRule</directive>. Ceci ne représente
certainement pas un vocabulaire des expressions rationnelles complet,
mais constitue un bon point de départ, et devrait vous aider à
déchiffrer les expressions rationnelles simples, et à écrire vos propres
expressions.</p>
<table>
<tr>
<th>Motif</th>
<th>Signification</th>
<th>Exemple</th>
</tr>
<tr><td><code>.</code></td><td>Correspond à tout caractère unique
</td><td><code>c.t</code> correspondra à <code>cat</code>,
<code>cot</code>, <code>cut</code>, etc.</td></tr>
<tr><td><code>+</code></td><td>Répète le caractère de correspondance
précédent une ou plusieurs fois</td>
<td><code>a+</code> correspond à <code>a</code>, <code>aa</code>,
<code>aaa</code>, etc.</td></tr>
<tr><td><code>*</code></td><td>Répète le caractère de correspondance
précédent zéro ou plusieurs fois</td>
<td><code>a*</code> correspond à tout ce à quoi correspond
<code>a+</code>, mais correspond aussi à la chaîne vide.</td></tr>
<tr><td><code>?</code></td><td>Rend la correspondance optionnelle.</td><td>
<code>colou?r</code> correspondra à <code>color</code> et <code>colour</code>.</td>
</tr>
<tr><td><code>^</code></td><td>Appelé ancrage, correspond au début de la
chaîne</td>
<td><code>^a</code> correspond à une chaîne qui commence par
<code>a</code></td></tr>
<tr><td><code>$</code></td><td>L'autre ancrage, correspond à la fin de
la chaîne.</td>
<td><code>a$</code> correspond à une chaîne qui se termine par
<code>a</code>.</td></tr>
<tr><td><code>( )</code></td><td>Regroupe plusieurs caractères en une
seule entité, et conserve une correspondance à des fins d'utilisation
dans une référence arrière.</td>
<td><code>(ab)+</code>
correspond à <code>ababab</code> - à savoir, le <code>+</code>
s'applique au groupe.
Pour plus de détails sur les références arrières, voir <a
href="#InternalBackRefs">ci-dessous</a>.</td></tr>
<tr><td><code>[ ]</code></td><td>Une classe de caractères - correspond à
un des caractères de la classe</td>
<td><code>c[uoa]t</code> correspond à <code>cut</code>,
<code>cot</code> ou <code>cat</code>.</td></tr>
<tr><td><code>[^ ]</code></td><td>Négation de la classe de caractères -
correspond à tout caractère ne faisant pas partie de la classe</td>
<td><code>c[^/]t</code> correspond à <code>cat</code> ou
<code>c=t</code> mais pas à <code>c/t</code></td></tr>
</table>
<p>Avec <module>mod_rewrite</module>, le caractère <code>!</code> peut
préfixer une expression rationnelle afin d'en exprimer la négation.
Autrement dit, une chaîne ne correspondra que si elle ne correspond pas
à l'expression située après le <code>!</code>.</p>
</section>
<section id="InternalBackRefs"><title>Disponibilité des références
arrières dans les expressions rationnelles</title>
<p>Vous devez vous souvenir d'une chose importante : chaque fois
que vous utilisez des parenthèses dans un <em>Modèle</em> ou dans
un des <em>modèles de conditions</em>, des références arrières
sont créées en interne et peuvent être rappelées via les chaînes
<code>$N</code> et <code>%N</code> (voir ci-dessous). Ces
références sont disponibles lors de la
création de la chaîne de substitution d'une directive
<directive module="mod_rewrite">RewriteRule</directive> ou de la
chaîne de test d'une directive <directive
module="mod_rewrite">RewriteCond</directive>.</p>
<p>Les captures dans les modèles de directives <directive
module="mod_rewrite">RewriteRule</directive> sont paradoxalement
disponibles dans toutes les directives <directive
module="mod_rewrite">RewriteCond</directive> qui précèdent, car
les expressions des directives <directive
module="mod_rewrite">RewriteRule</directive> sont évaluées avant
les conditions individuelles.</p>
<p>La figure 1 montre à quels endroits les
références arrières sont suceptibles
d'être développées, et illustre le flux des comparaisons
effectuées par les règles RewriteRule et
RewriteCond. Dans les chapitres suivants, nous examinerons comment
utiliser ces références arrières, donc ne vous affolez pas si
elles vous paraissent un peu exotiques au premier abord.</p>
<p class="figure">
<img src="../images/rewrite_backreferences.png"
alt="Flux des comparaisons effectuées par les règles RewriteRule
et RewriteCond" /><br />
<dfn>Figure 1 :</dfn> Le cheminement d'une référence arrière à
travers une règle.<br />
Dans cet exemple, une requête pour <code>/test/1234</code> serait
transformée en
<code>/admin.foo?page=test&id=1234&host=admin.example.com</code>.
</p>
</section>
</section>
<section id="rewriterule"><title>Les bases des règles de réécriture</title>
<p>Une règle de réécriture <directive
module="mod_rewrite">RewriteRule</directive> est constituée de trois
arguments séparés par des espaces. Les arguments sont :</p>
<ol>
<li><var>Modèle</var>: le modèle des URLs auxquelles la règle doit
s'appliquer;</li>
<li><var>Substitution</var>: vers quoi la requête correspondante doit être
transformée;</li>
<li><var>[drapeaux]</var>: options affectant la requête réécrite.</li>
</ol>
<p>Le <var>Modèle</var> est une <a href="#regex">expression
rationnelle</a>. Au sein de la première règle de réécriture, ou jusqu'à
ce qu'une substitution survienne, elle est comparée au chemin de
l'URL de la requête entrante (la
partie située après le nom d'hôte mais avant tout point d'interrogation
qui indique le début d'une chaîne de paramètres de
requête) ou, dans un contexte de répertoire, au chemin de la
requête relativement au répertoire pour lequel la
règle est définie. Lorsqu'une substitution a eu lieu, les
règles suivantes effectuent leurs comparaisons par rapport à la valeur
substituée.</p>
<p class="figure">
<img src="../images/syntax_rewriterule.png"
alt="Syntaxe de la directive RewriteRule" /><br />
<dfn>Figure 2 :</dfn> Syntaxe de la directive RewriteRule.
</p>
<p>La chaîne de <var>Substitution</var> peut, quant à elle, être de
trois types :</p>
<dl>
<dt>Un chemin complet du système de fichiers vers une ressource</dt>
<dd>
<highlight language="config">
RewriteRule "^/jeux" "/usr/local/jeux/web"
</highlight>
<p>Ceci peut faire correspondre une requête à toute localisation voulue de
votre système de fichiers, un peu comme la directive <directive
module="mod_alias">Alias</directive>.</p>
</dd>
<dt>Un chemin web vers une ressource</dt>
<dd>
<highlight language="config">
RewriteRule "^/foo$" "/bar"
</highlight>
<p>Si la directive <directive module="core">DocumentRoot</directive> a
pour valeur <code>/usr/local/apache2/htdocs</code>, cette règle va faire
correspondre les requêtes pour <code>http://example.com/foo</code> au
chemin <code>/usr/local/apache2/htdocs/bar</code>.</p>
</dd>
<dt>Une URL absolue</dt>
<dd>
<highlight language="config">
RewriteRule "^/produits/vues$" "http://site2.example.com/voirproduits.html" [R]
</highlight>
<p>Ceci informe le client qu'il doit effectuer une nouvelle requête vers
l'URL spécifiée.</p>
</dd>
</dl>
<p>La chaîne de <var>Substitution</var> peut aussi contenir des
<em>références arrières</em> vers des parties du chemin d'URL entrant
correspondant au <var>Modèle</var>. Considérons ce qui suit :</p>
<highlight language="config">
RewriteRule "^/produits/(.*)/view$" "/var/web/produitsdb/$1"
</highlight>
<p>La variable <code>$1</code> sera remplacée par tout texte
correspondant à l'expression située entre les parenthèses dans le
<var>Modèle</var>. Par exemple, une requête pour
<code>http://example.com/produits/r14df/vue</code> correspondra au
chemin <code>/var/web/produitsdb/r14df</code>.</p>
<p>S'il y a plus d'une expression entre parenthèses, elle seront
accessibles selon leur ordre d'apparition via les variables
<code>$1</code>, <code>$2</code>, <code>$3</code>, etc...</p>
</section>
<section id="flags"><title>Drapeaux de réécriture</title>
<p>Le comportement d'une règle <directive
module="mod_rewrite">RewriteRule</directive> peut être modifié par la
présence d'un ou plusieurs drapeaux en fin de règle. Par exemple, les
conditions de correspondance d'une règle peuvent être rendues
insensibles à la casse par la présence du drapeau <code>[NC]</code> :
</p>
<highlight language="config">
RewriteRule "^puppy.html" "petitchien.html" [NC]
</highlight>
<p>Pour une liste des drapeaux disponibles, leurs significations, et des
exemples, voir le document <a href="flags.html">Drapeaux de
réécriture</a>.</p>
</section>
<section id="rewritecond"><title>Conditions de réécriture</title>
<p>Il est possible d'utiliser une ou plusieurs directives <directive
module="mod_rewrite">RewriteCond</directive> pour restreindre les types
de requêtes auxquelles devra s'appliquer la règle <directive
module="mod_rewrite">RewriteRule</directive> suivante. Le premier
argument est une variable décrivant une caractéristique de la requête,
le second argument est une <a href="#regex">expression rationnelle</a>
qui doit correspondre à la variable, et un troisième argument optionnel
est une liste de drapeaux qui modifient la manière dont la
correspondance est évaluée.</p>
<p class="figure">
<img src="../images/syntax_rewritecond.png"
alt="Syntaxe de la directive RewriteCond" /><br />
<dfn>Figure 3 :</dfn> Syntaxe de la directive RewriteCond
</p>
<p>Par exemple, pour renvoyer toutes les requêtes en provenance d'une
certaine tranche d'adresses IP vers un autre serveur, vous pouvez
utiliser :</p>
<highlight language="config">
RewriteCond "%{REMOTE_ADDR}" "^10\.2\."
RewriteRule "(.*)" "http://intranet.example.com$1"
</highlight>
<p>Si vous spécifiez plus d'une directive <directive
module="mod_rewrite">RewriteCond</directive>, ces directives
doivent toutes être satisfaites pour que la règle <directive
module="mod_rewrite">RewriteRule</directive> suivante s'applique. Par exemple,
pour interdire les requêtes qui contiennent le mot "hack" dans la chaîne
de requête, sauf si elles contiennent aussi un cookie contenant le mot
"go", vous pouvez utiliser :</p>
<highlight language="config">
RewriteCond "%{QUERY_STRING}" "hack"
RewriteCond "%{HTTP_COOKIE}" "!go"
RewriteRule "." "-" [F]
</highlight>
<p>Notez que le point d'exclamation indique une correspondance négative
; ainsi, la règle n'est appliquée que si le cookie ne contient pas "go"</p>
<p>Les correspondances dans les expressions rationnelles contenues dans
les directives <directive module="mod_rewrite">RewriteCond</directive>
peuvent constituer des parties de la chaîne de <var>Substitution</var>
de la règle <directive module="mod_rewrite">RewriteRule</directive> via
les variables <code>%1</code>, <code>%2</code>, etc... Par
exemple, ce qui suit va diriger la requête vers un répertoire différent
en fonction du nom d'hôte utilisé pour accéder au site :</p>
<highlight language="config">
RewriteCond "%{HTTP_HOST}" "(.*)"
RewriteRule "^/(.*)" "/sites/%1/$1"
</highlight>
<p>Si la requête concernait <code>http://example.com/foo/bar</code>,
alors <code>%1</code> contiendrait <code>example.com</code> et
<code>$1</code> contiendrait <code>foo/bar</code>.</p>
</section>
<section id="rewritemap"><title>Tables de réécriture</title>
<p>La directive <directive module="mod_rewrite">RewriteMap</directive>
permet en quelque sorte de faire appel à une fonction externe pour
effectuer la réécriture à votre place. Tout ceci est décrit plus en
détails dans la <a href="rewritemap.html">Documentation
supplémentaire sur RewriteMap</a>.</p>
</section>
<section id="htaccess"><title>Fichiers .htaccess</title>
<p>La réécriture est en général définie au niveau de la configuration du
serveur principal (en dehors de toute section <directive type="section"
module="core">Directory</directive>) ou dans une section <directive
type="section" module="core">VirtualHost</directive>. Il s'agit là de la
manière la plus simple de mettre en oeuvre la réécriture et nous la
recommandons. Il est possible, cependant, de mettre en oeuvre la
réécriture au sein d'une section <directive type="section"
module="core">Directory</directive> ou d'un fichier <a
href="../howto/htaccess.html"><code>.htaccess</code></a> ; ce type de
configuration est cependant plus complexe. Cette technique est appelée
réécriture par répertoire.</p>
<p>La principale différence avec les réécritures au niveau du serveur réside
dans le fait que le préfixe du chemin du répertoire contenant le fichier
<code>.htaccess</code> est supprimé avant la mise en correspondance dans
la règle <directive module="mod_rewrite">RewriteRule</directive>. De
plus, on doit utiliser la directive <directive
module="mod_rewrite">RewriteBase</directive> pour s'assurer que la
requête est correctement mise en correspondance.</p>
</section>
</manualpage>
|