]> granicus.if.org Git - apache/blob - docs/manual/developer/lua.xml
xforms
[apache] / docs / manual / developer / lua.xml
1 <?xml version='1.0' encoding='UTF-8' ?>
2 <!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
3 <?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
4
5 <!-- $LastChangedRevision: 1353955 $ -->
6
7 <!--
8  Licensed to the Apache Software Foundation (ASF) under one or more
9  contributor license agreements.  See the NOTICE file distributed with
10  this work for additional information regarding copyright ownership.
11  The ASF licenses this file to You under the Apache License, Version 2.0
12  (the "License"); you may not use this file except in compliance with
13  the License.  You may obtain a copy of the License at
14
15      http://www.apache.org/licenses/LICENSE-2.0
16
17  Unless required by applicable law or agreed to in writing, software
18  distributed under the License is distributed on an "AS IS" BASIS,
19  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  See the License for the specific language governing permissions and
21  limitations under the License.
22 -->
23
24 <manualpage metafile="lua.xml.meta">
25 <parentdocument href="./">Developer</parentdocument>
26
27   <title>Creating hooks and scripts with mod_lua</title>
28
29 <summary>
30 <p>This document expands on the <module>mod_lua</module> documentation and explores
31  additional ways of using mod_lua for writing hooks and scripts.</p>
32 </summary>
33
34 <seealso><a href="../mod/mod_lua.html">mod_lua</a></seealso>
35 <seealso><a href="modguide.html">Developing modules for Apache 2.4</a></seealso>
36 <seealso><a href="request.html">Request Processing in Apache 2.4</a></seealso>
37 <seealso><a href="hooks.html">Apache 2.x Hook Functions</a></seealso>
38
39 <section id="introduction"><title>Introduction</title>
40 <section id="what"><title>What is mod_lua</title>
41 <p>
42 Stuff about what <module>mod_lua</module> is goes here.
43 </p>
44 </section>
45 <section id="contents"><title>What we will be discussing in this document</title>
46 <p>
47 This document will discuss several cases where <module>mod_lua</module> can be used 
48 to either ease up a phase of the request processing or create more transparency in 
49 the logic behind a decision made in a phase.
50 </p>
51
52 </section>
53
54 <section id="prerequisites"><title>Prerequisites</title>
55 <p>
56 First and foremost, you are expected to have a basic knowledge of how the Lua 
57 programming language works. In most cases, we will try to be as pedagogical 
58 as possible and link to documents describing the functions used in the 
59 examples, but there are also many cases where it is necessary to either 
60 just assume that "it works" or do some digging yourself into what the hows 
61 and whys of various function calls. 
62 </p>
63
64
65 </section>
66 </section>
67
68 <section id="enabling"><title>Optimizing mod_lua for production servers</title>
69
70 <section><title>Setting a scope for Lua states</title>
71 <p>
72 Setting the right <directive module="mod_lua">LuaScope</directive> setting 
73 for your Lua scripts can be essential to your server's 
74 performance. By default, the scope is set to <code>once</code>, which means 
75 that every call to a Lua script will spawn a new Lua state that handles that 
76 script and is destroyed immediately after. This option keeps the memory 
77 footprint of mod_lua low, but also affects the processing speed of a request. 
78 If you have the memory to spare, you can set the scope to <code>thread</code>, 
79 which will make mod_lua spawn a Lua state that lasts the entirity of a thread's 
80 lifetime, speeding up request processing by 2-3 times. Since mod_lua will create 
81 a state for each script, this may be an expensive move, memory-wise, so to 
82 compromise between speed and memory usage, you can choose the <code>server</code> 
83 option to create a pool of Lua states to be used. Each request for a Lua script or 
84 a hook function will then acquire a state from the pool and release it back when it's 
85 done using it, allowing you to still gain a significant performance increase, while 
86 keeping your memory footprint low. Some examples of possible settings are:
87 </p>
88 <highlight language="config">
89 LuaScope once
90 LuaScope thread
91 LuaScope server 5 40
92 </highlight>
93 <p>
94 As a general rule of thumb: If your server has none to low usage, use <code>once</code> 
95 or <code>request</code>, if your server has low to medium usage, use the <code>server</code> 
96 pool, and if it has high usage, use the <code>thread</code> setting. As your server's 
97 load increases, so will the number of states being actively used, and having your scope 
98 set to <code>once/request/conn</code> will stop being beneficial to your memory footprint.
99 </p>
100 <p>
101 <strong>Note:</strong> The <code>min</code> and <code>max</code> settings for the 
102 <code>server</code> scope denotes the minimum and maximum states to keep in a pool per 
103 server <em>process</em>, so keep this below your <code>ThreadsPerChild</code> limit.
104 </p>
105 </section>
106
107 <section><title>Using code caching</title>
108 <p>
109 By default, <module>mod_lua</module> stats each Lua script to determine whether a reload 
110 (and thus, a re-interpretation and re-compilation) of a script is required. This is managed 
111 through the <directive module="mod_lua">LuaCodeCache</directive> directive. If you are running 
112 your scripts on a production server, and you do not need to update them regularly, it may be 
113 advantageous to set this directive to the <code>forever</code> value, which will cause mod_lua 
114 to skip the stat process and always reuse the compiled byte-code from the first access to the 
115 script, thus speeding up the processing. For Lua hooks, this can prove to increase peformance, 
116 while for scripts handled by the <code>lua-script</code> handler, the increase in performance 
117 may be negligible, as files httpd will stat the files regardless.
118 </p>
119 </section>
120
121 <section><title>Keeping the scope clean</title>
122 <p>
123 For maximum performance, it is generally recommended that any initialization of libraries, 
124 constants and master tables be kept outside the handle's scope:
125 </p>
126 <highlight language="lua">
127 --[[ This is good practice ]]--
128 require "string"
129 require "someLibrary"
130 local masterTable = {}
131 local constant = "Foo bar baz"
132
133 function handle(r)
134     do_stuff()
135 end
136 </highlight>
137 <highlight language="lua">
138 --[[ This is bad practice ]]--
139 require "string"
140
141 function handle(r)
142     require "someLibrary"
143     local masterTable = {}
144     local constant = "Foo bar baz"
145     do_stuff()
146 end
147 </highlight>
148 </section>
149
150 </section>
151
152 <section id="basic_remap"><title>Example 1: A basic remapping module</title>
153 <p>
154
155 </p>
156
157 <highlight language="config">
158 LuaHookTranslateName /path/too/foo.lua remap
159 </highlight>
160
161
162 <!-- BEGIN EXAMPLE CODE -->
163 <highlight language="lua">
164 --[[
165     Simple remap example.
166     This example will rewrite /foo/test.bar to the physical file
167     /internal/test, somewhat like how mod_alias works.
168 ]]--
169
170 function remap(r)
171     -- Test if the URI matches our criteria
172     local barFile =  r.uri:match("/foo/([a-zA-Z0-9]+%.bar)")
173     if barFile then
174         r.filename = "/internal/" .. barFile
175     end
176     return apache2.OK
177 end
178 </highlight>
179 <!-- END EXAMPLE CODE -->
180
181
182 <!-- BEGIN EXAMPLE CODE -->
183 <highlight language="lua">
184 --[[
185     Advanced remap example.
186     This example will evaluate some conditions, and based on that, 
187     remap a file to one of two destinations, using a rewrite map.
188     
189 ]]--
190
191 local map = {
192       photos = {   
193                    source = [[^/photos/(.+)\.png$]], 
194                    destination = [[/uploads/www/$1.png]],
195                    proxy = false
196                 },
197       externals = {
198                    source = [[^/ext/(.*)$]],
199                    destination = [[http://www.example.com/$1]],
200                    proxy = true
201                 }
202 }
203
204 function interpolateString(s,v)
205     return s:gsub("%$(%d+)", function(a) return v[tonumber(a)] end)
206 end
207         
208 function remap(r)
209     -- browse through the rewrite map
210     for key, entry in pairs(map) do
211         -- Match source regex against URI
212         local match = apache2.regex(r, entry.source, r.uri) then
213         if match and match[0] then
214             r.filename = interpolateString(entry.destination, match)
215             -- Is this a proxied remap?
216             if entry.proxy then
217                 r.handler = "proxy-server" -- tell mod_proxy to handle this
218                 r.proxyreq = apache2.PROXYREQ_REVERSE -- We'll want to do a reverse proxy
219                 r.filename = "proxy:" .. r.filename -- Add the proxy scheme to the destination
220             end
221             return apache2.OK
222         end
223     end
224     return apache2.DECLINED
225 end
226 </highlight>
227 <!-- END EXAMPLE CODE -->
228
229 <p>
230 bla bla
231 </p>
232 </section>
233
234
235
236
237 <section id="mass_vhost"><title>Example 2: Mass virtual hosting</title>
238 <p>
239
240 </p>
241
242 <highlight language="config">
243 LuaHookTranslateName /path/too/foo.lua mass_vhost
244 </highlight>
245
246
247 <!-- BEGIN EXAMPLE CODE -->
248 <highlight language="lua">
249 --[[
250     Simple mass vhost script
251     This example will check a map for a virtual host and rewrite filename and 
252     document root accordingly.
253 ]]--
254
255 local vhosts = {
256     { domain = "example.com", home = "/www/example.com" },
257     { domain = "example.org", home = "/nfs/ext1/example.org" }
258 }
259
260 function mass_vhost(r)
261     -- Match against our hostname
262     for key, entry in pairs(vhosts) do
263         -- match against either host or *.host:
264         if apache2.strcmp_match(r.hostname, entry.domain) or
265            apache2.strcmp_match(r.hostname, "*." .. entry.domain) then
266             -- If it matches, rewrite filename and set document root
267             local filename = r.filename:sub(r.document_root:len()+1)
268             r.filename = entry.home .. filename
269             apahce2.set_document_root(entry.home)
270             return apache2.OK
271         end
272     end
273     return apache2.DECLINED
274 end
275 </highlight>
276 <!-- END EXAMPLE CODE -->
277
278
279 <!-- BEGIN EXAMPLE CODE -->
280 <highlight language="lua">
281 --[[
282     Advanced mass virtual hosting
283     This example will query a database for vhost entries and save them for
284     60 seconds before checking for updates. For best performance, such scripts
285     should generally be run with LuaScope set to 'thread' or 'server'
286 ]]--
287
288 local cached_vhosts = {}
289 local timeout = 60
290
291 -- Function for querying the database for saved vhost entries
292 function query_vhosts(host)
293     if not cached_vhosts[host] or (cached_vhosts[host] and cached_vhosts[host].updated &lt; os.time() - timeout) then
294         local db = apache2.dbopen(r,"mod_dbd")
295         local _host = db:escape(_host)
296         local res, err = db:query( ("SELECT `destination` FROM `vhosts` WHERE `hostname` = '%s' LIMIT 1"):format(_host) )
297         if res and #res == 1 then
298             cached_vhosts[host] = { updated = os.time(), destination = res[1][1] }
299         else
300             cached_vhosts[host] = nil
301         end
302         db:close()
303     end
304     if cached_vhosts[host] then 
305         return cached_vhosts[host].destination
306     else
307         return nil
308     end
309 end
310         
311 function mass_vhost(r)
312     -- Check whether the hostname is in our database
313     local destination = query_vhosts(r.hostname)
314     if destination then
315         -- If found, rewrite and change document root
316         local filename = r.filename:sub(r.document_root:len()+1)
317         r.filename = destination .. filename
318         apahce2.set_document_root(destination)
319         return apache2.OK
320     end
321     return apache2.DECLINED
322 end
323 </highlight>
324 <!-- END EXAMPLE CODE -->
325
326 <p>
327 bla bla
328 </p>
329 </section>
330
331
332
333
334 <section id="basic_auth"><title>Example 3: A basic authorization hook</title>
335
336 <highlight language="config">
337 LuaHookAuthChecker /path/too/foo.lua check_auth
338 </highlight>
339
340 <!-- BEGIN EXAMPLE CODE -->
341 <highlight language="lua">
342 --[[ 
343      A simple authentication hook that checks a table containing usernames and
344      passwords of two accounts.
345 ]]--
346 local accounts = {
347     bob  = 'somePassword',
348     jane = 'Iloveponies'
349 }
350
351 -- Function for parsing the Authorization header into a username and a password
352 function parse_auth(str)
353     local user,pass = nil, nil
354     if str and str:len() > 0 then
355         str = apache2.base64_decode(auth):sub(7));
356         user, pass = auth:match("([^:]+)%:([^:]+)")
357     end
358     return user, pass
359 end
360
361 -- The authentication hook
362 function check_auth(r)
363     local user, pass = parse_auth(r.headers_in['Authorization'])
364     local authenticated = false
365     if user and pass then
366         if accounts[user] and accounts[user] == pass then
367             authenticated = true
368             r.user = user
369         end
370     end
371     r.headers_out["WWW-Authenticate"] = 'Basic realm="Super secret zone"'
372     if not authenticated then
373         return 401
374     else
375         return apache2.OK
376     end
377 end
378 </highlight>
379 <!-- END EXAMPLE CODE -->
380
381
382 <!-- BEGIN EXAMPLE CODE -->
383 <highlight language="lua">
384 --[[ 
385      An advanced authentication checker with a database backend,
386      caching account entries for 1 minute
387 ]]--
388
389 local timeout = 60 -- Set account info to be refreshed every minute
390 local accounts = {}
391
392 -- Function for parsing the Authorization header into a username and a password
393 function parse_auth(str)
394     local user,pass = nil, nil
395     if str and str:len() > 0 then
396         str = apache2.base64_decode(auth):sub(7));
397         user, pass = auth:match("([^:]+)%:([^:]+)")
398     end
399     return user, pass
400 end
401
402 -- Function for querying the database for the account's password (stored as a salted SHA-1 hash)
403 function fetch_password(user)
404     if not accounts[user] or (accounts[user] and accounts[user].updated &lt; os.time() - timeout) then
405         local db = apache2.dbopen(r, "mod_dbd")
406         local usr = db:escape(user)
407         local res, err = db:query( ("SELECT `password` FROM `accounts` WHERE `user` = '%s' LIMIT 1"):format(usr) )
408         if res and #res == 1 then
409             accounts[user] = { updated = os.time(), password = res[1][1] }
410         else
411             accounts[user] = nil
412         end
413         db:close()
414     end
415     if accounts[user] then 
416         return accounts[user].password
417     else
418         return nil
419     end
420 end
421     
422 -- The authentication hook
423 function check_auth(r)
424     local user, pass = parse_auth(r.headers_in['Authorization'])
425     local authenticated = false
426     if user and pass then
427         pass = apache2.sha1("addSomeSalt" .. pass)
428         local stored_pass = fetch_password(user)
429         if stored_pass and pass == stored_pass then
430             authenticated = true
431             r.user = user
432         end
433     end
434     r.headers_out["WWW-Authenticate"] = 'Basic realm="Super secret zone"'
435     if not authenticated then
436         return 401
437     else
438         return apache2.OK
439     end
440 end
441 </highlight>
442 <!-- END EXAMPLE CODE -->
443
444
445 </section>
446
447 <section id="authz"><title>Example 4: Authorization using LuaAuthzProvider</title>
448
449 <highlight language="config">
450 LuaAuthzProvider rights /path/to/lua/script.lua rights_handler
451 &lt;Directory /www/private&gt;
452     Require rights member
453 &lt;/Directory&gt;
454 &lt;Directory /www/admin&gt;
455     Require rights admin
456 &lt;/Directory&gt;
457 </highlight>
458
459 <highlight language="lua">
460 --[[ 
461      This script has two user groups; members and admins, and whichever 
462      is refered to by the "Require rights" directive is checked to see
463      if the authenticated user belongs to this group.
464 ]]--
465
466 local members = { "rbowen", "humbedooh", "igalic", "covener" }
467 local admins = { "humbedooh" }
468
469 function rights_handler(r, what)
470     if r.user == nil then
471         return apache2.AUTHZ_AUTHZ_DENIED_NO_USER
472     end
473     if what == "member" then
474         for k, v in pairs(members) do
475             if r.user == v then
476                 return apache2.AUTHZ_GRANTED
477             end
478         end
479     elseif what == "admin" then
480         for k, v in pairs(admins) do
481             if r.user == v then
482                 return apache2.AUTHZ_GRANTED
483             end
484         end
485     end
486     return apache2.AUTHZ_DENIED
487 end
488 </highlight>
489 </section>
490
491 <section id="map_handler"><title>Example 5: Overlays using LuaMapHandler</title>
492
493 <highlight language="config">
494 LuaMapHandler ^/portal/([a-z]+)/   /path/to/lua/script.lua handle_$1
495 </highlight>
496 </section>
497
498 <section id="mod_status_lua"><title>Example 6: Basic Lua scripts</title>
499 </section>
500
501
502
503
504
505
506
507 <section id="String_manipulation">
508 <title>HTTPd bindings: String manipulation</title>
509 <p>
510 <a href="#apache2.base64_encode">apache2.base64_encode</a>
511 <br/>
512 <a href="#apache2.base64_decode">apache2.base64_decode</a>
513 <br/>
514 <a href="#apache2.escape">apache2.escape</a>
515 <br/>
516 <a href="#apache2.unescape">apache2.unescape</a>
517 <br/>
518 <a href="#apache2.escapehtml">apache2.escapehtml</a>
519 <br/>
520 <a href="#apache2.md5">apache2.md5</a>
521 <br/>
522 <a href="#apache2.sha1">apache2.sha1</a>
523 <br/>
524 <a href="#apache2.os_escape_path">apache2.os_escape_path</a>
525 <br/>
526 <a href="#apache2.escape_logitem">apache2.escape_logitem</a>
527 <br/>
528 </p>
529 <section id="apache2.base64_decode">
530 <title>apache2.base64_decode(
531     request_rec<em> r</em>,  string<em> string</em>
532     )
533     </title>
534 <p>
535 Decodes a base64-encoded string
536         </p>
537 <p>
538 <em>Arguments:</em>
539 </p>
540 <table border="1">
541 <tr>
542 <th>Argument</th>
543 <th>Description</th>
544 </tr>
545 <tr>
546 <td>r</td>
547 <td>The mod_lua request handle</td>
548 </tr>
549 <tr>
550 <td>string</td>
551 <td>The string to decode</td>
552 </tr>
553 </table>
554 <p>
555 <em>Return value(s):</em>
556 <br/>
557 The base64-decoded string.
558         </p>
559 <p>
560 <em>Example:</em>
561 </p>
562 <highlight language="lua">
563 local str = "This is a test"
564 local encoded = apache2.base64_encode(str)
565 local decoded = apache2.base64_decode(encoded)
566         </highlight>
567 <p> </p>
568 </section>
569 <section id="apache2.base64_encode">
570 <title>apache2.base64_encode(
571     request_rec<em> r</em>,  string<em> string</em>
572     )
573     </title>
574 <p>
575 Encodes a string using the base64 encoding scheme.
576         </p>
577 <p>
578 <em>Arguments:</em>
579 </p>
580 <table border="1">
581 <tr>
582 <th>Argument</th>
583 <th>Description</th>
584 </tr>
585 <tr>
586 <td>r</td>
587 <td>The mod_lua request handle</td>
588 </tr>
589 <tr>
590 <td>string</td>
591 <td>The string to encode</td>
592 </tr>
593 </table>
594 <p>
595 <em>Example:</em>
596 </p>
597 <highlight language="lua">
598 local str = "This is a test"
599 local encoded = apache2.base64_encode(str)
600 local decoded = apache2.base64_decode(encoded)
601         </highlight>
602 <p> </p>
603 </section>
604 <section id="apache2.escape">
605 <title>apache2.escape(
606     request_rec<em> r</em>,  string<em> string</em>
607     )
608     </title>
609 <p>
610 url-escapes a string
611         </p>
612 <p>
613 <em>Arguments:</em>
614 </p>
615 <table border="1">
616 <tr>
617 <th>Argument</th>
618 <th>Description</th>
619 </tr>
620 <tr>
621 <td>r</td>
622 <td>The mod_lua request handle</td>
623 </tr>
624 <tr>
625 <td>string</td>
626 <td>The string to escape</td>
627 </tr>
628 </table>
629 <p>
630 <em>Return value(s):</em>
631 <br/>
632 The URL-escaped string.
633         </p>
634 <p>
635 <em>Example:</em>
636 </p>
637 <highlight language="lua">
638 local str = "This is a test"
639 local escaped = apache2.escape(str)
640 print(escaped) -- prints "This+is+a+test"
641         </highlight>
642 <p> </p>
643 </section>
644 <section id="apache2.escape_logitem">
645 <title>apache2.escape_logitem(
646     request_rec<em> r</em>,  string<em> path</em>
647     )
648     </title>
649 <p>
650 Escape a string for logging
651         </p>
652 <p>
653 <em>Arguments:</em>
654 </p>
655 <table border="1">
656 <tr>
657 <th>Argument</th>
658 <th>Description</th>
659 </tr>
660 <tr>
661 <td>r</td>
662 <td>The mod_lua request handle</td>
663 </tr>
664 <tr>
665 <td>path</td>
666 <td>The string to escape</td>
667 </tr>
668 </table>
669 <p>
670 <em>Return value(s):</em>
671 <br/>
672 The converted string
673         </p>
674 <p> </p>
675 </section>
676 <section id="apache2.escapehtml">
677 <title>apache2.escapehtml(
678     request_rec<em> r</em>,  string<em> html</em>,  boolean<em> toasc</em>
679     )
680     </title>
681 <p>
682 Escapes HTML entities.
683         </p>
684 <p>
685 <em>Arguments:</em>
686 </p>
687 <table border="1">
688 <tr>
689 <th>Argument</th>
690 <th>Description</th>
691 </tr>
692 <tr>
693 <td>r</td>
694 <td>The mod_lua request handle</td>
695 </tr>
696 <tr>
697 <td>html</td>
698 <td>The HTML code to escape</td>
699 </tr>
700 <tr>
701 <td>toasc</td>
702 <td>Whether to escape all non-ASCI characters as &amp;#nnn;</td>
703 </tr>
704 </table>
705 <p>
706 <em>Return value(s):</em>
707 <br/>
708 The escaped HTML code.
709         </p>
710 <p>
711 <em>Example:</em>
712 </p>
713 <highlight language="lua">
714 local html = "&lt;b&gt;Testing!&lt;/b&gt;"
715 local escaped = apache2.escapehtml(html)
716 r:puts(escaped) -- prints "&amp;lt;b&amp;gt;Testing!&amp;lt;/b&amp;gt;"
717         </highlight>
718 <p> </p>
719 </section>
720 <section id="apache2.md5">
721 <title>apache2.md5(
722     request_rec<em> r</em>,  string<em> string</em>
723     )
724     </title>
725 <p>
726 Computes an MD5 digest sum based on a string (binary safe)
727         </p>
728 <p>
729 <em>Arguments:</em>
730 </p>
731 <table border="1">
732 <tr>
733 <th>Argument</th>
734 <th>Description</th>
735 </tr>
736 <tr>
737 <td>r</td>
738 <td>The mod_lua request handle</td>
739 </tr>
740 <tr>
741 <td>string</td>
742 <td>The (binary) string to digest</td>
743 </tr>
744 </table>
745 <p>
746 <em>Return value(s):</em>
747 <br/>
748 The MD5 digest sum of the data provided
749         </p>
750 <p>
751 <em>Example:</em>
752 </p>
753 <highlight language="lua">
754 local text = "The quick brown fox jumps over the lazy dog"
755 local md5 = apache2.md51(text)
756 r:puts(md5) -- prints out "9e107d9d372bb6826bd81d3542a419d6"
757         </highlight>
758 <p> </p>
759 </section>
760 <section id="apache2.os_escape_path">
761 <title>apache2.os_escape_path(
762     request_rec<em> r</em>,  string<em> path</em>,  boolean<em> partial</em>
763     )
764     </title>
765 <p>
766 convert an OS path to a URL in an OS dependant way.
767         </p>
768 <p>
769 <em>Arguments:</em>
770 </p>
771 <table border="1">
772 <tr>
773 <th>Argument</th>
774 <th>Description</th>
775 </tr>
776 <tr>
777 <td>r</td>
778 <td>The mod_lua request handle</td>
779 </tr>
780 <tr>
781 <td>path</td>
782 <td>The path to convert</td>
783 </tr>
784 <tr>
785 <td>partial</td>
786 <td>partial if set, assume that the path will be appended to something with a '/' in it (and thus does not prefix "./")</td>
787 </tr>
788 </table>
789 <p>
790 <em>Return value(s):</em>
791 <br/>
792 The converted URL
793         </p>
794 <p>
795 <em>Example:</em>
796 </p>
797 <highlight language="lua">
798 local path = ap_os_escape_path("C:/foo/bar.txt")
799         </highlight>
800 <p> </p>
801 </section>
802 <section id="apache2.sha1">
803 <title>apache2.sha1(
804     request_rec<em> r</em>,  string<em> string</em>
805     )
806     </title>
807 <p>
808 Computes an SHA-1 digest sum based on a string (binary safe)
809         </p>
810 <p>
811 <em>Arguments:</em>
812 </p>
813 <table border="1">
814 <tr>
815 <th>Argument</th>
816 <th>Description</th>
817 </tr>
818 <tr>
819 <td>r</td>
820 <td>The mod_lua request handle</td>
821 </tr>
822 <tr>
823 <td>string</td>
824 <td>The (binary) string to digest</td>
825 </tr>
826 </table>
827 <p>
828 <em>Return value(s):</em>
829 <br/>
830 The SHA-1 digest sum of the data provided
831         </p>
832 <p>
833 <em>Example:</em>
834 </p>
835 <highlight language="lua">
836 local text = "The quick brown fox jumps over the lazy dog"
837 local sha1 = apache2.sha1(text)
838 r:puts(sha1) -- prints out "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"
839         </highlight>
840 <p> </p>
841 </section>
842 <section id="apache2.unescape">
843 <title>apache2.unescape(
844     request_rec<em> r</em>,  string<em> string</em>
845     )
846     </title>
847 <p>
848 unescapes an URL-escaped string
849         </p>
850 <p>
851 <em>Arguments:</em>
852 </p>
853 <table border="1">
854 <tr>
855 <th>Argument</th>
856 <th>Description</th>
857 </tr>
858 <tr>
859 <td>r</td>
860 <td>The mod_lua request handle</td>
861 </tr>
862 <tr>
863 <td>string</td>
864 <td>The string to unescape</td>
865 </tr>
866 </table>
867 <p>
868 <em>Return value(s):</em>
869 <br/>
870 The URL-unescaped string
871         </p>
872 <p>
873 <em>Example:</em>
874 </p>
875 <highlight language="lua">
876 local str = "This+is+a+test"
877 local unescaped = apache2.unescape(str)
878 print(unescaped) -- prints "This is a test"
879         </highlight>
880 <p> </p>
881 </section>
882 </section>
883
884 <section id="Request_handling">
885 <title>HTTPd bindings: Request handling</title>
886 <p>
887 <a href="#apache2.requestbody">apache2.requestbody</a>
888 <br/>
889 <a href="#apache2.add_input_filter">apache2.add_input_filter</a>
890 <br/>
891 <a href="#apache2.get_basic_auth_pw">apache2.get_basic_auth_pw</a>
892 <br/>
893 <a href="#apache2.set_document_root">apache2.set_document_root</a>
894 <br/>
895 <a href="#apache2.set_context_prefix">apache2.set_context_prefix</a>
896 <br/>
897 <a href="#apache2.get_server_name_for_url">apache2.get_server_name_for_url</a>
898 <br/>
899 <a href="#apache2.set_keepalive">apache2.set_keepalive</a>
900 <br/>
901 <a href="#apache2.make_etag">apache2.make_etag</a>
902 <br/>
903 <a href="#apache2.send_interim_response">apache2.send_interim_response</a>
904 <br/>
905 </p>
906 <section id="apache2.add_input_filter">
907 <title>apache2.add_input_filter(
908     request_rec<em> r</em>,  string<em> filter</em>
909     )
910     </title>
911 <p>
912 Adds an input filter to the request
913         </p>
914 <p>
915 <em>Arguments:</em>
916 </p>
917 <table border="1">
918 <tr>
919 <th>Argument</th>
920 <th>Description</th>
921 </tr>
922 <tr>
923 <td>r</td>
924 <td>The mod_lua request handle</td>
925 </tr>
926 <tr>
927 <td>filter</td>
928 <td>The name of the filter handler to add</td>
929 </tr>
930 </table>
931 <p>
932 <em>Example:</em>
933 </p>
934 <highlight language="lua">
935 apache2.add_input_filter(r, "SPAM_FILTER") -- Check input for spam..?
936         </highlight>
937 <p> </p>
938 </section>
939 <section id="apache2.get_basic_auth_pw">
940 <title>apache2.get_basic_auth_pw(
941     request_rec<em> r</em>
942     )
943     </title>
944 <p>
945 Returns the password from a basic authorization request or nil if none was supplied
946         </p>
947 <p>
948 <em>Arguments:</em>
949 </p>
950 <table border="1">
951 <tr>
952 <th>Argument</th>
953 <th>Description</th>
954 </tr>
955 <tr>
956 <td>r</td>
957 <td>The mod_lua request handle</td>
958 </tr>
959 </table>
960 <p>
961 <em>Return value(s):</em>
962 <br/>
963 The password from a basic authorization request or nil if none was supplied
964         </p>
965 <p> </p>
966 </section>
967 <section id="apache2.get_server_name_for_url">
968 <title>apache2.get_server_name_for_url(
969     request_rec<em> r</em>
970     )
971     </title>
972 <p>
973 Get the current server name from the request for the purposes of using in a URL. 
974 If the server name is an IPv6 literal address, it will be returned in URL format (e.g., "[fe80::1]").
975         </p>
976 <p>
977 <em>Arguments:</em>
978 </p>
979 <table border="1">
980 <tr>
981 <th>Argument</th>
982 <th>Description</th>
983 </tr>
984 <tr>
985 <td>r</td>
986 <td>The mod_lua request handle</td>
987 </tr>
988 </table>
989 <p> </p>
990 </section>
991 <section id="apache2.make_etag">
992 <title>apache2.make_etag(
993     request_rec<em> r</em>,  boolean<em> force_weak</em>
994     )
995     </title>
996 <p>
997 Constructs an entity tag from the resource information.  If it's a real file, build in some of the file characteristics.
998         </p>
999 <p>
1000 <em>Arguments:</em>
1001 </p>
1002 <table border="1">
1003 <tr>
1004 <th>Argument</th>
1005 <th>Description</th>
1006 </tr>
1007 <tr>
1008 <td>r</td>
1009 <td>The mod_lua request handle</td>
1010 </tr>
1011 <tr>
1012 <td>force_weak</td>
1013 <td>force_weak Force the entity tag to be weak - it could be modified again in as short an interval.</td>
1014 </tr>
1015 </table>
1016 <p>
1017 <em>Return value(s):</em>
1018 <br/>
1019 The entity tag
1020         </p>
1021 <p> </p>
1022 </section>
1023 <section id="apache2.requestbody">
1024 <title>apache2.requestbody(
1025     request_rec<em> r</em>,  number<em> size</em>,  string<em> filename</em>
1026     )
1027     </title>
1028 <p>
1029 Reads the request body. If a filename is specified, the request body will be written to that file and the number of bytes written returned, otherwise, the full request body will be returned as a string.
1030         </p>
1031 <p>
1032 <em>Arguments:</em>
1033 </p>
1034 <table border="1">
1035 <tr>
1036 <th>Argument</th>
1037 <th>Description</th>
1038 </tr>
1039 <tr>
1040 <td>r</td>
1041 <td>The mod_lua request handle</td>
1042 </tr>
1043 <tr>
1044 <td>size</td>
1045 <td>The maximum size allowed, or 0/nil for unlimited size</td>
1046 </tr>
1047 <tr>
1048 <td>filename</td>
1049 <td>The file to save the output to, or nil to return it as a string</td>
1050 </tr>
1051 </table>
1052 <p>
1053 <em>Return value(s):</em>
1054 <br/>
1055 The number of bytes written if a filename was specified, otherwise it returns the entire request body as a string.
1056         </p>
1057 <p>
1058 <em>Example:</em>
1059 </p>
1060 <highlight language="lua">
1061 if tonumber(r.headers_in['Content-Length'] or 0) &lt; 10000 then
1062     local smallfile = apache2.requestbody(r, 10000) -- fetch a small file into memory
1063     r:puts("I saved the uploaded file in memory")
1064 else
1065     local read = apache2.requestbody(r, 0, "/path/to/tmp")
1066     r:puts("I saved the uploaded file in a temp directory. Total bytes written was: ", read)
1067 end
1068         </highlight>
1069 <p> </p>
1070 </section>
1071 <section id="apache2.send_interim_response">
1072 <title>apache2.send_interim_response(
1073     request_rec<em> r</em>,  boolean<em> send_headers</em>
1074     )
1075     </title>
1076 <p>
1077 Sends an interim (HTTP 1xx) response immediately.
1078         </p>
1079 <p>
1080 <em>Arguments:</em>
1081 </p>
1082 <table border="1">
1083 <tr>
1084 <th>Argument</th>
1085 <th>Description</th>
1086 </tr>
1087 <tr>
1088 <td>r</td>
1089 <td>The mod_lua request handle</td>
1090 </tr>
1091 <tr>
1092 <td>send_headers</td>
1093 <td>send_headers Whether to send&amp;clear headers in r-&gt;headers_out</td>
1094 </tr>
1095 </table>
1096 <p>
1097 <em>Example:</em>
1098 </p>
1099 <highlight language="lua">
1100 apache2.send_interim_response(r, false)
1101         </highlight>
1102 <p> </p>
1103 </section>
1104 <section id="apache2.set_context_prefix">
1105 <title>apache2.set_context_prefix(
1106     request_rec<em> r</em>,  string<em> prefix</em>,  string<em> document</em>
1107     )
1108     </title>
1109 <p>
1110 Set context_prefix and context_document_root for a request.
1111         </p>
1112 <p>
1113 <em>Arguments:</em>
1114 </p>
1115 <table border="1">
1116 <tr>
1117 <th>Argument</th>
1118 <th>Description</th>
1119 </tr>
1120 <tr>
1121 <td>r</td>
1122 <td>The mod_lua request handle</td>
1123 </tr>
1124 <tr>
1125 <td>prefix</td>
1126 <td>The URI prefix, without trailing slash</td>
1127 </tr>
1128 <tr>
1129 <td>document</td>
1130 <td>The corresponding directory on disk, without trailing slash</td>
1131 </tr>
1132 </table>
1133 <p> </p>
1134 </section>
1135 <section id="apache2.set_document_root">
1136 <title>apache2.set_document_root(
1137     request_rec<em> r</em>,  string<em> root</em>
1138     )
1139     </title>
1140 <p>
1141 Sets the document root of the request.
1142         </p>
1143 <p>
1144 <em>Arguments:</em>
1145 </p>
1146 <table border="1">
1147 <tr>
1148 <th>Argument</th>
1149 <th>Description</th>
1150 </tr>
1151 <tr>
1152 <td>r</td>
1153 <td>The mod_lua request handle</td>
1154 </tr>
1155 <tr>
1156 <td>root</td>
1157 <td>root</td>
1158 </tr>
1159 </table>
1160 <p>
1161 <em>Example:</em>
1162 </p>
1163 <highlight language="lua">
1164 -- Suppose our real document root is /var/bar, then...
1165 if r.hostname == "www.foo.com" then
1166     apache2.set_document_root(r, "/www/foo") -- change document root on the fly
1167 end
1168         </highlight>
1169 <p> </p>
1170 </section>
1171 <section id="apache2.set_keepalive">
1172 <title>apache2.set_keepalive(
1173     request_rec<em> r</em>
1174     )
1175     </title>
1176 <p>
1177 Sets the keepalive status for this request
1178         </p>
1179 <p>
1180 <em>Arguments:</em>
1181 </p>
1182 <table border="1">
1183 <tr>
1184 <th>Argument</th>
1185 <th>Description</th>
1186 </tr>
1187 <tr>
1188 <td>r</td>
1189 <td>The mod_lua request handle</td>
1190 </tr>
1191 </table>
1192 <p>
1193 <em>Return value(s):</em>
1194 <br/>
1195 True if keepalive can be set, false otherwise
1196         </p>
1197 <p> </p>
1198 </section>
1199 </section>
1200
1201 <section id="Parser_functions">
1202 <title>HTTPd bindings: Parser functions</title>
1203 <p>
1204 <a href="#apache2.expr">apache2.expr</a>
1205 <br/>
1206 <a href="#apache2.regex">apache2.regex</a>
1207 <br/>
1208 <a href="#apache2.strcmp_match">apache2.strcmp_match</a>
1209 <br/>
1210 </p>
1211 <section id="apache2.expr">
1212 <title>apache2.expr(
1213     request_rec<em> r</em>,  string<em> expression</em>
1214     )
1215     </title>
1216 <p>
1217 Evaluates an ap_expr (think &lt;If ...&gt;) expression and returns true if the expression is true, false otherwise. A second value containing an error string is returned if the expression is invalid.
1218         </p>
1219 <p>
1220 <em>Arguments:</em>
1221 </p>
1222 <table border="1">
1223 <tr>
1224 <th>Argument</th>
1225 <th>Description</th>
1226 </tr>
1227 <tr>
1228 <td>r</td>
1229 <td>The mod_lua request handle</td>
1230 </tr>
1231 <tr>
1232 <td>expression</td>
1233 <td>expression</td>
1234 </tr>
1235 </table>
1236 <p>
1237 <em>Return value(s):</em>
1238 <br/>
1239 True if the expression evaluates as true, false if the expression doesn't evaluate as true or if an error occurred. If an error occurred during parsing, a second value will be returned, containng the error string.
1240         </p>
1241 <p>
1242 <em>Example:</em>
1243 </p>
1244 <highlight language="lua">
1245 if apache2.expr("%{REQUEST_URI} =~ /force-gzip") then
1246     r:addoutputfilter("DEFLATE")
1247 end
1248         </highlight>
1249 <p> </p>
1250 </section>
1251 <section id="apache2.regex">
1252 <title>apache2.regex(
1253     request_rec<em> r</em>,  string<em> expression</em>,  string<em> source</em>
1254     )
1255     </title>
1256 <p>
1257 Evaluates a regular expression and, if it matches the source string, captures the variables and returns the matches as a table. On error, it returns nil.
1258         </p>
1259 <p>
1260 <em>Arguments:</em>
1261 </p>
1262 <table border="1">
1263 <tr>
1264 <th>Argument</th>
1265 <th>Description</th>
1266 </tr>
1267 <tr>
1268 <td>r</td>
1269 <td>The mod_lua request handle</td>
1270 </tr>
1271 <tr>
1272 <td>expression</td>
1273 <td>expression to match for</td>
1274 </tr>
1275 <tr>
1276 <td>source</td>
1277 <td>the source string to capture from</td>
1278 </tr>
1279 </table>
1280 <p>
1281 <em>Return value(s):</em>
1282 <br/>
1283 True if the expression evaluates as true, false if the expression doesn't evaluate as true or if an error occurred. If an error occurred during parsing, a second value will be returned, containng the error string.
1284         </p>
1285 <p>
1286 <em>Example:</em>
1287 </p>
1288 <highlight language="lua">
1289 local matches = apache2.regex(r, [[(\S+) kitty]], "Hello kitty")
1290 if matches and matches[1] then 
1291     r:puts("You said ", matches[1], " to kitty")
1292 end
1293         </highlight>
1294 <p> </p>
1295 </section>
1296 <section id="apache2.strcmp_match">
1297 <title>apache2.strcmp_match(
1298     string<em> str</em>,  string<em> expexted</em>,  boolean<em> ignoreCase</em>
1299     )
1300     </title>
1301 <p>
1302 Determines if a string matches a pattern containing the wildcards '?' or '*'
1303         </p>
1304 <p>
1305 <em>Arguments:</em>
1306 </p>
1307 <table border="1">
1308 <tr>
1309 <th>Argument</th>
1310 <th>Description</th>
1311 </tr>
1312 <tr>
1313 <td>str</td>
1314 <td>The string to check</td>
1315 </tr>
1316 <tr>
1317 <td>expexted</td>
1318 <td>The pattern to match against</td>
1319 </tr>
1320 <tr>
1321 <td>ignoreCase</td>
1322 <td>Whether to ignore case when matching</td>
1323 </tr>
1324 </table>
1325 <p>
1326 <em>Return value(s):</em>
1327 <br/>
1328 True if the two strings match, false otherwise.
1329         </p>
1330 <p>
1331 <em>Example:</em>
1332 </p>
1333 <highlight language="lua">
1334 if apache2.strcmp_match("foo.bar", "foo.*") then
1335     r:puts("It matches!")
1336 end
1337         </highlight>
1338 <p> </p>
1339 </section>
1340 </section>
1341
1342 <section id="Server_settings">
1343 <title>HTTPd bindings: Server settings</title>
1344 <p>
1345 <a href="#apache2.add_version_component">apache2.add_version_component</a>
1346 <br/>
1347 <a href="#apache2.mpm_query">apache2.mpm_query</a>
1348 <br/>
1349 <a href="#apache2.terminate">apache2.terminate</a>
1350 <br/>
1351 <a href="#apache2.scoreboard_process">apache2.scoreboard_process</a>
1352 <br/>
1353 <a href="#apache2.scoreboard_worker">apache2.scoreboard_worker</a>
1354 <br/>
1355 <a href="#apache2.module_info">apache2.module_info</a>
1356 <br/>
1357 <a href="#apache2.loaded_modules">apache2.loaded_modules</a>
1358 <br/>
1359 <a href="#apache2.runtime_dir_relative">apache2.runtime_dir_relative</a>
1360 <br/>
1361 <a href="#apache2.server_info">apache2.server_info</a>
1362 <br/>
1363 <a href="#apache2.state_query">apache2.state_query</a>
1364 <br/>
1365 <a href="#apache2.custom_response">apache2.custom_response</a>
1366 <br/>
1367 <a href="#apache2.exists_config_define">apache2.exists_config_define</a>
1368 <br/>
1369 </p>
1370 <section id="apache2.add_version_component">
1371 <title>apache2.add_version_component(
1372     request_rec<em> r</em>,  string<em> component</em>
1373     )
1374     </title>
1375 <p>
1376 Adds a component to the server description and banner strings
1377         </p>
1378 <p>
1379 <em>Arguments:</em>
1380 </p>
1381 <table border="1">
1382 <tr>
1383 <th>Argument</th>
1384 <th>Description</th>
1385 </tr>
1386 <tr>
1387 <td>r</td>
1388 <td>The mod_lua request handle</td>
1389 </tr>
1390 <tr>
1391 <td>component</td>
1392 <td>The component to add</td>
1393 </tr>
1394 </table>
1395 <p>
1396 <em>Example:</em>
1397 </p>
1398 <highlight language="lua">
1399 if not apache2.banner():match("FooModule") then -- Make sure we haven't added it already
1400     apache2.add_version_component(r, "FooModule/1.0")
1401 end
1402         </highlight>
1403 <p> </p>
1404 </section>
1405 <section id="apache2.custom_response">
1406 <title>apache2.custom_response(
1407     request_rec<em> r</em>,  number<em> status</em>,  string<em> string</em>
1408     )
1409     </title>
1410 <p>
1411 Install a custom response handler for a given status
1412         </p>
1413 <p>
1414 <em>Arguments:</em>
1415 </p>
1416 <table border="1">
1417 <tr>
1418 <th>Argument</th>
1419 <th>Description</th>
1420 </tr>
1421 <tr>
1422 <td>r</td>
1423 <td>The mod_lua request handle</td>
1424 </tr>
1425 <tr>
1426 <td>status</td>
1427 <td>The status for which the custom response should be used</td>
1428 </tr>
1429 <tr>
1430 <td>string</td>
1431 <td>The custom response.  This can be a static string, a file or a URL</td>
1432 </tr>
1433 </table>
1434 <p>
1435 <em>Example:</em>
1436 </p>
1437 <highlight language="lua">
1438 apache2.custom_response(r, 404, "Not found!!")
1439         </highlight>
1440 <p> </p>
1441 </section>
1442 <section id="apache2.exists_config_define">
1443 <title>apache2.exists_config_define(
1444     string<em> name</em>
1445     )
1446     </title>
1447 <p>
1448 Checks for a definition from the server command line
1449         </p>
1450 <p>
1451 <em>Arguments:</em>
1452 </p>
1453 <table border="1">
1454 <tr>
1455 <th>Argument</th>
1456 <th>Description</th>
1457 </tr>
1458 <tr>
1459 <td>name</td>
1460 <td>The define to check for</td>
1461 </tr>
1462 </table>
1463 <p>
1464 <em>Example:</em>
1465 </p>
1466 <highlight language="lua">
1467 if apache2.exists_config_define("FOO") then
1468     r:puts("This server was started with -DFOO")
1469 end
1470         </highlight>
1471 <p> </p>
1472 </section>
1473 <section id="apache2.loaded_modules">
1474 <title>apache2.loaded_modules(
1475     
1476     )
1477     </title>
1478 <p>
1479 Returns a table containing the name (c filename) of all loaded modules
1480         </p>
1481 <p>
1482 <em>Arguments:</em>
1483 </p>
1484 <p>None</p>
1485 <p>
1486 <em>Return value(s):</em>
1487 <br/>
1488 A table containing the name (c filename) of all loaded modules
1489         </p>
1490 <p> </p>
1491 </section>
1492 <section id="apache2.module_info">
1493 <title>apache2.module_info(
1494     string<em> c</em>,  string<em> file</em>
1495     )
1496     </title>
1497 <p>
1498 Returns information about a specific module (if loaded)
1499         </p>
1500 <p>
1501 <em>Arguments:</em>
1502 </p>
1503 <table border="1">
1504 <tr>
1505 <th>Argument</th>
1506 <th>Description</th>
1507 </tr>
1508 <tr>
1509 <td>c</td>
1510 <td>c</td>
1511 </tr>
1512 <tr>
1513 <td>file</td>
1514 <td>file</td>
1515 </tr>
1516 </table>
1517 <p>
1518 <em>Return value(s):</em>
1519 <br/>
1520 The various commands available to this module as a table, or nil if the module wasn't found.
1521         </p>
1522 <p> </p>
1523 </section>
1524 <section id="apache2.mpm_query">
1525 <title>apache2.mpm_query(
1526     number<em> i</em>
1527     )
1528     </title>
1529 <p>
1530 Queries the MPM for a specific value
1531         </p>
1532 <p>
1533 <em>Arguments:</em>
1534 </p>
1535 <table border="1">
1536 <tr>
1537 <th>Argument</th>
1538 <th>Description</th>
1539 </tr>
1540 <tr>
1541 <td>i</td>
1542 <td>i</td>
1543 </tr>
1544 </table>
1545 <p>
1546 <em>Return value(s):</em>
1547 <br/>
1548 The queried value
1549         </p>
1550 <p> </p>
1551 </section>
1552 <section id="apache2.runtime_dir_relative">
1553 <title>apache2.runtime_dir_relative(
1554     request_rec<em> r</em>,  string<em> file</em>
1555     )
1556     </title>
1557 <p>
1558 Returns the path of a file relative to the default runtime directory
1559         </p>
1560 <p>
1561 <em>Arguments:</em>
1562 </p>
1563 <table border="1">
1564 <tr>
1565 <th>Argument</th>
1566 <th>Description</th>
1567 </tr>
1568 <tr>
1569 <td>r</td>
1570 <td>The mod_lua request handle</td>
1571 </tr>
1572 <tr>
1573 <td>file</td>
1574 <td>file</td>
1575 </tr>
1576 </table>
1577 <p>
1578 <em>Return value(s):</em>
1579 <br/>
1580 The path of a file relative to the default runtime directory
1581         </p>
1582 <p> </p>
1583 </section>
1584 <section id="apache2.scoreboard_process">
1585 <title>apache2.scoreboard_process(
1586     request_rec<em> r</em>,  number<em> child</em>
1587     )
1588     </title>
1589 <p>
1590 Returns the scoreboard for a server daemon as a table
1591         </p>
1592 <p>
1593 <em>Arguments:</em>
1594 </p>
1595 <table border="1">
1596 <tr>
1597 <th>Argument</th>
1598 <th>Description</th>
1599 </tr>
1600 <tr>
1601 <td>r</td>
1602 <td>The mod_lua request handle</td>
1603 </tr>
1604 <tr>
1605 <td>child</td>
1606 <td>The server child to query</td>
1607 </tr>
1608 </table>
1609 <p>
1610 <em>Return value(s):</em>
1611 <br/>
1612 The scoreboard for a server daemon as a table
1613         </p>
1614 <p> </p>
1615 </section>
1616 <section id="apache2.scoreboard_worker">
1617 <title>apache2.scoreboard_worker(
1618     request_rec<em> r</em>,  number<em> child</em>,  number<em> thread</em>
1619     )
1620     </title>
1621 <p>
1622 Returns the scoreboard for a single thread as a table
1623         </p>
1624 <p>
1625 <em>Arguments:</em>
1626 </p>
1627 <table border="1">
1628 <tr>
1629 <th>Argument</th>
1630 <th>Description</th>
1631 </tr>
1632 <tr>
1633 <td>r</td>
1634 <td>The mod_lua request handle</td>
1635 </tr>
1636 <tr>
1637 <td>child</td>
1638 <td>The server child to query</td>
1639 </tr>
1640 <tr>
1641 <td>thread</td>
1642 <td>The thread to query</td>
1643 </tr>
1644 </table>
1645 <p>
1646 <em>Return value(s):</em>
1647 <br/>
1648 The scoreboard for a single thread as a table
1649         </p>
1650 <p> </p>
1651 </section>
1652 <section id="apache2.server_info">
1653 <title>apache2.server_info(
1654     
1655     )
1656     </title>
1657 <p>
1658 Returns a table with information about the server program
1659         </p>
1660 <p>
1661 <em>Arguments:</em>
1662 </p>
1663 <p>None</p>
1664 <p>
1665 <em>Return value(s):</em>
1666 <br/>
1667 A table with information about the server program
1668         </p>
1669 <p> </p>
1670 </section>
1671 <section id="apache2.state_query">
1672 <title>apache2.state_query(
1673     number<em> field</em>
1674     )
1675     </title>
1676 <p>
1677 Query the server for some state information
1678         </p>
1679 <p>
1680 <em>Arguments:</em>
1681 </p>
1682 <table border="1">
1683 <tr>
1684 <th>Argument</th>
1685 <th>Description</th>
1686 </tr>
1687 <tr>
1688 <td>field</td>
1689 <td>Which information is requested</td>
1690 </tr>
1691 </table>
1692 <p>
1693 <em>Example:</em>
1694 </p>
1695 <highlight language="lua">
1696 local gen = apache2.state_query(2)
1697 r:puts("This is generation no. " .. gen .. " of the top-level parent")
1698         </highlight>
1699 <p> </p>
1700 </section>
1701 <section id="apache2.terminate">
1702 <title>apache2.terminate(
1703     
1704     )
1705     </title>
1706 <p>
1707 Kills off a server process. This has no other use than to show how dangerous mod_lua can be ;)
1708         </p>
1709 <p>
1710 <em>Arguments:</em>
1711 </p>
1712 <p>None</p>
1713 <p> </p>
1714 </section>
1715 </section>
1716 <section id="Database_connectivity">
1717 <title>HTTPd bindings: Database connectivity</title>
1718 <p>
1719 <a href="#apache2.dbopen">apache2.dbopen</a>
1720 <br/>
1721 <a href="#db:query">db:query</a>
1722 <br/>
1723 <a href="#db:do">db:do</a>
1724 <br/>
1725 <a href="#db:close">db:close</a>
1726 <br/>
1727 </p>
1728 <section id="apache2.dbopen">
1729 <title>apache2.dbopen(
1730     request_rec<em> r</em>,  string<em> dbtype</em>,  string<em> conn_string</em>
1731     )
1732     </title>
1733 <p>
1734 Opens up a new database connection. See the DB functions for mod_pLua for more info on this.
1735         </p>
1736 <p>
1737 <em>Arguments:</em>
1738 </p>
1739 <table border="1">
1740 <tr>
1741 <th>Argument</th>
1742 <th>Description</th>
1743 </tr>
1744 <tr>
1745 <td>r</td>
1746 <td>The mod_lua request handle</td>
1747 </tr>
1748 <tr>
1749 <td>dbtype</td>
1750 <td>dbtype</td>
1751 </tr>
1752 <tr>
1753 <td>conn_string</td>
1754 <td>connection string</td>
1755 </tr>
1756 </table>
1757 <p>
1758 <em>Return value(s):</em>
1759 <br/>
1760 The database connection as a table with functions, or nil if the connection failed. If a connection failed, a second argument (string) with the error code is returned.
1761         </p>
1762 <p>
1763 <em>Example:</em>
1764 </p>
1765 <highlight language="lua">
1766 local db, error = apache2.dbopen(r, "mod_dbd")
1767 if error then
1768     r:puts("DB error: ", error)
1769 else
1770     -- DB stuff here
1771 end
1772         </highlight>
1773 <p> </p>
1774 </section>
1775 <section id="db:close">
1776 <title>db:close(
1777     request_rec<em> r</em>
1778     )
1779     </title>
1780 <p>
1781 Closes a database connection
1782         </p>
1783 <p>
1784 <em>Arguments:</em>
1785 </p>
1786 <table border="1">
1787 <tr>
1788 <th>Argument</th>
1789 <th>Description</th>
1790 </tr>
1791 <tr>
1792 <td>r</td>
1793 <td>The mod_lua request handle</td>
1794 </tr>
1795 </table>
1796 <p>
1797 <em>Example:</em>
1798 </p>
1799 <highlight language="lua">
1800 local db = apache2.dbopen(r, "mod_dbd") -- open a db connection
1801 db:close() -- close it down
1802         </highlight>
1803 <p> </p>
1804 </section>
1805 <section id="db:do">
1806 <title>db:do(
1807     request_rec<em> r</em>,  string<em> query</em>
1808     )
1809     </title>
1810 <p>
1811 Executes a statement that doesn't return a result set
1812         </p>
1813 <p>
1814 <em>Arguments:</em>
1815 </p>
1816 <table border="1">
1817 <tr>
1818 <th>Argument</th>
1819 <th>Description</th>
1820 </tr>
1821 <tr>
1822 <td>r</td>
1823 <td>The mod_lua request handle</td>
1824 </tr>
1825 <tr>
1826 <td>query</td>
1827 <td>The SQL statement to execute</td>
1828 </tr>
1829 </table>
1830 <p>
1831 <em>Return value(s):</em>
1832 <br/>
1833 If the statement is valid, a table of results are returned. If an error occurred, the first return value is false and the second return value is a string containing an error message.
1834         </p>
1835 <p>
1836 <em>Example:</em>
1837 </p>
1838 <highlight language="lua">
1839 local db = apache2.dbopen(r, "mod_dbd")
1840 local affected = db:do("DELETE FROM `table` WHERE 1")
1841 if affected then
1842     r:puts("Affected ", affected, " rows")
1843 end
1844         </highlight>
1845 <p> </p>
1846 </section>
1847 <section id="db:query">
1848 <title>db:query(
1849     request_rec<em> r</em>,  string<em> query</em>
1850     )
1851     </title>
1852 <p>
1853 Queries the database for information using the specified statement.
1854         </p>
1855 <p>
1856 <em>Arguments:</em>
1857 </p>
1858 <table border="1">
1859 <tr>
1860 <th>Argument</th>
1861 <th>Description</th>
1862 </tr>
1863 <tr>
1864 <td>r</td>
1865 <td>The mod_lua request handle</td>
1866 </tr>
1867 <tr>
1868 <td>query</td>
1869 <td>The SQL statement to execute</td>
1870 </tr>
1871 </table>
1872 <p>
1873 <em>Return value(s):</em>
1874 <br/>
1875 If the statement is valid, a table of results are returned. If an error occurred, the first return value is false and the second return value is a string containing an error message.
1876         </p>
1877 <p>
1878 <em>Example:</em>
1879 </p>
1880 <highlight language="lua">
1881 local db = apache2.dbopen(r, "mod_dbd")
1882 local result, error = db:query("SELECT * FROM `table` WHERE 1")
1883 if result then
1884     for key, value in pairs(result)
1885         r:puts( ("row %s: %s\n"):format(key, table.concat(value, ", ")) )
1886     end
1887 end
1888         </highlight>
1889 <p> </p>
1890 </section>
1891 </section>
1892 <section id="Miscellaneous">
1893 <title>HTTPd bindings: Miscellaneous</title>
1894 <p>
1895 <a href="#apache2.clock">apache2.clock</a>
1896 <br/>
1897 <a href="#apache2.sleep">apache2.sleep</a>
1898 <br/>
1899 </p>
1900 <section id="apache2.clock">
1901 <title>apache2.clock(
1902     
1903     )
1904     </title>
1905 <p>
1906 Returns the current time in microseconds.
1907         </p>
1908 <p>
1909 <em>Arguments:</em>
1910 </p>
1911 <p>None</p>
1912 <p>
1913 <em>Return value(s):</em>
1914 <br/>
1915 The current time in microseconds.
1916         </p>
1917 <p> </p>
1918 </section>
1919 <section id="apache2.sleep">
1920 <title>apache2.sleep(
1921     number<em> seconds</em>
1922     )
1923     </title>
1924 <p>
1925 Sleeps for a while. Floating point values can be used to sleep for less than a second.
1926         </p>
1927 <p>
1928 <em>Arguments:</em>
1929 </p>
1930 <table border="1">
1931 <tr>
1932 <th>Argument</th>
1933 <th>Description</th>
1934 </tr>
1935 <tr>
1936 <td>seconds</td>
1937 <td>The number of seconds to sleep.</td>
1938 </tr>
1939 </table>
1940 <p>
1941 <em>Example:</em>
1942 </p>
1943 <highlight language="lua">
1944 r:puts("this is ")
1945 apache2.flush(r)
1946 apache2.sleep(0.25) -- sleep for a quarter second.
1947 r:puts("delayed")
1948         </highlight>
1949 <p> </p>
1950 </section>
1951 </section>
1952
1953
1954 </manualpage>