]> granicus.if.org Git - apache/blob - docs/manual/mod/mod_lua.xml.fr
Rebuild
[apache] / docs / manual / mod / mod_lua.xml.fr
1 <?xml version="1.0"?>
2 <!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
4 <!-- English Revision: 1570528:1576894 (outdated) -->
5 <!-- French translation : Lucien GENTIS -->
6 <!-- Reviewed by : Vincent Deffontaines -->
7
8 <!--
9  Licensed to the Apache Software Foundation (ASF) under one or more
10  contributor license agreements.  See the NOTICE file distributed with
11  this work for additional information regarding copyright ownership.
12  The ASF licenses this file to You under the Apache License, Version 2.0
13  (the "License"); you may not use this file except in compliance with
14  the License.  You may obtain a copy of the License at
15
16      http://www.apache.org/licenses/LICENSE-2.0
17
18  Unless required by applicable law or agreed to in writing, software
19  distributed under the License is distributed on an "AS IS" BASIS,
20  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  See the License for the specific language governing permissions and
22  limitations under the License.
23 -->
24
25 <modulesynopsis metafile="mod_lua.xml.meta">
26
27 <name>mod_lua</name>
28
29 <description>Fournit des points d'entr&eacute;e Lua dans diff&eacute;rentes parties du
30 traitement des requ&ecirc;tes httpd</description>
31 <status>Experimental</status>
32 <sourcefile>mod_lua.c</sourcefile>
33 <identifier>lua_module</identifier>
34 <compatibility>versions 2.3 et sup&eacute;rieures</compatibility>
35
36 <summary>
37 <p>Ce module permet d'ajouter au serveur des extensions sous forme de
38 scripts &eacute;crits dans le langage de programmation Lua.
39 <module>mod_lua</module> fournit de nombreuses extensions
40 (hooks) disponibles avec les modules natifs du serveur HTTP Apache,
41 comme les associations de requ&ecirc;tes &agrave; des fichiers, la g&eacute;n&eacute;ration de
42 r&eacute;ponses dynamiques, le contr&ocirc;le d'acc&egrave;s, l'authentification et
43 l'autorisation.</p>
44
45 <p>Vous trouverez davantage d'informations &agrave; propos du langage de
46 programmation Lua sur <a href="http://www.lua.org/">le site web de
47 Lua</a>.</p>
48
49 <note><code>mod_lua</code> est encore au stade exp&eacute;rimental. Son mode
50 d'utilisation et son comportement pourront changer &agrave; tout moment jusqu'&agrave;
51 ce qu'il passe au stade stable, et ce m&ecirc;me entre deux versions stables
52 2.4.x. N'oublez pas de consulter le fichier CHANGES avant toute mise &agrave;
53 jour.</note>
54
55 <note type="warning"><title>Avertissement</title>
56 <p>Ce module poss&egrave;de une grande capacit&eacute; d'action sur le fonctrionnement
57 de httpd, ce qui lui conf&egrave;re une grande puissance, mais peut aussi
58 induire un risque de s&eacute;curit&eacute;. Il est d&eacute;conseill&eacute; d'utiliser ce module
59 sur un serveur partag&eacute; avec des utilisateurs auxquels vous ne pouvez pas
60 accorder une confiance absolue, car il peut permettre de modifier le
61 fonctionnement interne de httpd.</p>
62 </note>
63
64 </summary>
65
66 <section id="basicconf"><title>Configuration de base</title>
67
68 <p>La directive de base pour le chargement du module est</p>
69
70 <highlight language="config">
71     LoadModule lua_module modules/mod_lua.so
72 </highlight>
73
74 <p>
75 <code>mod_lua</code> fournit un gestionnaire nomm&eacute;
76 <code>lua-script</code> qui peut &ecirc;tre utilis&eacute; avec une directive
77 <code>AddHandler</code> :</p>
78
79 <highlight language="config">
80 AddHandler lua-script .lua
81 </highlight>
82
83 <p>
84 Ceci aura pour effet de faire traiter les requ&ecirc;tes pour les fichiers
85 dont l'extension est <code>.lua</code> par <code>mod_lua</code> en
86 invoquant cette fonction de <code>gestion</code> de fichier.
87 </p>
88
89 <p>Pour plus de d&eacute;tails, voir la directive
90 <directive>LuaMapHandler</directive>.
91  </p>
92 </section>
93
94 <section id="writinghandlers"><title>Ecrire des gestionnaires</title>
95 <p>Dans l'API du serveur HTTP Apache, un gestionnaire est une sorte de
96 point d'accroche (hook) sp&eacute;cifique responsable de la g&eacute;n&eacute;ration de la
97 r&eacute;ponse. <module>mod_proxy</module>, <module>mod_cgi</module> et
98 <module>mod_status</module> sont des exemples de modules comportant un
99 gestionnaire.</p>
100
101 <p><code>mod_lua</code> cherche toujours &agrave; invoquer une fonction Lua pour le
102 gestionnaire, plut&ocirc;t que de simplement &eacute;valuer le corps d'un script dans
103 le style de CGI. Une fonction de gestionnaire se pr&eacute;sente comme suit :</p>
104
105
106 <highlight language="lua">
107 <strong>example.lua</strong><br/>
108 -- exemple de gestionnaire
109
110 require "string"
111
112 --[[
113      Il s'agit du nom de m&eacute;thode par d&eacute;faut pour les gestionnaires Lua ;
114      voir les noms de fonctions optionnels dans la directive
115      LuaMapHandler pour choisir un point d'entr&eacute;e diff&eacute;rent.
116 --]]
117 function handle(r)
118     r.content_type = "text/plain"
119
120     if r.method == 'GET' then
121         r:puts("Hello Lua World!\n")
122         for k, v in pairs( r:parseargs() ) do
123             r:puts( string.format("%s: %s\n", k, v) )
124         end
125     elseif r.method == 'POST' then
126         r:puts("Hello Lua World!\n")
127         for k, v in pairs( r:parsebody() ) do
128             r:puts( string.format("%s: %s\n", k, v) )
129         end
130     else
131     elseif r.method == 'PUT' then
132 -- message d'erreur personnalis&eacute;
133         r:puts("Unsupported HTTP method " .. r.method)
134         r.status = 405
135         return apache2.ok
136     else
137 -- message d'erreur ErrorDocument
138         return 501
139     end
140     return apache2.OK
141 end
142 </highlight>
143
144 <p>
145 Ce gestionnaire se contente d'afficher les arguments cod&eacute;s d'un uri ou
146 d'un formulaire dans un page au format texte.
147 </p>
148
149 <p>
150 Cela signifie que vous pouvez (et &ecirc;tes encourag&eacute; &agrave;) avoir plusieurs
151 gestionnaires (ou points d'entr&eacute;e, ou filtres) dans le m&ecirc;me script.
152 </p>
153
154 </section>
155 <section id="writingauthzproviders">
156 <title>Ecriture de fournisseurs d'autorisation</title>
157
158 <p><module>mod_authz_core</module> fournit une interface d'autorisation
159 de haut niveau bien plus facile &agrave; utiliser que dans les hooks
160 correspondants. Le premier argument de la directive <directive
161 module="mod_authz_core">Require</directive> permet de sp&eacute;cifier le
162 fournisseur d'autorisation &agrave; utiliser. Pour chaque directive <directive
163 module="mod_authz_core">Require</directive>,
164 <module>mod_authz_core</module> appellera le fournisseur d'autorisation
165 sp&eacute;cifi&eacute;, le reste de la ligne constituant les param&egrave;tres. Le
166 fournisseur consid&eacute;r&eacute; va alors v&eacute;rifier les autorisations et fournir le
167 r&eacute;sultat dans une valeur de retour.</p>
168
169 <p>En g&eacute;n&eacute;ral, le fournisseur authz est appel&eacute; avant l'authentification.
170 S'il doit conna&icirc;tre le nom d'utilisateur authentifi&eacute; (ou si
171 l'utilisateur est appel&eacute; &agrave; &ecirc;tre authentifi&eacute;), le fournisseur doit
172 renvoyer <code>apache2.AUTHZ_DENIED_NO_USER</code>, ce qui va
173 d&eacute;clancher le processus d'authentification et un deuxi&egrave;me appel du
174 fournisseur authz.</p>
175
176 <p>La fonction du fournisseur authz ci-dessous accepte deux arguments,
177 une adresse IP et un nom d'utilisateur. Elle autorise l'acc&egrave;s dans le
178 cas o&ugrave; la requ&ecirc;te provient de l'adresse IP sp&eacute;cifi&eacute;e, ou si
179 l'utilisateur authentifi&eacute; correspond au second argument :</p>
180
181 <highlight language="lua">
182 <strong>authz_provider.lua</strong><br/>
183
184 require 'apache2'
185
186 function authz_check_foo(r, ip, user)
187     if r.useragent_ip == ip then
188         return apache2.AUTHZ_GRANTED
189     elseif r.user == nil then
190         return apache2.AUTHZ_DENIED_NO_USER
191     elseif r.user == user then
192         return apache2.AUTHZ_GRANTED
193     else
194         return apache2.AUTHZ_DENIED
195     end
196 end
197 </highlight>
198
199 <p>La configuration suivante enregistre cette fonction en tant que
200 fournisseur <code>foo</code>, et la configure por l'URL <code>/</code> :</p>
201 <highlight language="config">
202 LuaAuthzProvider foo authz_provider.lua authz_check_foo
203 &lt;Location /&gt;
204   Require foo 10.1.2.3 john_doe
205 &lt;/Location&gt;
206 </highlight>
207
208 </section>
209
210 <section id="writinghooks"><title>Ecriture de fonctions d'accroche
211 (hooks)</title>
212
213 <p>Les fonctions d'accroche d&eacute;terminent la mani&egrave;re dont les modules (et
214 les scripts Lua) participent au traitement des requ&ecirc;tes. Chaque type
215 d'accroche propos&eacute; par le serveur a un r&ocirc;le sp&eacute;cifique, comme
216 l'association de requ&ecirc;tes au syst&egrave;me de fichiers, le contr&ocirc;le d'acc&egrave;s,
217 ou la d&eacute;finition de types MIME : </p>
218
219 <table border="1" style="zebra">
220     <tr>
221         <th>Phase d'accroche</th>
222         <th>Directive mod_lua</th>
223         <th>Description</th>
224     </tr>
225     <tr>
226         <td>Gestionnaire rapide</td>
227         <td><directive module="mod_lua">LuaQuickHandler</directive></td>
228         <td>Il s'agit de la premi&egrave;re accroche appel&eacute;e lorsqu'une requ&ecirc;te
229         a &eacute;t&eacute; associ&eacute;e &agrave; un serveur ou un serveur virtuel.</td>
230     </tr>
231     <tr>
232         <td>Phase de traduction</td>
233         <td><directive module="mod_lua">LuaHookTranslateName</directive></td>
234         <td>Cette phase traduit l'URI de la requ&ecirc;te en nom de fichier
235         sur le syst&egrave;me. Ce sont des modules comme
236         <module>mod_alias</module> et <module>mod_rewrite</module> qui
237         interviennent au cours de cette phase.</td>
238     </tr>
239     <tr>
240         <td>Choix du lieu de stockage de la ressource</td>
241         <td><directive module="mod_lua">LuaHookMapToStorage</directive></td>
242         <td>Cette phase d&eacute;finit le lieu de stockage de la ressource :
243         physique, en cache ou externe/mandat&eacute;. Elle est assur&eacute;e par les
244         modules de mandat ou de mise en cache.</td>
245     </tr>
246     <tr>
247         <td>Autorisation d'acc&egrave;s</td>
248         <td><directive module="mod_lua">LuaHookAccessChecker</directive></td>
249         <td>Cette phase v&eacute;rifie si un client a l'autorisation d'acc&egrave;s &agrave;
250         la ressource. Elle s'ex&eacute;cute avant l'authentification de
251         l'utisateur ; il faut donc &ecirc;tre prudent.
252         </td>
253     </tr>
254     <tr>
255         <td>V&eacute;rification de l'identifiant utilisateur</td>
256         <td><directive module="mod_lua">LuaHookCheckUserID</directive></td>
257         <td>Cette phase v&eacute;rifie l'identifiant de l'utilisateur ayant
258         fait l'objet d'une n&eacute;gociation.</td>
259     </tr>
260     <tr>
261         <td>V&eacute;rification de l'autorisation d'acc&egrave;s</td>
262         <td><directive module="mod_lua">LuaHookAuthChecker</directive>
263         ou
264             <directive module="mod_lua">LuaAuthzProvider</directive></td>
265         <td>Cette phase v&eacute;rifie l'autorisation d'acc&egrave;s d'un utilisateur
266         en fonction des ses param&egrave;tres de connexion, comme
267         l'identifiant, le certificat, etc...
268         </td>
269     </tr>
270     <tr>
271         <td>V&eacute;rification du type de la ressource</td>
272         <td><directive module="mod_lua">LuaHookTypeChecker</directive></td>
273         <td>Cette phase assigne un type de contenu et un gestionnaire &agrave;
274         la ressource.</td>
275     </tr>
276     <tr>
277         <td>Derniers r&eacute;glages</td>
278         <td><directive module="mod_lua">LuaHookFixups</directive></td>
279         <td>C'est la derni&egrave;re phase avant l'activation des gestionnaires
280         de contenu. Toute modification de derni&egrave;re minute &agrave; la requ&ecirc;te
281         doit &ecirc;tre effectu&eacute;e ici.</td>
282     </tr>
283     <tr>
284         <td>Gestionnaire de contenu</td>
285         <td>fichiers fx. <code>.lua</code> ou directive <directive module="mod_lua">LuaMapHandler</directive></td>
286         <td>C'est durant cette phase que le contenu est trait&eacute;. Les
287         fichiers sont lus, interpr&eacute;t&eacute;s, certains sont ex&eacute;cut&eacute;s, et le
288         r&eacute;sultat obtenu est envoy&eacute; au client.</td>
289     </tr>
290     <tr>
291         <td>Journalisation</td>
292         <td><directive module="mod_lua">LuaHookLog</directive></td>
293         <td>Lorsqu'une requ&ecirc;te a &eacute;t&eacute; trait&eacute;e, plusieurs phases de
294         journalisation interviennent, et enregistrent leurs r&eacute;sultats
295         dans les fichiers d'erreur ou d'acc&egrave;s. Mod_lua peut
296         s'intercaler au d&eacute;part de ce processus et ainsi contr&ocirc;ler la
297         journalisation.</td>
298     </tr>
299
300 </table>
301
302 <p>Les fonctions d'accroche re&ccedil;oivent l'objet de la requ&ecirc;te comme seul
303 argument (sauf LuaAuthzProvider qui re&ccedil;oit aussi des arguments en
304 provenance de la directive Require). Elles peuvent renvoyer une valeur,
305 selon la fonction, mais il s'agit en g&eacute;n&eacute;ral d'un
306 code d'&eacute;tat HTTP ou des valeurs OK, DONE, ou DECLINED,
307 que vous pouvez &eacute;crire dans Lua sous la forme <code>apache2.OK</code>,
308 <code>apache2.DONE</code>, ou <code>apache2.DECLINED</code>.</p>
309
310
311 <highlight language="lua">
312 <strong>translate_name.lua</strong><br/>
313 -- exemple d'accroche qui r&eacute;&eacute;crit un URI en chemin du syst&egrave;me de
314 fichiers.
315
316 require 'apache2'
317
318 function translate_name(r)
319     if r.uri == "/translate-name" then
320         r.filename = r.document_root .. "/find_me.txt"
321         return apache2.OK
322     end
323     -- on ne g&egrave;re pas cette URL et on donne sa chance &agrave; un autre module
324     return apache2.DECLINED
325 end
326 </highlight>
327
328
329 <highlight language="lua">
330 <strong>translate_name2.lua</strong><br/>
331 --[[ exemple d'accroche qui r&eacute;&eacute;crit un URI vers un autre URI. Il renvoie
332         un apache2.DECLINED pour permettre &agrave; un autre interpr&eacute;teur d'URL de
333         travailler sur la substitution, y compris l'accroche translate_name
334         de base dont les tables de correspondances se basent sur DocumentRoot.
335
336      Note: utilisez le drapeau early/late de la directive pour
337      l'ex&eacute;cuter avant ou apr&egrave;s mod_alias.
338 --]]
339
340 require 'apache2'
341
342 function translate_name(r)
343     if r.uri == "/translate-name" then
344         r.uri = "/find_me.txt"
345         return apache2.DECLINED
346     end
347     return apache2.DECLINED
348 end
349 </highlight>
350 </section>
351
352 <section id="datastructures"><title>Structures de donn&eacute;es</title>
353
354 <dl>
355 <dt>request_rec</dt>
356         <dd>
357         <p>request_rec est consid&eacute;r&eacute;e en tant que donn&eacute;e utilisateur.
358         Elle poss&egrave;de une m&eacute;tatable qui vous permet d'accomplir des
359         choses int&eacute;ressantes. Pour la plus grande partie, elle poss&egrave;de
360         les m&ecirc;mes champs que la structure request_rec, la
361         plupart d'entre eux &eacute;tant accessibles en lecture et &eacute;criture (le
362         contenu des champs de la table peut &ecirc;tre modifi&eacute;, mais les
363         champs eux-m&ecirc;mes ne peuvent pas &ecirc;tre &eacute;tablis en tant que tables
364         distinctes).</p>
365
366         <table border="1" style="zebra">
367
368         <tr>
369           <th><strong>Nom</strong></th>
370           <th><strong>Type Lua</strong></th>
371           <th><strong>Modifiable</strong></th>
372           <th><strong>Description</strong></th>
373         </tr>
374         <tr>
375           <td><code>allowoverrides</code></td>
376           <td>string</td>
377           <td>non</td>
378           <td>L'option AllowOverride s'applique &agrave; la requ&ecirc;te courante.</td>
379         </tr>
380         <tr>
381           <td><code>ap_auth_type</code></td>
382           <td>string</td>
383           <td>non</td>
384           <td>Ce champ contient le type d'authentification effectu&eacute;e
385           (par exemple <code>basic</code>)</td>
386         </tr>
387         <tr>
388           <td><code>args</code></td>
389           <td>string</td>
390           <td>oui</td>
391           <td>La cha&icirc;ne de param&egrave;tres de la requ&ecirc;te (par exemple
392           <code>foo=bar&amp;name=johnsmith</code>)</td>
393         </tr>
394         <tr>
395           <td><code>assbackwards</code></td>
396           <td>boolean</td>
397           <td>non</td>
398           <td>contient true s'il s'agit d'une requ&ecirc;te de style HTTP/0.9
399           (par exemple <code>GET /foo</code> (sans champs d'en-t&ecirc;te) )</td>
400         </tr>
401         <tr>
402           <td><code>auth_name</code></td>
403           <td>string</td>
404           <td>non</td>
405           <td>La cha&icirc;ne d'identification utilis&eacute;e pour la v&eacute;rification
406           de l'autorisation d'acc&egrave;s (si elle est disponible).</td>
407         </tr>
408         <tr>
409           <td><code>banner</code></td>
410           <td>string</td>
411           <td>non</td>
412           <td>La banni&egrave;re du serveur, par exemple <code>Apache HTTP
413           Server/2.4.3 openssl/0.9.8c</code></td>
414         </tr>
415         <tr>
416           <td><code>basic_auth_pw</code></td>
417           <td>string</td>
418           <td>non</td>
419           <td>Le mot de passe pour l'authentification de base envoy&eacute;
420           avec la requ&ecirc;te, s'il existe</td>
421         </tr>
422         <tr>
423           <td><code>canonical_filename</code></td>
424           <td>string</td>
425           <td>non</td>
426           <td>Le nom de fichier canonique de la requ&ecirc;te</td>
427         </tr>
428         <tr>
429           <td><code>content_encoding</code></td>
430           <td>string</td>
431           <td>non</td>
432           <td>Le type de codage du contenu de la requ&ecirc;te courante</td>
433         </tr>
434         <tr>
435           <td><code>content_type</code></td>
436           <td>string</td>
437           <td>oui</td>
438           <td>Le type de contenu de la requ&ecirc;te courante, tel qu'il a &eacute;t&eacute;
439           d&eacute;termin&eacute; au cours de la phase type_check (par exemple
440           <code>image/gif</code> ou <code>text/html</code>)</td>
441         </tr>
442
443         <tr>
444           <td><code>context_prefix</code></td>
445           <td>string</td>
446           <td>non</td>
447           <td></td>
448         </tr>
449         <tr>
450           <td><code>context_document_root</code></td>
451           <td>string</td>
452           <td>non</td>
453           <td></td>
454         </tr>
455
456         <tr>
457           <td><code>document_root</code></td>
458           <td>string</td>
459           <td>non</td>
460           <td>La racine des documents du serveur</td>
461         </tr>
462         <tr>
463           <td><code>err_headers_out</code></td>
464           <td>table</td>
465           <td>non</td>
466           <td>L'en-t&ecirc;te MIME de l'environnement pour la r&eacute;ponse, &eacute;crit
467           m&ecirc;me en cas d'erreur et conserv&eacute; pendant les redirections
468           internes</td>
469         </tr>
470         <tr>
471           <td><code>filename</code></td>
472           <td>string</td>
473           <td>oui</td>
474           <td>Le nom de fichier correspondant &agrave; la requ&ecirc;te, par exemple
475           /www/example.com/foo.txt. Il peut &ecirc;tre modifi&eacute; au cours des
476           phases translate-name ou map-to-storage du traitement de la
477           requ&ecirc;te pour permettre au gestionnaire par d&eacute;faut (ou aux
478           gestionnaires de script) de servir une version du fichier
479           autre que celle demand&eacute;e.</td>
480         </tr>
481         <tr>
482           <td><code>handler</code></td>
483           <td>string</td>
484           <td>oui</td>
485           <td>Le nom du <a href="../handler.html">gestionnaire</a> qui
486           doit traiter la requ&ecirc;te, par exemple <code>lua-script</code>
487           si elle doit &ecirc;tre trait&eacute;e par mod_lua. Cette valeur est en
488           g&eacute;n&eacute;ral d&eacute;finie via les directives <directive
489           module="mod_mime">AddHandler</directive> ou <directive
490           module="core">SetHandler</directive>, mais peut aussi l'&ecirc;tre
491           via mod_lua pour permettre &agrave; un autre gestionnaire de traiter
492           une requ&ecirc;te sp&eacute;cifique qui ne serait pas trait&eacute;e par d&eacute;faut
493           par ce dernier.
494             </td>
495         </tr>
496         <tr>
497           <td><code>headers_in</code></td>
498           <td>table</td>
499           <td>oui</td>
500           <td>Les en-t&ecirc;tes MIME de l'environnement de la requ&ecirc;te. Il
501           s'agit des en-t&ecirc;tes comme <code>Host, User-Agent,
502           Referer</code>, etc...</td>
503         </tr>
504         <tr>
505           <td><code>headers_out</code></td>
506           <td>table</td>
507           <td>oui</td>
508           <td>Les en-t&ecirc;tes MIME de l'environnement de la r&eacute;ponse.</td>
509         </tr>
510         <tr>
511           <td><code>hostname</code></td>
512           <td>string</td>
513           <td>non</td>
514           <td>Le nom d'h&ocirc;te, tel que d&eacute;fini par l'en-t&ecirc;te
515           <code>Host:</code> ou par un URI complet.</td>
516         </tr>
517         <tr>
518           <td><code>is_https</code></td>
519           <td>boolean</td>
520           <td>non</td>
521           <td>Indique si la requ&ecirc;te &agrave; &eacute;t&eacute; faite via HTTPS</td>
522         </tr>
523         <tr>
524           <td><code>is_initial_req</code></td>
525           <td>boolean</td>
526           <td>non</td>
527           <td>Indique si la requ&ecirc;te courante est la requ&ecirc;te initiale ou
528           une sous-requ&ecirc;te.</td>
529         </tr>
530         <tr>
531           <td><code>limit_req_body</code></td>
532           <td>number</td>
533           <td>non</td>
534           <td>La taille maximale du corps de la requ&ecirc;te, ou 0 si aucune
535           limite.</td>
536         </tr>
537         <tr>
538         <td><code>log_id</code></td>
539           <td>string</td>
540           <td>non</td>
541           <td>L'identifiant de la requ&ecirc;te dans les journaux d'acc&egrave;s ou
542           d'erreur.</td>
543         </tr>
544         <tr>
545           <td><code>method</code></td>
546           <td>string</td>
547           <td>non</td>
548           <td>La m&eacute;thode de la requ&ecirc;te, par exemple <code>GET</code> ou
549           <code>POST</code>.</td>
550         </tr>
551         <tr>
552           <td><code>notes</code></td>
553           <td>table</td>
554           <td>oui</td>
555           <td>Une liste de notes qui peuvent &ecirc;tre transmises d'un module
556           &agrave; l'autre.</td>
557         </tr>
558         <tr>
559           <td><code>options</code></td>
560           <td>string</td>
561           <td>non</td>
562           <td>La valeur de la directive Options pour la requ&ecirc;te
563           courante.</td>
564         </tr>
565         <tr>
566           <td><code>path_info</code></td>
567           <td>string</td>
568           <td>non</td>
569           <td>La valeur de PATH_INFO extraite de la requ&ecirc;te.</td>
570         </tr>
571         <tr>
572           <td><code>port</code></td>
573           <td>number</td>
574           <td>non</td>
575           <td>Le port du serveur utilis&eacute; par la requ&ecirc;te.</td>
576         </tr>
577         <tr>
578           <td><code>protocol</code></td>
579           <td>string</td>
580           <td>non</td>
581           <td>Le protocole utilis&eacute;, par exemple <code>HTTP/1.1</code></td>
582         </tr>
583         <tr>
584           <td><code>proxyreq</code></td>
585           <td>string</td>
586           <td>oui</td>
587           <td>Indique s'il s'agit d'une requ&ecirc;te mandat&eacute;e ou non. Cette
588           valeur est en g&eacute;n&eacute;ral d&eacute;finie au cours de la phase
589           post_read_request/translate_name du traitement de la requ&ecirc;te.</td>
590         </tr>
591         <tr>
592           <td><code>range</code></td>
593           <td>string</td>
594           <td>non</td>
595           <td>Le contenu de l'en-t&ecirc;te <code>Range:</code>.</td>
596         </tr>
597         <tr>
598           <td><code>remaining</code></td>
599           <td>number</td>
600           <td>non</td>
601           <td>Le nombre d'octets du corps de la requ&ecirc;te restant &agrave; lire.</td>
602         </tr>
603         <tr>
604           <td><code>server_built</code></td>
605           <td>string</td>
606           <td>non</td>
607           <td>La date de compilation du serveur.</td>
608         </tr>
609         <tr>
610           <td><code>server_name</code></td>
611           <td>string</td>
612           <td>non</td>
613           <td>Le nom du serveur pour cette requ&ecirc;te.</td>
614         </tr>
615         <tr>
616           <td><code>some_auth_required</code></td>
617           <td>boolean</td>
618           <td>non</td>
619           <td>Indique si une autorisation est/&eacute;tait requise pour cette
620           requ&ecirc;te.</td>
621         </tr>
622         <tr>
623           <td><code>subprocess_env</code></td>
624           <td>table</td>
625           <td>oui</td>
626           <td>Le jeu de variables d'environnement pour cette requ&ecirc;te.</td>
627         </tr>
628         <tr>
629           <td><code>started</code></td>
630           <td>number</td>
631           <td>non</td>
632           <td>Le moment o&ugrave; le serveur a &eacute;t&eacute; (re)d&eacute;marr&eacute;, en secondes
633           depuis epoch (1er janvier 1970)</td>
634         </tr>
635         <tr>
636           <td><code>status</code></td>
637           <td>number</td>
638           <td>oui</td>
639           <td>Le code de retour (courant) pour cette requ&ecirc;te, par
640           exemple <code>200</code> ou <code>404</code>.</td>
641         </tr>
642         <tr>
643           <td><code>the_request</code></td>
644           <td>string</td>
645           <td>non</td>
646           <td>La cha&icirc;ne de la requ&ecirc;te telle qu'elle a &eacute;t&eacute; envoy&eacute;e par le
647           client, par exemple <code>GET /foo/bar HTTP/1.1</code>.</td>
648         </tr>
649         <tr>
650           <td><code>unparsed_uri</code></td>
651           <td>string</td>
652           <td>non</td>
653           <td>La partie URI non interpr&eacute;t&eacute;e de la requ&ecirc;te</td>
654         </tr>
655         <tr>
656           <td><code>uri</code></td>
657           <td>string</td>
658           <td>oui</td>
659           <td>L'URI apr&egrave;s interpr&eacute;tation par httpd</td>
660         </tr>
661         <tr>
662           <td><code>user</code></td>
663           <td>string</td>
664           <td>oui</td>
665           <td>Si une authentification a &eacute;t&eacute; effectu&eacute;e, nom de
666           l'utilisateur authentifi&eacute;.</td>
667         </tr>
668         <tr>
669           <td><code>useragent_ip</code></td>
670           <td>string</td>
671           <td>non</td>
672           <td>L'adresse IP de l'agent qui a envoy&eacute; la requ&ecirc;te</td>
673         </tr>
674         </table>
675         </dd>
676     </dl>
677 </section>
678 <section id="functions"><title>M&eacute;thodes de l'objet request_rec</title>
679
680 <p>L'objet request_rec poss&egrave;de (au minimum) les m&eacute;thodes suivantes :</p>
681
682 <highlight language="lua">
683 r:flush()   -- vide le tampon de sortie
684             -- Renvoie true si le vidage a &eacute;t&eacute; effectu&eacute; avec succ&egrave;s,
685             false dans le cas contraire.
686
687 while nous_avons_des_donn&eacute;es_&agrave;_envoyer do
688     r:puts("Bla bla bla\n") -- envoi des donn&eacute;es &agrave; envoyer vers le tampon
689     r:flush() -- vidage du tampon (envoi au client)
690     r.usleep(500000) -- mise en attente pendant 0.5 secondes et bouclage
691 end
692 </highlight>
693
694 <highlight language="lua">
695 r:addoutputfilter(name|function) -- ajoute un filtre en sortie
696
697 r:addoutputfilter("fooFilter") -- ins&egrave;re le filtre fooFilter dans le flux de sortie
698 </highlight>
699
700 <highlight language="lua">
701 r:sendfile(filename) -- envoie un fichier entier au client en
702 utilisant sendfile s'il est support&eacute; par la plateforme :
703
704 if use_sendfile_thing then
705     r:sendfile("/var/www/large_file.img")
706 end
707 </highlight>
708
709 <highlight language="lua">
710 r:parseargs() -- renvoie deux tables : une table standard de couples
711 cl&eacute;/valeur pour les donn&eacute;es GET simples, et une autre pour les donn&eacute;es
712 multivalu&eacute;es (par exemple foo=1&amp;foo=2&amp;foo=3) :
713
714 local GET, GETMULTI = r:parseargs()
715 r:puts("Votre nom est : " .. GET['name'] or "Unknown")
716 </highlight>
717
718
719 <highlight language="lua">
720 r:parsebody()([sizeLimit]) -- interpr&egrave;te le corps de la requ&ecirc;te
721 en tant que POST et renvoie deux tables lua, comme r:parseargs(). Un nombre optionnel
722 peut &ecirc;tre fourni pour sp&eacute;cifier le nombre maximal d'octets &agrave;
723 interpr&eacute;ter. La valeur par d&eacute;faut est 8192.
724
725 local POST, POSTMULTI = r:parsebody(1024*1024)
726 r:puts("Votre nom est : " .. POST['name'] or "Unknown")
727 </highlight>
728
729
730 <highlight language="lua">
731 r:puts("bonjour", " le monde", "!") -- affichage dans le corps de la r&eacute;ponse
732 </highlight>
733
734 <highlight language="lua">
735 r:write("une simple cha&icirc;ne") -- affichage dans le
736 corps de la r&eacute;ponse
737 </highlight>
738
739 <highlight language="lua">
740 r:escape_html("&lt;html&gt;test&lt;/html&gt;") -- Echappe le
741 code HTML et renvoie le r&eacute;sultat
742 </highlight>
743
744 <highlight language="lua">
745 r:base64_encode(string) -- Encode une cha&icirc;ne &agrave; l'aide du
746 standard de codage Base64.
747
748 local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q=
749 </highlight>
750
751 <highlight language="lua">
752 r:base64_decode(string) -- D&eacute;code une cha&icirc;ne cod&eacute;e en Base64.
753
754 local decoded = r:base64_decode("VGhpcyBpcyBhIHRlc3Q=") -- returns 'This is a test'
755 </highlight>
756
757 <highlight language="lua">
758 r:md5(string) -- Calcule et renvoie le condens&eacute; MD5 d'une cha&icirc;ne
759 en mode binaire (binary safe).
760
761 local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339
762 </highlight>
763
764 <highlight language="lua">
765 r:sha1(string) -- Calcule et renvoie le condens&eacute; SHA1 d'une cha&icirc;ne
766 en mode binaire (binary safe).
767
768 local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19
769 </highlight>
770
771 <highlight language="lua">
772 r:escape(string) -- Echappe une cha&icirc;ne de type URL.
773
774 local url = "http://foo.bar/1 2 3 &amp; 4 + 5"
775 local escaped = r:escape(url) -- renvoie 'http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5'
776 </highlight>
777
778 <highlight language="lua">
779 r:unescape(string) -- D&eacute;s&eacute;chappe une cha&icirc;ne de type URL.
780
781 local url = "http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5"
782 local unescaped = r:unescape(url) -- renvoie 'http://foo.bar/1 2 3 &amp; 4 + 5'
783 </highlight>
784
785 <highlight language="lua">
786 r:construct_url(string) -- Construit une URL &agrave; partir d'un URI
787
788 local url = r:construct_url(r.uri)
789 </highlight>
790
791 <highlight language="lua">
792 r.mpm_query(number) -- Interroge le serveur &agrave; propos de son
793 module MPM via la requ&ecirc;te ap_mpm_query.
794
795 local mpm = r.mpm_query(14)
796 if mpm == 1 then
797     r:puts("Ce serveur utilise le MPM Event")
798 end
799 </highlight>
800
801 <highlight language="lua">
802 r:expr(string) -- Evalue une cha&icirc;ne de type <a
803 href="../expr.html">expr</a>.
804
805 if r:expr("%{HTTP_HOST} =~ /^www/") then
806     r:puts("Ce nom d'h&ocirc;te commence par www")
807 end
808 </highlight>
809
810 <highlight language="lua">
811 r:scoreboard_process(a) -- Interroge le serveur &agrave; propos du
812 processus &agrave; la position <code>a</code>.
813
814 local process = r:scoreboard_process(1)
815 r:puts("Le serveur 1 a comme PID " .. process.pid)
816 </highlight>
817
818 <highlight language="lua">
819 r:scoreboard_worker(a, b) -- Interroge le serveur &agrave; propos du
820 thread <code>b</code>, dans le processus <code>a</code>.
821
822 local thread = r:scoreboard_worker(1, 1)
823 r:puts("L'ID du thread 1 du serveur 1 est " .. thread.tid .. " et son
824 &eacute;tat est " .. thread.status)
825 </highlight>
826
827 <highlight language="lua">
828 r:clock() -- Renvoie l'heure courante avec une pr&eacute;cision d'une
829 microseconde.
830 </highlight>
831
832 <highlight language="lua">
833 r:requestbody(filename) -- Lit et renvoie le corps d'une requ&ecirc;te. Si
834 'filename' est sp&eacute;cifi&eacute;, le corps de requ&ecirc;te n'est pas renvoy&eacute;, mais
835 sauvegard&eacute; dans le fichier correspondant.
836
837 local input = r:requestbody()
838 r:puts("Vous m'avez envoy&eacute; le corps de requ&ecirc;te suivant :\n")
839 r:puts(input)
840 </highlight>
841
842 <highlight language="lua">
843 r:add_input_filter(filter_name) -- Ajoute le filtre en entr&eacute;e
844 'filter_name'.
845 </highlight>
846
847 <highlight language="lua">
848 r:module_info(module_name) -- Interroge le serveur &agrave; propos d'un
849 module.
850
851 local mod = r.module_info("mod_lua.c")
852 if mod then
853     for k, v in pairs(mod.commands) do
854        r:puts( ("%s: %s\n"):format(k,v)) -- affiche toutes les directives impl&eacute;ment&eacute;es par ce module
855     end
856 end
857 </highlight>
858
859 <highlight language="lua">
860 r:loaded_modules() -- Renvoie une liste des modules charg&eacute;s par
861 httpd.
862
863 for k, module in pairs(r:loaded_modules()) do
864     r:puts("J'ai charg&eacute; le module " .. module .. "\n")
865 end
866 </highlight>
867
868 <highlight language="lua">
869 r:runtime_dir_relative(filename) -- G&eacute;n&egrave;re le nom d'un fichier run-time
870 (par exemple la m&eacute;moire partag&eacute;e "file") relativement au r&eacute;pertoire de
871 run-time. 
872 </highlight>
873
874 <highlight language="lua">
875 r:server_info() -- Renvoie une table contenant des informations
876 &agrave; propos du serveur, comme le nom de l'ex&eacute;cutable httpd, le
877 module mpm utilis&eacute;, etc...
878 </highlight>
879
880 <highlight language="lua">
881 r:set_document_root(file_path) -- D&eacute;finit la racine des
882 documents pour la requ&ecirc;te &agrave; file_path.
883 </highlight>
884
885 <highlight language="lua">
886 r:add_version_component(component_string) -- Ajoute un &eacute;l&eacute;ment &agrave;
887 la banni&egrave;re du serveur.
888 </highlight>
889
890 <highlight language="lua">
891 r:set_context_info(prefix, docroot) -- D&eacute;finit le pr&eacute;fixe et la
892 racine des documents du contexte pour une requ&ecirc;te.
893 </highlight>
894
895 <highlight language="lua">
896 r:os_escape_path(file_path) -- Convertit un chemin du syst&egrave;me de
897 fichiers en URL ind&eacute;pendamment du syst&egrave;me d'exploitation.
898 </highlight>
899
900 <highlight language="lua">
901 r:escape_logitem(string) -- Echappe une cha&icirc;ne pour
902 journalisation.
903 </highlight>
904
905 <highlight language="lua">
906 r.strcmp_match(string, pattern) -- V&eacute;rifie si 'string' correspond &agrave;
907 'pattern' via la fonction strcmp_match (GLOBs). Par exemple, est-ce que
908 'www.example.com' correspond &agrave; '*.example.com' ?
909
910 local match = r.strcmp_match("foobar.com", "foo*.com")
911 if match then 
912     r:puts("foobar.com matches foo*.com")
913 end
914 </highlight>
915
916 <highlight language="lua">
917 r:set_keepalive() -- D&eacute;finit l'&eacute;tat de persistance d'une
918 requ&ecirc;te. Renvoie true dans la mesure du possible, false dans le
919 cas contraire.
920 </highlight>
921
922 <highlight language="lua">
923 r:make_etag() -- G&eacute;n&egrave;re et renvoie le etag pour la requ&ecirc;te
924 courante.
925 </highlight>
926
927 <highlight language="lua">
928 r:send_interim_response(clear) -- Renvoie une r&eacute;ponse d'int&eacute;rim (1xx) au
929 client. Si 'clear' est vrai, les en-t&ecirc;tes disponibles seront envoy&eacute;s et
930 effac&eacute;s.
931 </highlight>
932
933 <highlight language="lua">
934 r:custom_response(status_code, string) -- G&eacute;n&egrave;re et d&eacute;finit une r&eacute;ponse
935 personnalis&eacute;e pour un code d'&eacute;tat particulier. Le fonctionnement est
936 tr&egrave;s proche de celui de la directive ErrorDocument.
937
938 r:custom_response(404, "Baleted!")
939 </highlight>
940
941 <highlight language="lua">
942 r.exists_config_define(string) -- V&eacute;rifie si une d&eacute;finition de
943 configuration existe.
944
945 if r.exists_config_define("FOO") then
946     r:puts("httpd a probablement &eacute;t&eacute; lanc&eacute; avec l'option -DFOO, ou FOO a
947     &eacute;t&eacute; d&eacute;fini dans la configuration")
948 end
949 </highlight>
950
951 <highlight language="lua">
952 r:state_query(string) -- Interroge le serveur &agrave; propos de son
953 &eacute;tat.
954 </highlight>
955
956 <highlight language="lua">
957 r:stat(filename [,wanted]) -- Ex&eacute;cute stat() sur un fichier, et renvoie
958 une table contenant des informations &agrave; propos de ce fichier.
959
960 local info = r:stat("/var/www/foo.txt")
961 if info then
962     r:puts("Ce fichier existe et a &eacute;t&eacute; modifi&eacute; pour la derni&egrave;re fois &agrave; : " .. info.modified)
963 end
964 </highlight>
965
966 <highlight language="lua">
967 r:regex(string, pattern [,flags]) -- Ex&eacute;cute une recherche &agrave; base
968 d'expression rationnelle sur une cha&icirc;ne, et renvoie les
969 &eacute;ventuelles correspondances trouv&eacute;es.
970
971 local matches = r:regex("foo bar baz", [[foo (\w+) (\S*)]])
972 if matches then
973     r:puts("L'expression rationnelle correspond et le dernier mot
974     captur&eacute; ($2) est : " .. matches[2])
975 end
976
977 -- Exemple avec insensibilit&eacute; &agrave; la casse :
978 local matches = r:regex("FOO bar BAz", [[(foo) bar]], 1)
979
980 -- les drapeaux peuvent &ecirc;tre une combibaison bit &agrave; bit de :
981 -- 0x01: insensibilit&eacute; &agrave; la casse
982 -- 0x02: recherche multiligne
983 </highlight>
984
985 <highlight language="lua">
986 r.usleep(microsecondes) -- Interrompt l'ex&eacute;cution du script pendant le nombre de microsecondes sp&eacute;cifi&eacute;.
987 </highlight>
988
989 <highlight language="lua">
990 r:dbacquire(dbType[, dbParams]) -- Acquiert une connexion &agrave; une
991 base de donn&eacute;es et renvoie une classe database. Voir '<a
992 href="#databases">Connectivit&eacute; aux bases de donn&eacute;es</a>' pour plus de
993 d&eacute;tails.
994 </highlight>
995
996 <highlight language="lua">
997 r:ivm_set("key", value) -- D&eacute;fini une variable Inter-VM avec une valeur sp&eacute;cifique.
998                         -- Ces valeurs sont conserv&eacute;es m&ecirc;me si la VM est
999                         -- arr&ecirc;t&eacute;e ou non utilis&eacute;e, et ne doivent donc &ecirc;tre
1000                         -- utilis&eacute;es que si MaxConnectionsPerChild > 0.
1001                         -- Les valeurs peuvent &ecirc;tre de type number, string
1002                         -- ou boolean et sont stock&eacute;es s&eacute;par&eacute;ment pour
1003                         -- chaque processus (elles ne seront donc pas d'une
1004                         -- grande utilit&eacute; si l'on utilise le mpm prefork).
1005                         
1006 r:ivm_get("key")        -- Lit le contenu d'une variable d&eacute;finie via ivm_set. Renvoie
1007                         -- le contenu de la variable si elle existe, ou nil
1008                         -- dans le cas contraire.
1009                         
1010 -- Voici un exemple de lecture/&eacute;criture qui sauvegarde une variable
1011 -- globale en dehors de la VM :
1012 function handle(r)
1013     -- La premi&egrave;re VM qui effectue l'appel suivant n'obtiendra aucune
1014     -- valeur, et devra la cr&eacute;er
1015     local foo = r:ivm_get("cached_data")
1016     if not foo then
1017         foo = do_some_calcs() -- simulation de valeurs de retour
1018         r:ivm_set("cached_data", foo) -- d&eacute;finition globale de la variable
1019     end
1020     r:puts("La donn&eacute;e en cache est : ", foo)
1021 end                     
1022 </highlight>
1023 <highlight language="lua">
1024 r:htpassword(string [,algorithm [,cost]]) -- G&eacute;n&egrave;re un hash de mot de passe &agrave; partir d'une cha&icirc;ne.
1025                                           -- algorithm: 0 = APMD5 (d&eacute;faut), 1 = SHA, 2 = BCRYPT, 3 = CRYPT.
1026                                           -- cost: ne s'utilise qu'avec l'algorythme BCRYPT (d&eacute;faut = 5).
1027 </highlight>
1028
1029 <highlight language="lua">
1030 r:mkdir(dir [,mode]) -- Cr&eacute;e un r&eacute;pertoire et d&eacute;finit son mode via le param&egrave;tre optionnel mode.
1031 </highlight>
1032
1033 <highlight language="lua">
1034 r:mkrdir(dir [,mode]) -- Cr&eacute;e des r&eacute;pertoires de mani&egrave;re r&eacute;cursive et d&eacute;finit leur mode via le param&egrave;tre optionnel mode.
1035 </highlight>
1036
1037 <highlight language="lua">
1038 r:rmdir(dir) -- Supprime un r&eacute;pertoire.
1039 </highlight>
1040
1041 <highlight language="lua">
1042 r:touch(file [,mtime]) -- D&eacute;finit la date de modification d'un fichier &agrave; la date courante ou &agrave; la valeur optionnelle mtime en msec.
1043 </highlight>
1044
1045 <highlight language="lua">
1046 r:get_direntries(dir) -- Renvoie une table contenant toutes les entr&eacute;es de r&eacute;pertoires.
1047
1048 -- Renvoie un chemin sous forme &eacute;clat&eacute;e en chemin, fichier, extension
1049 function handle(r)
1050   local dir = r.context_document_root
1051   for _, f in ipairs(r:get_direntries(dir)) do
1052     local info = r:stat(dir .. "/" .. f)
1053     if info then
1054       local mtime = os.date(fmt, info.mtime / 1000000)
1055       local ftype = (info.filetype == 2) and "[dir] " or "[file]"
1056       r:puts( ("%s %s %10i %s\n"):format(ftype, mtime, info.size, f) )
1057     end
1058   end
1059 end
1060 </highlight>
1061
1062 <highlight language="lua">
1063 r.date_parse_rfc(string) -- Interpr&egrave;te une cha&icirc;ne date/heure et renvoie l'&eacute;quivalent en secondes depuis epoche.
1064 </highlight>
1065
1066 <highlight language="lua">
1067 r:getcookie(key) -- Obtient un cookie HTTP
1068 </highlight>
1069
1070 <highlight language="lua">
1071 r:setcookie(key, value, secure, expires) -- D&eacute;finit un cookie HTTP, par exemple :
1072 r:setcookie("foo", "bar and stuff", false, os.time() + 86400)
1073 </highlight>
1074
1075 <highlight language="lua">
1076 r:wsupgrade() -- Met &agrave; jour une connexion vers les WebSockets si possible (et si demand&eacute;) :
1077 if r:wsupgrade() then -- si la mise &agrave; jour est possible :
1078     r:wswrite("Bienvenue dans les websockets!") -- &eacute;crit quelque chose &agrave; l'intention du client
1079     r:wsclose()  -- Au revoir !
1080 end
1081 </highlight>
1082
1083 <highlight language="lua">
1084 r:wsread() -- Lit un cadre de websocket depuis une connexion vers websocket mise &agrave; jour (voir ci-dessus) :
1085            
1086 local line, isFinal = r:wsread() -- isFinal indique s'il s'agit du cadre final.
1087                                  -- dans le cas contraire, on peut lire les cadres suivants
1088 r:wswrite("Vous avez &eacute;crit : " .. line)
1089 </highlight>
1090
1091 <highlight language="lua">
1092 r:wswrite(line) -- &eacute;crit un cadre vers un client WebSocket :
1093 r:wswrite("Bonjour le Monde !")
1094 </highlight>
1095
1096 <highlight language="lua">
1097 r:wsclose() -- ferme une requ&ecirc;te WebSocket et l'ach&egrave;ve pour httpd :
1098
1099 if r:wsupgrade() then
1100     r:wswrite("Ecrire quelque chose : ")
1101     local line = r:wsread() or "nothing"
1102     r:wswrite("Vous avez &eacute;crit : " .. line);
1103     r:wswrite("Au revoir !")
1104     r:wsclose()
1105 end
1106 </highlight>
1107 <highlight language="lua">
1108 r:wspeek() -- V&eacute;rifie s'il y a des donn&eacute;es &agrave; lire
1109
1110 -- Se met en sommeil tant que rien ne nous est envoy&eacute; ...
1111 while r:wspeek() == false do
1112    r.usleep(50000)
1113 end
1114 -- Il y a des donn&eacute;es &agrave; lire !
1115 local line = r:wsread()
1116
1117 </highlight>
1118
1119 </section>
1120
1121 <section id="logging"><title>Fonctions de journalisation</title>
1122
1123 <highlight language="lua">
1124         -- exemples de messages de journalisation
1125         r:trace1("Ceci est un message de journalisation de niveau
1126         trace") -- les niveaux valides vont de trace1 &agrave; trace8 <br />
1127         r:debug("Ceci est un message de journalisation de niveau debug")<br />
1128         r:info("Ceci est un message de journalisation de niveau info")<br />
1129         r:notice("Ceci est un message de journalisation de niveau notice")<br />
1130         r:warn("Ceci est un message de journalisation de niveau warn")<br />
1131         r:err("Ceci est un message de journalisation de niveau err")<br />
1132         r:alert("Ceci est un message de journalisation de niveau alert")<br />
1133         r:crit("Ceci est un message de journalisation de niveau crit")<br />
1134         r:emerg("Ceci est un message de journalisation de niveau emerg")<br />
1135 </highlight>
1136
1137 </section>
1138
1139 <section id="apache2"><title>Paquet apache2</title>
1140 <p>Le paquet nomm&eacute; <code>apache2</code> est fourni avec (au minimum) le
1141 contenu suivant :</p>
1142 <dl>
1143   <dt>apache2.OK</dt>
1144   <dd>Constante interne OK. Les gestionnaires renverront cette valeur
1145   s'ils ont trait&eacute; la requ&ecirc;te.</dd>
1146   <dt>apache2.DECLINED</dt>
1147   <dd>Constante interne DECLINED. Les gestionnaires renverront cette
1148   valeur s'ils n'ont pas l'intention de traiter la requ&ecirc;te.</dd>
1149   <dt>apache2.DONE</dt>
1150   <dd>Constante interne DONE.</dd>
1151   <dt>apache2.version</dt>
1152   <dd>Cha&icirc;ne contenant la version du serveur HTTP Apache</dd>
1153   <dt>apache2.HTTP_MOVED_TEMPORARILY</dt>
1154   <dd>Code d'&eacute;tat HTTP</dd>
1155   <dt>apache2.PROXYREQ_NONE, apache2.PROXYREQ_PROXY, apache2.PROXYREQ_REVERSE, apache2.PROXYREQ_RESPONSE</dt>
1156   <dd>Constantes internes utilis&eacute;es par <module>mod_proxy</module></dd>
1157   <dt>apache2.AUTHZ_DENIED, apache2.AUTHZ_GRANTED, apache2.AUTHZ_NEUTRAL, apache2.AUTHZ_GENERAL_ERROR, apache2.AUTHZ_DENIED_NO_USER</dt>
1158   <dd>constantes internes utilis&eacute;es par <module>mod_authz_core</module></dd>
1159
1160 </dl>
1161 <p>Les autres codes d'&eacute;tat HTTP ne sont pas encore impl&eacute;ment&eacute;s.</p>
1162 </section>
1163
1164
1165 <section id="modifying_buckets">
1166     <title>Modification de contenu avec les filtres lua</title>
1167     <p>
1168     Les fonctions de filtrage impl&eacute;ment&eacute;es via les directives <directive
1169     module="mod_lua">LuaInputFilter</directive> ou <directive
1170     module="mod_lua">LuaOutputFilter</directive> sont con&ccedil;ues comme des
1171     fonctions de 3&egrave;me phase non blocantes utilisant des sous-routines
1172     pour suspendre et reprendre l'ex&eacute;cution d'une fonction lorsque des
1173     paquets de donn&eacute;es sont envoy&eacute;s &agrave; la cha&icirc;ne de filtrage. La
1174     structure de base d'une telle fonction est :
1175     </p>
1176     <highlight language="lua">
1177 function filter(r)
1178     -- Nous indiquons tout d'abord que nous sommes pr&ecirc;ts &agrave; recevoir des
1179     -- blocs de donn&eacute;es.
1180     -- Avant ceci, nous pouvons d&eacute;finir notre environnement, tester
1181     -- certaines conditions, et, si nous le jugeons n&eacute;cessaire, refuser le
1182     -- filtrage d'une requ&ecirc;te :
1183     if something_bad then
1184         return -- Le filtrage est saut&eacute;
1185     end
1186     -- Sans se pr&eacute;occuper des donn&eacute;es que nous devons &eacute;ventuellement ajouter, un arr&ecirc;t est r&eacute;alis&eacute; ici.
1187     -- Noter que les filtres de sortie sont les seuls capables d'ajouter des &eacute;l&eacute;ments au d&eacute;but des donn&eacute;es.
1188     -- Les filtres en entr&eacute;e peuvent ajouter des &eacute;l&eacute;ments &agrave; la fin des donn&eacute;es au stade final.
1189
1190     coroutine.yield([optional header to be prepended to the content])
1191
1192     -- Apr&egrave;s cet arr&ecirc;t, nous allons recevoir d'autres blocs de donn&eacute;es, un par un ;
1193     -- nous pouvons les traiter comme il nous pla&icirc;t et proc&eacute;der &agrave; la r&eacute;ponse.
1194     -- Ces blocs sont conserv&eacute;s dans la variable globale 'bucket', nous r&eacute;alisons donc
1195     -- une boucle pour v&eacute;rifier que 'bucket' n'est pas vide :
1196     while bucket ~= nil do
1197         local output = mangle(bucket) -- Do some stuff to the content
1198         coroutine.yield(output) -- Return our new content to the filter chain
1199     end
1200
1201     -- Une fois les blocs de donn&eacute;es &eacute;puis&eacute;s, 'bucket' est positionn&eacute; &agrave; une valeur vide ('nil'),
1202     -- ce qui va nous faire sortir de cette boucle et nous amener &agrave; l'&eacute;tape suivante.
1203     -- On peut ajouter ce qu'on veut &agrave; la fin des donn&eacute;es &agrave; cette &eacute;tape, qui constitue le dernier
1204     -- arr&ecirc;t. Les filtres d'entr&eacute;e comme de sortie peuvent servir &agrave; ajouter des &eacute;l&eacute;ments &agrave; la fin
1205     --  des donn&eacute;es &agrave; cette &eacute;tape.
1206     coroutine.yield([optional footer to be appended to the content])
1207 end
1208     </highlight>
1209 </section>
1210 <section id="databases">
1211     <title>Connectivit&eacute; aux bases de donn&eacute;es</title>
1212     <p>Mod_lua impl&eacute;mente une fonctionnalit&eacute; basique de connexion aux
1213 bases de donn&eacute;es permettant d'envoyer des requ&ecirc;tes ou d'ex&eacute;cuter des
1214 commandes aupr&egrave;s des moteurs de base de donn&eacute;es les plus courants
1215 (mySQL, PostgreSQL, FreeTDS, ODBC, SQLite, Oracle), ainsi que mod_dbd.
1216     </p>
1217     <p>L'exemple suivant montre comment se connecter &agrave; une base de
1218 donn&eacute;es et extraire des informations d'une table :</p>
1219     <highlight language="lua">
1220 function handle(r)
1221     -- connexion &agrave; la base de donn&eacute;es
1222     local database, err = r:dbacquire("mysql", "server=localhost,user=someuser,pass=somepass,dbname=mydb")
1223     if not err then
1224         -- S&eacute;lection de certaines informations
1225         local results, err = database:select(r, "SELECT `name`, `age` FROM `people` WHERE 1")
1226         if not err then
1227             local rows = results(0) -- extrait tous les enregistrements en mode synchrone
1228             for k, row in pairs(rows) do
1229                 r:puts( string.format("Name: %s, Age: %s&lt;br/&gt;", row[1], row[2]) )
1230             end
1231         else
1232             r:puts("Database query error: " .. err)
1233         end
1234         database:close()
1235     else
1236         r:puts("Connexion &agrave; la base de donn&eacute;es impossible : " .. err)
1237     end
1238 end
1239     </highlight>
1240     <p>
1241     Pour utiliser <module>mod_dbd</module>, sp&eacute;cifiez
1242 <code>mod_dbd</code> comme type de base de donn&eacute;es, ou laissez le champ
1243 vide :
1244     </p>
1245     <highlight language="lua">
1246     local database = r:dbacquire("mod_dbd")
1247     </highlight>
1248     <section id="database_object">
1249         <title>L'objet database et ses m&eacute;thodes</title>
1250         <p>L'objet database renvoy&eacute; par <code>dbacquire</code> poss&egrave;de
1251 les m&eacute;thodes suivantes :</p>
1252         <p><strong>S&eacute;lection normale et requ&ecirc;te vers une base de donn&eacute;es
1253 :</strong></p>
1254     <highlight language="lua">
1255 -- Ex&eacute;cution d'une requ&ecirc;te et renvoie du nombre d'enregistrements
1256 affect&eacute;s :
1257 local affected, errmsg = database:query(r, "DELETE FROM `tbl` WHERE 1")
1258
1259 -- Ex&eacute;cution d'une requ&ecirc;te et renvoie du r&eacute;sultat qui peut &ecirc;tre utilis&eacute;
1260 en mode synchrone ou asynchrone :
1261 local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1")
1262     </highlight>
1263         <p><strong>Utilisation de requ&ecirc;tes pr&eacute;par&eacute;es (recommand&eacute;) :</strong></p>
1264     <highlight language="lua">
1265 -- Cr&eacute;ation et ex&eacute;cution d'une requ&ecirc;te pr&eacute;par&eacute;e :
1266 local statement, errmsg = database:prepare(r, "DELETE FROM `tbl` WHERE `age` > %u")
1267 if not errmsg then
1268     local result, errmsg = statement:query(20) -- ex&eacute;cute la requ&ecirc;te pour age &gt; 20
1269 end
1270
1271 -- Extrait une requ&ecirc;te pr&eacute;par&eacute;e depuis une directive DBDPrepareSQL :
1272 local statement, errmsg = database:prepared(r, "someTag")
1273 if not errmsg then
1274     local result, errmsg = statement:select("John Doe", 123) -- injecte les valeurs "John Doe" et 123 dans la requ&ecirc;te
1275 end
1276
1277 </highlight>
1278         <p><strong>Echappement de valeurs, fermeture de la base donn&eacute;es,
1279 etc...</strong></p>
1280     <highlight language="lua">
1281 -- Echappe une valeur pour pouvoir l'utiliser dans une requ&ecirc;te :
1282 local escaped = database:escape(r, [["'|blabla]])
1283
1284 -- Ferme une base de donn&eacute;es et lib&egrave;re les liens vers cette derni&egrave;re :
1285 database:close()
1286
1287 -- V&eacute;rifie si une connexion &agrave; une base de donn&eacute;es est en service et
1288 op&eacute;rationnelle :
1289 local connected = database:active()
1290     </highlight>
1291     </section>
1292     <section id="result_sets">
1293     <title>Travail avec les jeux d'enregistrements renvoy&eacute;s par les requ&ecirc;tes</title>
1294     <p>Les jeux d'enregistrements renvoy&eacute;s par <code>db:select</code> ou par des
1295 requ&ecirc;tes pr&eacute;par&eacute;es cr&eacute;&eacute;es par <code>db:prepare</code> permettent de
1296 s&eacute;lectionner des enregistrements en mode synchrone ou
1297 asynchrone, selon le nombre d'enregistrements sp&eacute;cifi&eacute; :<br/>
1298     <code>result(0)</code> s&eacute;lectionne tous les enregistrements en mode
1299 synchrone en renvoyant une table d'enregistrements.<br/>
1300     <code>result(-1)</code> s&eacute;lectionne le prochain enregistrement disponible en
1301 mode asynchrone.<br/>
1302     <code>result(N)</code> s&eacute;lectionne l'enregistrement num&eacute;ro
1303 <code>N</code> en mode asynchrone.
1304     </p>
1305     <highlight language="lua">
1306 -- extrait un jeu d'enregistrements via une requ&ecirc;te r&eacute;guli&egrave;re :
1307 local result, err = db:select(r, "SELECT * FROM `tbl` WHERE 1")
1308
1309 local rows = result(0) -- s&eacute;lectionne tous les enregistrements en mode synchrone
1310 local row = result(-1) -- s&eacute;lectionne le prochain enregistrement disponible en mode asynchrone
1311 local row = result(1234) -- s&eacute;lectionne l'enregistrement 1234 en mode asynchrone
1312 local row = result(-1, true) -- Lit l'enregistrement suivant en utilisant les noms d'enregistrements comme index.
1313     </highlight>
1314     <p>Il est possible de construire une fonction qui renvoie une
1315 fonction it&eacute;rative permettant de traiter tous les enregistrement en mode
1316 synchrone ou asynchrone selon la valeur de l'argument async :
1317     </p>
1318     <highlight language="lua">
1319 function rows(resultset, async)
1320     local a = 0
1321     local function getnext()
1322         a = a + 1
1323         local row = resultset(-1)
1324         return row and a or nil, row
1325     end
1326     if not async then
1327         return pairs(resultset(0))
1328     else
1329         return getnext, self
1330     end
1331 end
1332
1333 local statement, err = db:prepare(r, "SELECT * FROM `tbl` WHERE `age` > %u")
1334 if not err then
1335      -- s&eacute;lectionne des enregistrements en mode asynchrone :
1336     local result, err = statement:select(20)
1337     if not err then
1338         for index, row in rows(result, true) do
1339             ....
1340         end
1341     end
1342
1343      -- s&eacute;lectionne des enregistrements en mode synchrone :
1344     local result, err = statement:select(20)
1345     if not err then
1346         for index, row in rows(result, false) do
1347             ....
1348         end
1349     end
1350 end
1351     </highlight>
1352     </section>
1353     <section id="closing_databases">
1354         <title>Fermeture d'une connexion &agrave; une base de donn&eacute;es</title>
1355
1356     <p>Lorsqu'elles ne sont plus utilis&eacute;es, les connexions aux bases de
1357 donn&eacute;es doivent &ecirc;tre ferm&eacute;es avec <code>database:close()</code>. Si vous
1358 ne les fermez pas manuellement, mod_lua les fermera peut-&ecirc;tre en tant
1359 que r&eacute;sidus collect&eacute;s, mais si ce n'est pas le cas, vous pouvez finir
1360 pas avoir trop de connexions vers la base de donn&eacute;es inutilis&eacute;es. Les
1361 deux mesures suivantes sont pratiquement identiques :
1362     </p>
1363     <highlight language="lua">
1364 -- M&eacute;thode 1 : fermeture manuelle de la connexion
1365 local database = r:dbacquire("mod_dbd")
1366 database:close() -- c'est tout
1367
1368 -- M&eacute;thode 2 : on laisse le collecteur de r&eacute;sidus la fermer
1369 local database = r:dbacquire("mod_dbd")
1370 database = nil -- on coupe le lien
1371 collectgarbage() -- fermeture de la connexion par le collecteur de r&eacute;sidus
1372 </highlight>
1373     </section>
1374     <section id="database_caveat">
1375     <title>Pr&eacute;cautions &agrave; prendre lorsque l'on travaille avec les bases
1376 de donn&eacute;es</title>
1377     <p>Bien que les fonctions <code>query</code> et <code>run</code>
1378 soient toujours disponibles, il est recommand&eacute; d'utiliser des requ&ecirc;tes
1379 pr&eacute;par&eacute;es chaque fois que possible, afin d'une part d'optimiser les
1380 performances (si votre connexion reste longtemps en vie), et d'autre part
1381 minimiser le risque d'attaques par injection SQL. Les fonctions
1382 <code>run</code> et <code>query</code> ne doivent &ecirc;tre utilis&eacute;es que
1383 lorsque la requ&ecirc;te ne contient pas de variables (requ&ecirc;te statique). Dans
1384 le cas des requ&ecirc;tes dynamiques, utilisez <code>db:prepare</code> ou
1385 <code>db:prepared</code>.
1386     </p>
1387     </section>
1388
1389 </section>
1390
1391 <directivesynopsis>
1392 <name>LuaRoot</name>
1393 <description>Sp&eacute;cifie le chemin de base pour la r&eacute;solution des chemins
1394 relatifs dans les directives de mod_lua</description>
1395 <syntax>LuaRoot /chemin/vers/un/r&eacute;pertoire</syntax>
1396 <contextlist><context>server config</context><context>virtual host</context>
1397 <context>directory</context><context>.htaccess</context>
1398 </contextlist>
1399 <override>All</override>
1400
1401 <usage>
1402     <p>Cette directive permet de sp&eacute;cifier le chemin de base qui sera
1403     utilis&eacute; pour &eacute;valuer tous les chemins relatifs dans mod_lua. En
1404     l'absence de cette directive, les chemins relatifs sont r&eacute;solus par
1405     rapport au r&eacute;pertoire de travail courant, ce qui ne sera pas
1406     toujours appropri&eacute; pour un serveur.</p>
1407 </usage>
1408 </directivesynopsis>
1409
1410 <directivesynopsis>
1411 <name>LuaScope</name>
1412 <description>Une valeur parmi once, request, conn, thread -- la valeur
1413 par d&eacute;faut est once</description>
1414 <syntax>LuaScope once|request|conn|thread|server [min] [max]</syntax>
1415 <default>LuaScope once</default>
1416 <contextlist><context>server config</context><context>virtual host</context>
1417 <context>directory</context><context>.htaccess</context>
1418 </contextlist>
1419 <override>All</override>
1420
1421 <usage>
1422     <p>Cette directive permet de sp&eacute;cifier la dur&eacute;e de vie de
1423     l'interpr&eacute;teur Lua qui sera utilis&eacute; dans ce "r&eacute;pertoire". La valeur
1424     par d&eacute;faut est "once".</p>
1425
1426    <dl>
1427     <dt>once:</dt> <dd>utilise l'interpr&eacute;teur une fois.</dd>
1428
1429     <dt>request:</dt> <dd>utilise l'interpr&eacute;teur pour traiter tout ce
1430     qui est bas&eacute; sur le m&ecirc;me fichier dans la requ&ecirc;te, et qui se trouve
1431     aussi dans la port&eacute;e de la requ&ecirc;te.</dd>
1432
1433     <dt>conn:</dt> <dd>idem request, mais attach&eacute; &agrave; connection_rec</dd>
1434
1435     <dt>thread:</dt> <dd>Utilise l'interpr&eacute;teur pendant toute la dur&eacute;e
1436     de vie du thread qui traite la requ&ecirc;te (disponible seulement avec
1437     les MPMs thread&eacute;s).</dd>
1438
1439     <dt>server:</dt>  <dd>Le comportement est ici diff&eacute;rent, car la
1440     port&eacute;e du serveur pr&eacute;sente une dur&eacute;e de vie assez longue, et
1441     plusieurs threads vont partager le m&ecirc;me server_rec. Pour g&eacute;rer tout
1442     ceci, les &eacute;tats lua du serveur sont stock&eacute;s dans une liste de ressources
1443     apr. Les arguments <code>min</code> et <code>max</code> permettent
1444     de sp&eacute;cifier les nombres minimaux et maximaux d'&eacute;tats lua &agrave; stocker
1445     dans la liste.</dd>
1446    </dl>
1447    <p>En g&eacute;n&eacute;ral, les port&eacute;es <code>thread</code> et <code>server</code>
1448    sont 2 &agrave; 3 fois plus rapides que les autres, car elles n'ont pas besoin
1449    de r&eacute;g&eacute;n&eacute;rer de nouveaux &eacute;tats Lua &agrave; chaque requ&ecirc;te (comme c'est le
1450    cas avec le MPM event, o&ugrave; m&ecirc;me les connexions persistantes utilisent un
1451    nouveau thread pour chaque requ&ecirc;te). Si vous pensez que vos scripts
1452    n'auront pas de probl&egrave;me s'il r&eacute;utilisent un &eacute;tat, alors les port&eacute;es
1453    <code>thread</code> ou <code>server</code> doivent &ecirc;tre utilis&eacute;es car
1454    elles pr&eacute;senteront de meilleures performances. Alors que la port&eacute;e
1455    <code>thread</code> fournira les r&eacute;ponses les plus rapides, la port&eacute;e
1456    <code>server</code> utilisera moins de m&eacute;moire car les &eacute;tats sont
1457    rassembl&eacute;s dans des jeux, permettant par exemple &agrave; 1000 threads de
1458    partager 100 &eacute;tats Lua, ne n&eacute;cessitant ainsi que 10% de la m&eacute;moire
1459    requise par la port&eacute;e <code>thread</code>.
1460     </p>
1461 </usage>
1462 </directivesynopsis>
1463
1464 <directivesynopsis>
1465 <name>LuaMapHandler</name>
1466 <description>Met en correspondance un chemin avec un gestionnaire lua</description>
1467 <syntax>LuaMapHandler modele-uri /chemin/vers/lua/script.lua
1468 [nom-fonction]</syntax>
1469 <contextlist><context>server config</context><context>virtual host</context>
1470 <context>directory</context><context>.htaccess</context>
1471 </contextlist>
1472 <override>All</override>
1473 <usage>
1474     <p>Cette directive permet de faire correspondre un mod&egrave;le d'uri avec
1475     une fonction de gestionnaire situ&eacute;e dans un fichier sp&eacute;cifique. Elle
1476     utilise les expressions rationnelles PCRE pour mettre en
1477     correspondance l'uri, et supporte les groupes de correspondance
1478     d'interpolation dans le chemin du fichier et le nom de la fonction.
1479     Prenez garde aux probl&egrave;mes de s&eacute;curit&eacute; en &eacute;crivant vos expressions
1480     rationnelles.</p>
1481    <example><title>Exemples :</title>
1482     <highlight language="config">
1483     LuaMapHandler /(\w+)/(\w+) /scripts/$1.lua handle_$2
1484     </highlight>
1485    </example>
1486         <p>Cette directive va faire correspondre des uri comme
1487         /photos/show?id=9 au fichier /scripts/photos.lua, et invoquera la
1488         fonction de gestionnaire handle_show au niveau de la vm lua
1489         apr&egrave;s chargement de ce fichier.</p>
1490
1491 <highlight language="config">
1492     LuaMapHandler /bingo /scripts/wombat.lua
1493 </highlight>
1494         <p>Cette directive invoquera la fonction "handle" qui est la
1495         valeur par d&eacute;faut si aucun nom de fonction sp&eacute;cifique n'est
1496         sp&eacute;cifi&eacute;.</p>
1497 </usage>
1498 </directivesynopsis>
1499
1500 <directivesynopsis>
1501 <name>LuaPackagePath</name>
1502 <description>Ajoute un r&eacute;pertoire au package.path de lua</description>
1503 <syntax>LuaPackagePath /chemin/vers/include/?.lua</syntax>
1504 <contextlist><context>server config</context><context>virtual host</context>
1505 <context>directory</context><context>.htaccess</context>
1506 </contextlist>
1507 <override>All</override>
1508     <usage><p>Cette directive permet d'ajouter un chemin &agrave; la liste des
1509     chemins de recherche du module lua. Elle suit les m&ecirc;mes conventions
1510     que lua. Ceci modifie le package.path dans les vms lua.</p>
1511
1512     <example><title>Exemples :</title>
1513         <highlight language="config">
1514 LuaPackagePath /scripts/lib/?.lua
1515 LuaPackagePath /scripts/lib/?/init.lua
1516     </highlight>
1517     </example>
1518 </usage>
1519 </directivesynopsis>
1520
1521 <directivesynopsis>
1522 <name>LuaPackageCPath</name>
1523 <description>Ajoute un r&eacute;pertoire au package.cpath de lua</description>
1524 <syntax>LuaPackageCPath /chemin/vers/include/?.soa</syntax>
1525 <contextlist><context>server config</context><context>virtual host</context>
1526 <context>directory</context><context>.htaccess</context>
1527 </contextlist>
1528 <override>All</override>
1529
1530 <usage>
1531     <p>Cette directive permet d'ajouter un chemin &agrave; la liste des chemins
1532     de recherche des biblioth&egrave;ques partag&eacute;es de lua. Ceci modifie le
1533     package.cpath dans les vms lua.</p>
1534
1535 </usage>
1536 </directivesynopsis>
1537
1538 <directivesynopsis>
1539 <name>LuaCodeCache</name>
1540 <description>Configure le cache de code compil&eacute;.</description>
1541 <syntax>LuaCodeCache stat|forever|never</syntax>
1542 <default>LuaCodeCache stat</default>
1543 <contextlist>
1544 <context>server config</context><context>virtual host</context>
1545 <context>directory</context><context>.htaccess</context>
1546 </contextlist>
1547 <override>All</override>
1548
1549 <usage><p>
1550     Cette directive permet de d&eacute;finir le comportement du cache de code
1551     en m&eacute;moire. La valeur par d&eacute;faut est stat ; dans ce cas, le script
1552     du niveau le plus haut (et pas les scripts inclus) est v&eacute;rifi&eacute; &agrave;
1553     chaque fois que ce fichier est n&eacute;cessaire, et est recharg&eacute; si la
1554     date de modification est plus r&eacute;cente que celle du script d&eacute;j&agrave;
1555     charg&eacute;. Les autres valeurs permettent respectivement de garder le
1556     fichier en cache perp&eacute;tuellement (forever - jamais v&eacute;rifi&eacute; ni
1557     remplac&eacute;), ou de ne jamais le mettre en cache (never).</p>
1558
1559     <p>En g&eacute;n&eacute;ral, les valeurs stat et forever sont utilis&eacute;es pour un
1560     serveur en production, et les valeurs stat ou never pour un serveur
1561     en d&eacute;veloppement.</p>
1562
1563     <example><title>Exemples :</title>
1564         <highlight language="config">
1565 LuaCodeCache stat
1566 LuaCodeCache forever
1567 LuaCodeCache never
1568     </highlight>
1569     </example>
1570
1571 </usage>
1572 </directivesynopsis>
1573
1574 <directivesynopsis>
1575 <name>LuaHookTranslateName</name>
1576 <description>Fournit un point d'entr&eacute;e &agrave; la phase du nom de
1577 traduction du traitement de la requ&ecirc;te</description>
1578 <syntax>LuaHookTranslateName  /chemin/vers/lua/script.lua  nom_fonction_hook [early|late]</syntax>
1579 <contextlist><context>server config</context><context>virtual host</context>
1580 </contextlist>
1581 <override>All</override>
1582 <compatibility>Le troisi&egrave;me argument optionnel est disponible depuis la
1583 version 2.3.15 du serveur HTTP Apache.</compatibility>
1584
1585 <usage><p>
1586     Cette directive permet d'ajouter un point d'entr&eacute;e (&agrave;
1587     APR_HOOK_MIDDLE) &agrave; la phase du nom de traduction du traitement de la
1588     requ&ecirc;te. La fonction hook accepte un seul argument, le request_rec,
1589     et doit renvoyer un code d'&eacute;tat qui est soit un code d'erreur HTTP,
1590     ou une constante d&eacute;finie dans le module apache2 :  apache2.OK,
1591     apache2.DECLINED, ou apache2.DONE.</p>
1592
1593     <p>Pour ceux qui ne sont pas familiers avec les points d'entr&eacute;e
1594     (hook), en gros, chaque hook sera invoqu&eacute; jusqu'&agrave; ce que l'un
1595     d'entre eux renvoie apache2.OK. Si un hook n'effectuer pas la
1596     traduction, il doit juste renvoyer apache2.DECLINED. Si le
1597     traitement de la requ&ecirc;te doit &ecirc;tre interrompu, la valeur renvoy&eacute;e
1598     doit &ecirc;tre apache2.DONE.</p>
1599
1600     <p>Exemple :</p>
1601
1602 <highlight language="config">
1603 # httpd.conf
1604 LuaHookTranslateName /scripts/conf/hooks.lua silly_mapper
1605 </highlight>
1606
1607 <highlight language="lua">
1608 -- /scripts/conf/hooks.lua --
1609 require "apache2"
1610 function silly_mapper(r)
1611     if r.uri == "/" then
1612         r.filename = "/var/www/home.lua"
1613         return apache2.OK
1614     else
1615         return apache2.DECLINED
1616     end
1617 end
1618 </highlight>
1619
1620    <note><title>Contexte</title><p>Cette directive ne peut &ecirc;tre
1621    utilis&eacute;e ni &agrave; l'int&eacute;rieur d'une section <directive type="section"
1622    module="core">Directory</directive> ou <directive type="section"
1623    module="core">Files</directive>, ni dans un fichier htaccess.</p></note>
1624
1625    <note><title>Ordonnancement</title><p>Les arguments optionnels
1626    "early" ou "late" permettent de contr&ocirc;ler le moment auquel ce script
1627    s'ex&eacute;cute par rapport aux autres modules.</p></note>
1628 </usage>
1629 </directivesynopsis>
1630
1631 <directivesynopsis>
1632 <name>LuaHookFixups</name>
1633 <description>Fournit un point d'entr&eacute;e pour la phase de correction du
1634 traitement de la requ&ecirc;te</description>
1635 <syntax>LuaHookFixups  /chemin/vers/lua/script.lua hook_function_name</syntax>
1636 <contextlist><context>server config</context><context>virtual host</context>
1637 <context>directory</context><context>.htaccess</context>
1638 </contextlist>
1639 <override>All</override>
1640 <usage>
1641 <p>
1642     Idem LuaHookTranslateName, mais s'ex&eacute;cute durant la phase de
1643     correction.
1644 </p>
1645 </usage>
1646 </directivesynopsis>
1647
1648 <directivesynopsis>
1649 <name>LuaHookLog</name>
1650 <description>Permet une insertion dans la phase de journalisation du
1651 traitement d'une requ&ecirc;te</description>
1652 <syntax>LuaHookLog  /path/to/lua/script.lua log_function_name</syntax>
1653 <contextlist><context>server config</context><context>virtual host</context>
1654 <context>directory</context><context>.htaccess</context>
1655 </contextlist>
1656 <override>All</override>
1657 <usage>
1658 <p>
1659     Ce dispositif d'insertion simple permet d'ex&eacute;cuter une fonction
1660     lorsque httpd entre dans la phase de journalisation du traitement
1661     d'une requ&ecirc;te. Vous pouvez ainsi ajouter des donn&eacute;es &agrave; vos propres
1662     entr&eacute;es de journalisation, manipuler les entr&eacute;es du journal standard
1663     avant leur enregistrement ou emp&ecirc;cher l'enregistrement d'une entr&eacute;e
1664     dans le journal. Pour emp&ecirc;cher l'enregistrement normal des entr&eacute;es
1665     du journal, renvoyez simplement <code>apache2.DONE</code> dans votre
1666     gestionnaire de journalisation, ou au contraire, renvoyez
1667     <code>apache2.OK</code> pour que httpd effectue une journalisation
1668     normale.
1669 </p>
1670 <p>Exemple :</p>
1671 <highlight language="config">
1672 LuaHookLog /path/to/script.lua logger
1673 </highlight>
1674 <highlight language="lua">
1675 -- /path/to/script.lua --
1676 function logger(r)
1677     -- on joue &agrave; pile ou face :
1678     -- Si on obtient 1, on &eacute;crit dans notre propre journal Lua et on dit
1679     -- &agrave; httpd de ne pas enregistrer d'entr&eacute;e dans le journal standard..
1680     -- Si on obtient 2, on nettoie un peu les donn&eacute;es avant que httpd ne
1681     -- les enregistre dans le journal standard.
1682
1683     if math.random(1,2) == 1 then
1684         -- On effectue notre propre journalisation et le journal
1685         -- standard n'est pas aliment&eacute;
1686         local f = io.open("/foo/secret.log", "a")
1687         if f then
1688             f:write("Quelque chose de secret est arriv&eacute; &agrave; " .. r.uri .. "\n")
1689             f:close()
1690         end
1691         return apache2.DONE -- On dit &agrave; httpd de ne rien enregistrer
1692                                 --dans le journal standard
1693     else
1694         r.uri = r.uri:gsub("somesecretstuff", "") -- nettoie les donn&eacute;es
1695         return apache2.OK -- et httpd doit alors les enregistrer.
1696     end
1697 end
1698 </highlight>
1699 </usage>
1700 </directivesynopsis>
1701
1702
1703 <directivesynopsis>
1704 <name>LuaHookMapToStorage</name>
1705 <description>Fournit un point d'entr&eacute;e pour la phase map_to_storage du
1706 traitement de la requ&ecirc;te</description>
1707 <syntax>LuaHookMapToStorage  /chemin/vers/lua/script.lua hook_function_name</syntax>
1708 <contextlist><context>server config</context><context>virtual host</context>
1709 <context>directory</context><context>.htaccess</context>
1710 </contextlist>
1711 <override>All</override>
1712     <usage>
1713     <p>Identique &agrave; la directive
1714     <directive>LuaHookTranslateName</directive>, mais s'ex&eacute;cute &agrave; la
1715     phase map-to-storage du traitement de la requ&ecirc;te. Les modules comme
1716     mod_cache agissent pendant cette phase, ce qui permet de pr&eacute;senter
1717     un exemple int&eacute;ressant de ce que l'on peut faire ici :</p>
1718     <highlight language="config">
1719     LuaHookMapToStorage /path/to/lua/script.lua check_cache
1720     </highlight>
1721     <highlight language="lua">
1722 require"apache2"
1723 cached_files = {}
1724
1725 function read_file(filename)
1726     local input = io.open(filename, "r")
1727     if input then
1728         local data = input:read("*a")
1729         cached_files[filename] = data
1730         file = cached_files[filename]
1731         input:close()
1732     end
1733     return cached_files[filename]
1734 end
1735
1736 function check_cache(r)
1737     if r.filename:match("%.png$") then -- Only match PNG files
1738         local file = cached_files[r.filename] -- Check cache entries
1739         if not file then
1740             file = read_file(r.filename)  -- Read file into cache
1741         end
1742         if file then -- If file exists, write it out
1743             r.status = 200
1744             r:write(file)
1745             r:info(("Sent %s to client from cache"):format(r.filename))
1746             return apache2.DONE -- skip default handler for PNG files
1747         end
1748     end
1749     return apache2.DECLINED -- If we had nothing to do, let others serve this.
1750 end
1751     </highlight>
1752
1753     </usage>
1754 </directivesynopsis>
1755
1756 <directivesynopsis>
1757 <name>LuaHookCheckUserID</name>
1758 <description>Fournit un point d'entr&eacute;e pour la phase check_user_id du
1759 traitement de la requ&ecirc;te</description>
1760 <syntax>LuaHookCheckUserID  /chemin/vers/lua/script.lua hook_function_name [early|late]</syntax>
1761 <contextlist><context>server config</context><context>virtual host</context>
1762 <context>directory</context><context>.htaccess</context>
1763 </contextlist>
1764 <override>All</override>
1765 <compatibility>Le troisi&egrave;me argument optionnel est disponible depuis la
1766 version 2.3.15 du serveur HTTP Apache.</compatibility>
1767 <usage><p>...</p>
1768    <note><title>Ordonnancement</title><p>Les arguments optionnels
1769    "early" ou "late" permettent de contr&ocirc;ler le moment auquel ce script
1770    s'ex&eacute;cute par rapport aux autres modules.</p></note>
1771 </usage>
1772 </directivesynopsis>
1773
1774 <directivesynopsis>
1775 <name>LuaHookTypeChecker</name>
1776 <description>Fournit un point d'entr&eacute;e pour la phase type_checker du
1777 traitement de la requ&ecirc;te</description>
1778 <syntax>LuaHookTypeChecker  /chemin/vers/lua/script.lua hook_function_name</syntax>
1779 <contextlist><context>server config</context><context>virtual host</context>
1780 <context>directory</context><context>.htaccess</context>
1781 </contextlist>
1782 <override>All</override>
1783     <usage><p>...</p></usage>
1784 </directivesynopsis>
1785
1786 <directivesynopsis>
1787 <name>LuaHookAuthChecker</name>
1788 <description>Fournit un point d'entr&eacute;e pour la phase auth_checker du
1789 traitement de la requ&ecirc;te</description>
1790 <syntax>LuaHookAuthChecker  /chemin/vers/lua/script.lua hook_function_name [early|late]</syntax>
1791 <contextlist><context>server config</context><context>virtual host</context>
1792 <context>directory</context><context>.htaccess</context>
1793 </contextlist>
1794 <override>All</override>
1795 <compatibility>Le troisi&egrave;me argument optionnel est disponible depuis la
1796 version 2.3.15 du serveur HTTP Apache.</compatibility>
1797     <usage>
1798 <p>Invoque une fonction lua au cours de la phase auth_checker du
1799 traitement de la requ&ecirc;te. Cette directive peut s'utiliser pour
1800 impl&eacute;menter une v&eacute;rification arbitraire de l'authentification et de
1801 l'autorisation. Voici un exemple tr&egrave;s simple :
1802 </p>
1803 <highlight language="lua">
1804 require 'apache2'
1805
1806 -- fonction d'accroche authcheck fictive
1807 -- Si la requ&ecirc;te ne contient aucune donn&eacute;e d'authentification, l'en-t&ecirc;te
1808 -- de la r&eacute;ponse est d&eacute;fini et un code 401 est renvoy&eacute; afin de demander au
1809 -- navigateur d'effectuer une authentification basique. Si la requ&ecirc;te
1810 -- comporte des donn&eacute;es d'authentification, elles ne sont pas vraiment
1811 -- consult&eacute;es, mais on admet la prise en compte de l'utilisateur 'foo' et
1812 -- on la valide. On v&eacute;rifie ensuite si l'utilisateur est bien 'foo' et on
1813 -- accepte la requ&ecirc;te.
1814 function authcheck_hook(r)
1815
1816    -- recherche des informations d'authentification
1817    auth = r.headers_in['Authorization']
1818    if auth ~= nil then
1819      -- d&eacute;finition d'un utilisateur par d&eacute;faut
1820      r.user = 'foo'
1821    end
1822
1823    if r.user == nil then
1824       r:debug("authcheck: user is nil, returning 401")
1825       r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
1826       return 401
1827    elseif r.user == "foo" then
1828       r:debug('user foo: OK')
1829    else
1830       r:debug("authcheck: user='" .. r.user .. "'")
1831       r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
1832       return 401
1833    end
1834    return apache2.OK
1835 end
1836 </highlight>
1837 <note><title>Ordonnancement</title><p>Les arguments optionnels
1838    "early" ou "late" permettent de contr&ocirc;ler le moment auquel ce script
1839    s'ex&eacute;cute par rapport aux autres modules.</p></note>
1840 </usage>
1841 </directivesynopsis>
1842
1843 <directivesynopsis>
1844 <name>LuaHookAccessChecker</name>
1845 <description>Fournit un point d'entr&eacute;e pour la phase access_checker du
1846 traitement de la requ&ecirc;te</description>
1847 <syntax>LuaHookAccessChecker  /chemin/vers/lua/script.lua  hook_function_name [early|late]</syntax>
1848 <contextlist><context>server config</context><context>virtual host</context>
1849 <context>directory</context><context>.htaccess</context>
1850 </contextlist>
1851 <override>All</override>
1852 <compatibility>Le troisi&egrave;me argument optionnel est disponible depuis la
1853 version 2.3.15 du serveur HTTP Apache.</compatibility>
1854
1855 <usage>
1856 <p>Ajoute votre fonction d'accroche &agrave; la phase access_checker. Une
1857 fonction d'accroche access checker renvoie en g&eacute;n&eacute;ral OK, DECLINED, ou
1858 HTTP_FORBIDDEN.</p>
1859 <note><title>Ordonnancement</title><p>Les arguments optionnels
1860    "early" ou "late" permettent de contr&ocirc;ler le moment auquel ce script
1861    s'ex&eacute;cute par rapport aux autres modules.</p></note>
1862 </usage>
1863 </directivesynopsis>
1864 <directivesynopsis>
1865 <name>LuaHookInsertFilter</name>
1866 <description>Fournit un point d'entr&eacute;e pour la phase insert_filter du
1867 traitement de la requ&ecirc;te</description>
1868 <syntax>LuaHookInsertFilter  /chemin/vers/lua/script.lua hook_function_name</syntax>
1869 <contextlist><context>server config</context><context>virtual host</context>
1870 <context>directory</context><context>.htaccess</context>
1871 </contextlist>
1872 <override>All</override>
1873     <usage><p>Non encore impl&eacute;ment&eacute;</p></usage>
1874 </directivesynopsis>
1875
1876 <directivesynopsis>
1877 <name>LuaInherit</name>
1878 <description>Contr&ocirc;le la mani&egrave;re dont les sections de configuration
1879 parentes sont fusionn&eacute;es dans les enfants</description>
1880 <syntax>LuaInherit none|parent-first|parent-last</syntax>
1881 <default>LuaInherit parent-first</default>
1882 <contextlist><context>server config</context><context>virtual host</context>
1883 <context>directory</context><context>.htaccess</context>
1884 </contextlist>
1885 <override>All</override>
1886 <compatibility>Versions 2.4.0 et sup&eacute;rieures</compatibility>
1887     <usage><p>Par d&eacute;faut, si des directives LuaHook* se trouvent dans
1888     des sections de configuration Directory ou Location qui se
1889     chevauchent, les scripts
1890     d&eacute;finis dans les sections les plus sp&eacute;cifiques s'ex&eacute;cutent
1891     <em>apr&egrave;s</em> ceux d&eacute;finis dans les sections plus g&eacute;n&eacute;riques
1892     (LuaInherit parent-first). Vous pouvez inverser cet ordre, ou faire
1893     en sorte que le contexte parent ne s'applique pas du tout.</p>
1894
1895     <p>Jusqu'aux versions 2.3.x, le comportement par d&eacute;faut consistait &agrave;
1896     ignorer les directives LuaHook* situ&eacute;es dans les sections de
1897     configuration parentes.</p></usage>
1898 </directivesynopsis>
1899
1900 <directivesynopsis>
1901 <name>LuaQuickHandler</name>
1902 <description>Fournit un point d'entr&eacute;e pour la gestion rapide du
1903 traitement de la requ&ecirc;te</description>
1904 <syntax>LuaQuickHandler /path/to/script.lua hook_function_name</syntax>
1905 <contextlist><context>server config</context><context>virtual host</context>
1906 <context>directory</context><context>.htaccess</context>
1907 </contextlist>
1908 <override>All</override>
1909 <usage>
1910     <p>Cette phase s'ex&eacute;cute juste apr&egrave;s l'attribution de la requ&ecirc;te &agrave;
1911     un serveur virtuel, et permet d'effectuer certains traitements avant
1912     le d&eacute;roulement des autres phases, ou de servir une requ&ecirc;te sans
1913     avoir &agrave; la traduire, l'associer &agrave; un espace de stockage, etc...
1914     Comme cette phase s'ex&eacute;cute avant toute autre, les directives telles
1915     que <directive type="section" module="core">Location</directive> ou
1916     <directive type="section" module="core">Directory</directive> ne
1917     sont pas encore prises en compte, car Les URI n'ont pas encore &eacute;t&eacute;
1918     enti&egrave;rement interpr&eacute;t&eacute;s.
1919     </p>
1920    <note><title>Contexte</title><p>Cette directive ne peut &ecirc;tre
1921    utilis&eacute;e ni &agrave; l'int&eacute;rieur d'une section <directive type="section"
1922    module="core">Directory</directive> ou <directive type="section"
1923    module="core">Files</directive>, ni dans un fichier htaccess.</p></note>
1924 </usage>
1925 </directivesynopsis>
1926
1927 <directivesynopsis>
1928 <name>LuaAuthzProvider</name>
1929 <description>Branche une fonction fournisseur d'autorisation dans <module>mod_authz_core</module>
1930 </description>
1931 <syntax>LuaAuthzProvider provider_name /path/to/lua/script.lua function_name</syntax>
1932 <contextlist><context>server config</context> </contextlist>
1933 <compatibility>Disponible depuis la version 2.4.3 du serveur HTTP Apache</compatibility>
1934
1935 <usage>
1936 <p>Lorsqu'une fonction lua a &eacute;t&eacute; enregistr&eacute;e en tant que fournisseur
1937 d'autorisation, elle peut &ecirc;tre appel&eacute;e via la directive <directive
1938 module="mod_authz_core">Require</directive> :</p>
1939
1940
1941 <highlight language="config">
1942 LuaRoot /usr/local/apache2/lua
1943 LuaAuthzProvider foo authz.lua authz_check_foo
1944 &lt;Location /&gt;
1945   Require foo johndoe
1946 &lt;/Location&gt;
1947 </highlight>
1948 <highlight language="lua">
1949 require "apache2"
1950 function authz_check_foo(r, who)
1951     if r.user ~= who then return apache2.AUTHZ_DENIED
1952     return apache2.AUTHZ_GRANTED
1953 end
1954 </highlight>
1955
1956 </usage>
1957 </directivesynopsis>
1958
1959 <directivesynopsis>
1960 <name>LuaInputFilter</name>
1961 <description>Fournit une fonction Lua pour le filtrage en entr&eacute;e</description>
1962 <syntax>LuaInputFilter filter_name /path/to/lua/script.lua function_name</syntax>
1963 <contextlist><context>server config</context> </contextlist>
1964 <compatibility>Disponible depuis la version 2.5.0 du serveur HTTP
1965 Apache</compatibility>
1966
1967 <usage>
1968 <p>Cette directive permet d'ajouter un filtre en entr&eacute;e sous la forme
1969 d'une fonction Lua. A l'instar des filtres en sorties, les filtres en
1970 entr&eacute;e fonctionnent comme des sous-routines, intervenant dans un premier
1971 temps avant l'envoi du contenu des tampons, puis chaque fois qu'un
1972 paquet de donn&eacute;es doit &ecirc;tre transmis &agrave; la cha&icirc;ne, et &eacute;ventuellement
1973 produisant toute donn&eacute;e &agrave; ajouter aux donn&eacute;es en entr&eacute;e. La variable
1974 globale <code>bucket</code> contient les paquets de donn&eacute;es tels qu'ils
1975 sont transmis au script Lua :
1976 </p>
1977
1978 <highlight language="config">
1979 LuaInputFilter myInputFilter /www/filter.lua input_filter
1980 &lt;FilesMatch "\.lua&gt;
1981   SetInputFilter myInputFilter
1982 &lt;/FilesMatch&gt;
1983 </highlight>
1984 <highlight language="lua">
1985 --[[
1986     Exemple de filtre en entr&eacute;e qui convertit toutes les donn&eacute;es POST en
1987     majuscules.
1988 ]]--
1989 function input_filter(r)
1990     print("luaInputFilter called") -- debug print
1991     coroutine.yield() -- Yield and wait for buckets
1992     while bucket do -- For each bucket, do...
1993         local output = string.upper(bucket) -- Convertit toutes les donn&eacute;es POST en majuscules
1994         coroutine.yield(output) -- Envoie les donn&eacute;es trait&eacute;es &agrave; la cha&icirc;ne
1995     end
1996     -- plus aucune donn&eacute;e &agrave; traiter.
1997     coroutine.yield("&amp;filterSignature=1234") -- Ajoute une signature &agrave; la fin
1998 end
1999 </highlight>
2000 <p>
2001 Le filtre en entr&eacute;e peut interdire ou sauter un filtre s'il est
2002 consid&eacute;r&eacute; comme ind&eacute;sirable :
2003 </p>
2004 <highlight language="lua">
2005 function input_filter(r)
2006     if not good then
2007         return -- Emp&ecirc;che tout simplement le filtrage et transmet le contenu original
2008     end
2009     coroutine.yield() -- attend des paquets de donn&eacute;es
2010     ... -- insert les filtres ici
2011 end
2012 </highlight>
2013 <p>
2014 Voir "<a href="#modifying_buckets">Modification de contenu avec les
2015 filtres Lua</a>" pour plus de d&eacute;tails.
2016 </p>
2017 </usage>
2018 </directivesynopsis>
2019
2020 <directivesynopsis>
2021 <name>LuaOutputFilter</name>
2022 <description>Fournit une fonction Lua pour le filtrage de contenu en
2023 sortie</description>
2024 <syntax>LuaOutputFilter filter_name /path/to/lua/script.lua function_name</syntax>
2025 <contextlist><context>server config</context> </contextlist>
2026 <compatibility>Disponible &agrave; partir de la version 2.5.0 du serveur HTTP
2027 Apache</compatibility>
2028
2029 <usage>
2030 <p>>Cette directive permet d'ajouter un filtre en sortie sous la forme
2031 d'une fonction Lua. A l'instar des filtres en sorties, les filtres en
2032 entr&eacute;e fonctionnent comme des sous-routines, intervenant dans un premier
2033 temps avant l'envoi du contenu des tampons, puis chaque fois qu'un
2034 paquet de donn&eacute;es doit &ecirc;tre transmis &agrave; la cha&icirc;ne, et &eacute;ventuellement
2035 produisant toute donn&eacute;e &agrave; ajouter aux donn&eacute;es en sortie. La variable
2036 globale <code>bucket</code> contient les paquets de donn&eacute;es tels qu'ils
2037 sont transmis au script Lua :
2038 </p>
2039
2040 <highlight language="config">
2041 LuaOutputFilter myOutputFilter /www/filter.lua output_filter
2042 &lt;FilesMatch "\.lua&gt;
2043   SetOutputFilter myOutputFilter
2044 &lt;/FilesMatch&gt;
2045 </highlight>
2046 <highlight language="lua">
2047 --[[
2048     Exemple de filtre en sortie qui &eacute;chappe toutes les entit&eacute;s HTML en
2049     sortie
2050 ]]--
2051 function output_filter(r)
2052     coroutine.yield("(Handled by myOutputFilter)&lt;br/&gt;\n") -- Ajoute des donn&eacute;es au d&eacute;but de la sortie, puis attend des paquets de donn&eacute;es &agrave; traiter
2053     while bucket do -- Pour chaque paquet, faire ...
2054         local output = r:escape_html(bucket) -- Echappe les donn&eacute;es en sortie
2055         coroutine.yield(output) -- Envoie les donn&eacute;es trait&eacute;es &agrave; la cha&icirc;ne
2056     end
2057     -- plus aucune donn&eacute;e &agrave; traiter.
2058 end
2059 </highlight>
2060 <p>
2061 Comme les filres en entr&eacute;e, le filtre en sortie peut interdire ou sauter un filtre s'il est
2062 consid&eacute;r&eacute; comme ind&eacute;sirable :
2063 </p>
2064 <highlight language="lua">
2065 function output_filter(r)
2066     if not r.content_type:match("text/html") then
2067         return -- Emp&ecirc;che tout simplement le filtrage et transmet le contenu original
2068     end
2069     coroutine.yield() -- attend des paquets de donn&eacute;es
2070     ... -- insert les filtres ici
2071 end
2072 </highlight>
2073 <note><title>Les filtres Lua avec <module>mod_filter</module></title>
2074 <p>Lorsqu'on utilise un filtre Lua comme fournisseur sous-jacent via la
2075 directive <directive module="mod_filter">FilterProvider</directive>, le
2076 filtrage ne fonctionnera que si <var>filter-name</var> est identique &agrave;
2077 <var>provider-name</var>.
2078 </p> </note>
2079
2080 <p>
2081 Voir "<a href="#modifying_buckets">Modification de contenu avec les
2082 filtres Lua</a>" pour plus de d&eacute;tails.
2083 </p>
2084
2085 </usage>
2086 </directivesynopsis>
2087
2088 </modulesynopsis>
2089