mod_lua.html.en revision 374adaff9445c620465679c1e5fa624c171d9783
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu This file is generated from xml source: DO NOT EDIT
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="/style/css/prettify.css" />
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<script src="/style/scripts/prettify.js" type="text/javascript">
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<link href="/images/favicon.ico" rel="shortcut icon" /></head>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<p class="apache">Apache HTTP Server Version 2.5</p>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<img alt="" src="/images/feather.gif" /></div>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<div class="up"><a href="./"><img title="<-" alt="<-" src="/images/left.gif" /></a></div>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<a href="http://www.apache.org/">Apache</a> > <a href="http://httpd.apache.org/">HTTP Server</a> > <a href="http://httpd.apache.org/docs/">Documentation</a> > <a href="../">Version 2.5</a> > <a href="./">Modules</a></div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<div id="preamble"><h1>Apache Module mod_lua</h1>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p><span>Available Languages: </span><a href="/en/mod/mod_lua.html" title="English"> en </a> |
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<a href="/fr/mod/mod_lua.html" hreflang="fr" rel="alternate" title="Fran�ais"> fr </a></p>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td>Provides Lua hooks into various portions of the httpd
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<tr><th><a href="module-dict.html#Status">Status:</a></th><td>Experimental</td></tr>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<tr><th><a href="module-dict.html#ModuleIdentifier">Module�Identifier:</a></th><td>lua_module</td></tr>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<tr><th><a href="module-dict.html#SourceFile">Source�File:</a></th><td>mod_lua.c</td></tr>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<tr><th><a href="module-dict.html#Compatibility">Compatibility:</a></th><td>2.3 and later</td></tr></table>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p>This module allows the server to be extended with scripts written in the
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian MaederLua programming language. The extension points (hooks) available with
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<code class="module"><a href="/mod/mod_lua.html">mod_lua</a></code> include many of the hooks available to
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maedernatively compiled Apache HTTP Server modules, such as mapping requests to
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederfiles, generating dynamic responses, access control, authentication, and
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederauthorization</p>
e418cbe496169f326cdaa6b4ba60f23d74c6b0bdChristian Maeder<p>More information on the Lua programming language can be found at the
e418cbe496169f326cdaa6b4ba60f23d74c6b0bdChristian Maeder<a href="http://www.lua.org/">the Lua website</a>.</p>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<div class="note"><code>mod_lua</code> is still in experimental state.
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian MaederUntil it is declared stable, usage and behavior may change
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederat any time, even between stable releases of the 2.4.x series.
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian MaederBe sure to check the CHANGES file before upgrading.</div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p>This module holds a great deal of power over httpd, which is both a
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederstrength and a potential security risk. It is <strong>not</strong> recommended
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederthat you use this module on a server that is shared with users you do not
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maedertrust, as it can be abused to change the internal workings of httpd.</p>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<div id="quickview"><h3 class="directives">Directives</h3>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luaauthzprovider">LuaAuthzProvider</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luacodecache">LuaCodeCache</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookaccesschecker">LuaHookAccessChecker</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookauthchecker">LuaHookAuthChecker</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookcheckuserid">LuaHookCheckUserID</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookfixups">LuaHookFixups</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookinsertfilter">LuaHookInsertFilter</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahooklog">LuaHookLog</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahookmaptostorage">LuaHookMapToStorage</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahooktranslatename">LuaHookTranslateName</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luahooktypechecker">LuaHookTypeChecker</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luainherit">LuaInherit</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luainputfilter">LuaInputFilter</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luamaphandler">LuaMapHandler</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luaoutputfilter">LuaOutputFilter</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luapackagecpath">LuaPackageCPath</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luapackagepath">LuaPackagePath</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luaquickhandler">LuaQuickHandler</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luaroot">LuaRoot</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#luascope">LuaScope</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#basicconf">Basic Configuration</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#writinghandlers">Writing Handlers</a></li>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#writingauthzproviders">Writing Authorization Providers</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#writinghooks">Writing Hooks</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#datastructures">Data Structures</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#functions">Built in functions</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#logging">Logging Functions</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#apache2">apache2 Package</a></li>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#modifying_buckets">Modifying contents with Lua filters</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<li><img alt="" src="/images/down.gif" /> <a href="#databases">Database connectivity</a></li>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder</ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<h2><a name="basicconf" id="basicconf">Basic Configuration</a></h2>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<p>The basic module loading directive is</p>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<code>mod_lua</code> provides a handler named <code>lua-script</code>,
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederwhich can be used with an <code>AddHandler</code> directive:</p>
f52a4838c101d52bbbd689f6b51f2c1c9202f0a8Christian MaederAddHandler lua-script .lua
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian MaederThis will cause <code>mod_lua</code> to handle requests for files
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederending in <code>.lua</code> by invoking that file's
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<p>For more flexibility, see <code class="directive">LuaMapHandler</code>.
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<h2><a name="writinghandlers" id="writinghandlers">Writing Handlers</a></h2>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<p> In the Apache HTTP Server API, the handler is a specific kind of hook
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederresponsible for generating the response. Examples of modules that include a
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederhandler are <code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code>, <code class="module"><a href="/mod/mod_cgi.html">mod_cgi</a></code>,
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederand <code class="module"><a href="/mod/mod_status.html">mod_status</a></code>.</p>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<p><code>mod_lua</code> always looks to invoke a Lua function for the handler, rather than
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maederjust evaluating a script body CGI style. A handler function looks
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maedersomething like this:</p>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder-- example handler
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederrequire "string"
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder This is the default method name for Lua handlers, see the optional
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder function-name in the LuaMapHandler directive to choose a different
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederfunction handle(r)
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder if r.method == 'GET' then
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder r:puts("Hello Lua World!\n")
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder for k, v in pairs( r:parseargs() ) do
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder r:puts( string.format("%s: %s\n", k, v) )
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder elseif r.method == 'POST' then
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder r:puts("Hello Lua World!\n")
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder for k, v in pairs( r:parsebody() ) do
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder r:puts( string.format("%s: %s\n", k, v) )
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder elseif r.method == 'PUT' then
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder-- use our own Error contents
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder r:puts("Unsupported HTTP method " .. r.method)
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder-- use the ErrorDocument
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian MaederThis handler function just prints out the uri or form encoded
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederarguments to a plaintext page.
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian MaederThis means (and in fact encourages) that you can have multiple
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederhandlers (or hooks, or filters) in the same script.
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<h2><a name="writingauthzproviders" id="writingauthzproviders">Writing Authorization Providers</a></h2>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p><code class="module"><a href="/mod/mod_authz_core.html">mod_authz_core</a></code> provides a high-level interface to
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederauthorization that is much easier to use than using into the relevant
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederhooks directly. The first argument to the
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<code class="directive"><a href="/mod/mod_authz_core.html#require">Require</a></code> directive gives
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederthe name of the responsible authorization provider. For any
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<code class="directive"><a href="/mod/mod_authz_core.html#require">Require</a></code> line,
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder<code class="module"><a href="/mod/mod_authz_core.html">mod_authz_core</a></code> will call the authorization provider
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maederof the given name, passing the rest of the line as parameters. The
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maederprovider will then check authorization and pass the result as return
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p>The authz provider is normally called before authentication. If it needs to
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederknow the authenticated user name (or if the user will be authenticated at
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederall), the provider must return <code>apache2.AUTHZ_DENIED_NO_USER</code>.
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian MaederThis will cause authentication to proceed and the authz provider to be
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maedercalled a second time.</p>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder<p>The following authz provider function takes two arguments, one ip
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maederaddress and one user name. It will allow access from the given ip address
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederwithout authentication, or if the authenticated user matches the second
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maederrequire 'apache2'
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederfunction authz_check_foo(r, ip, user)
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder elseif r.user == nil then
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder elseif r.user == user then
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<p>The following configuration registers this function as provider
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<code>foo</code> and configures it for URL <code>/</code>:</p>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian MaederLuaAuthzProvider foo authz_provider.lua authz_check_foo
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<Location />
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder Require foo 10.1.2.3 john_doe
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder</Location>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<h2><a name="writinghooks" id="writinghooks">Writing Hooks</a></h2>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder<p>Hook functions are how modules (and Lua scripts) participate in the
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederprocessing of requests. Each type of hook exposed by the server exists for
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maedera specific purpose, such as mapping requests to the file system,
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maederperforming access control, or setting mime types:</p>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luaquickhandler">LuaQuickHandler</a></code></td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td>This is the first hook that will be called after a request has
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder been mapped to a host or virtual host</td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luahooktranslatename">LuaHookTranslateName</a></code></td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>This phase translates the requested URI into a filename on the
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder system. Modules such as <code class="module"><a href="/mod/mod_alias.html">mod_alias</a></code> and
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder <code class="module"><a href="/mod/mod_rewrite.html">mod_rewrite</a></code> operate in this phase.</td>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder <td><code class="directive"><a href="#luahookmaptostorage">LuaHookMapToStorage</a></code></td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td>This phase maps files to their physical, cached or external/proxied storage.
1fac054baed931dc57f0e41dd0ade39adac28c49Christian Maeder It can be used by proxy or caching modules</td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luahookaccesschecker">LuaHookAccessChecker</a></code></td>
1fac054baed931dc57f0e41dd0ade39adac28c49Christian Maeder <td>This phase checks whether a client has access to a resource. This
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder phase is run before the user is authenticated, so beware.
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td><code class="directive"><a href="#luahookcheckuserid">LuaHookCheckUserID</a></code></td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td>This phase it used to check the negotiated user ID</td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luahookauthchecker">LuaHookAuthChecker</a></code> or
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <code class="directive"><a href="#luaauthzprovider">LuaAuthzProvider</a></code></td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td>This phase authorizes a user based on the negotiated credentials, such as
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder user ID, client certificate etc.
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luahooktypechecker">LuaHookTypeChecker</a></code></td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>This phase checks the requested file and assigns a content type and
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder a handler to it</td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td><code class="directive"><a href="#luahookfixups">LuaHookFixups</a></code></td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>This is the final "fix anything" phase before the content handlers
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder are run. Any last-minute changes to the request should be made here.</td>
e2ca90217abd35b3d5f98bfe73ecffb34badd837Christian Maeder <td>fx. <code>.lua</code> files or through <code class="directive"><a href="#luamaphandler">LuaMapHandler</a></code></td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>This is where the content is handled. Files are read, parsed, some are run,
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder and the result is sent to the client</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td><code class="directive"><a href="#luahooklog">LuaHookLog</a></code></td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>Once a request has been handled, it enters several logging phases,
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder which logs the request in either the error or access log. Mod_lua
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder is able to hook into the start of this and control logging output.</td>
1fac054baed931dc57f0e41dd0ade39adac28c49Christian Maeder<p>Hook functions are passed the request object as their only argument
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder(except for LuaAuthzProvider, which also gets passed the arguments from
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederthe Require directive).
1fac054baed931dc57f0e41dd0ade39adac28c49Christian MaederThey can return any value, depending on the hook, but most commonly
1fac054baed931dc57f0e41dd0ade39adac28c49Christian Maederthey'll return OK, DONE, or DECLINED, which you can write in Lua as
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder<code>apache2.OK</code>, <code>apache2.DONE</code>, or
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder<code>apache2.DECLINED</code>, or else an HTTP status code.</p>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder-- example hook that rewrites the URI to a filesystem path.
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederrequire 'apache2'
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederfunction translate_name(r)
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder if r.uri == "/translate-name" then
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder r.filename = r.document_root .. "/find_me.txt"
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder -- we don't care about this URL, give another module a chance
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder--[[ example hook that rewrites one URI to another URI. It returns a
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder apache2.DECLINED to give other URL mappers a chance to work on the
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder substitution, including the core translate_name hook which maps based
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder on the DocumentRoot.
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder Note: Use the early/late flags in the directive to make it run before
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder or after mod_alias.
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederrequire 'apache2'
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maederfunction translate_name(r)
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder if r.uri == "/translate-name" then
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder<h2><a name="datastructures" id="datastructures">Data Structures</a></h2>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <p>The request_rec is mapped in as a userdata. It has a metatable
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder which lets you do useful things with it. For the most part it
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder has the same fields as the request_rec struct, many of which are writable as
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder well as readable. (The table fields' content can be changed, but the
b7413fd7a18b060775364d271c3e706c07227b13Christian Maeder fields themselves cannot be set to different tables.)</p>
5c37a9e2ecfe62f615c383db85582a67e3511e10Christian Maeder <table class="bordered"><tr class="header">
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>The AllowOverride options applied to the current request.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>If an authentication check was made, this is set to the type
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder of authentication (f.x. <code>basic</code>)</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>The query string arguments extracted from the request
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder (f.x. <code>foo=bar&name=johnsmith</code>)</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>Set to true if this is an HTTP/0.9 style request
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder (e.g. <code>GET /foo</code> (with no headers) )</td>
45ad02e03fb913ba373d8fdcfe50244be3df31eaChristian Maeder <td>The realm name used for authorization (if applicable).</td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>The server banner, f.x. <code>Apache HTTP Server/2.4.3 openssl/0.9.8c</code></td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>The basic auth password sent with this request, if any</td>
ee31a8a5f5d786472f2b5dfb271b38e6d401fa35Christian Maeder <td>The canonical filename of the request</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>The content encoding of the current request</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td>The content type of the current request, as determined in the
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder type_check phase (f.x. <code>image/gif</code> or <code>text/html</code>)</td>
7bffb8b0e6cae4bb7ecb59b99327add6106c06b9Christian Maeder <td><code>context_document_root</code></td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>MIME header environment for the response, printed even on errors and
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder persist across internal redirects</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The file name that the request maps to, f.x. /www/example.com/foo.txt. This can be
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder changed in the translate-name or map-to-storage phases of a request to allow the
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder default handler (or script handlers) to serve a different file than what was requested.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The name of the <a href="/handler.html">handler</a> that should serve this request, f.x.
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <code>lua-script</code> if it is to be served by mod_lua. This is typically set by the
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <code class="directive"><a href="/mod/mod_mime.html#addhandler">AddHandler</a></code> or <code class="directive"><a href="/mod/core.html#sethandler">SetHandler</a></code>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder directives, but could also be set via mod_lua to allow another handler to serve up a specific request
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder that would otherwise not be served by it.
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>MIME header environment from the request. This contains headers such as <code>Host,
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>MIME header environment for the response.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The host name, as set by the <code>Host:</code> header or by a full URI.</td>
6596e6462e9356ac01f15a6dcada971e1f346b63Christian Maeder <td>Whether or not this request is done via HTTPS</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>Whether this request is the initial request or a sub-request</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The size limit of the request body for this request, or 0 if no limit.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The ID to identify request in access and error log.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The request method, f.x. <code>GET</code> or <code>POST</code>.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>A list of notes that can be passed on from one module to another.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The Options directive applied to the current request.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The PATH_INFO extracted from this request.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The server port used by the request.</td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>The protocol used, f.x. <code>HTTP/1.1</code></td>
133498fca44f178d10e2eb6d965ce3442d2e2e32Christian Maeder <td>Denotes whether this is a proxy request or not. This value is generally set in
6596e6462e9356ac01f15a6dcada971e1f346b63Christian Maeder the post_read_request/translate_name phase of a request.</td>
6596e6462e9356ac01f15a6dcada971e1f346b63Christian Maeder <td>The contents of the <code>Range:</code> header.</td>
6596e6462e9356ac01f15a6dcada971e1f346b63Christian Maeder <td>The number of bytes remaining to be read from the request body.</td>
<td>The (current) HTTP return code for this request, f.x. <code>200</code> or <code>404</code>.</td>
<td>If an authentication check has been made, this is set to the name of the authenticated user.</td>
r.usleep(500000) -- fake processing time for 0.5 sec. and repeat
r:sendfile(filename) -- sends an entire file to the client, using sendfile if supported by the current platform:
local url = "http://foo.bar/1 2 3 & 4 + 5"
local escaped = r:escape(url) -- returns 'http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5'
local url = "http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5"
local unescaped = r:unescape(url) -- returns 'http://foo.bar/1 2 3 & 4 + 5'
local url = r:construct_url(r.uri)
r.mpm_query(number) -- Queries the server for MPM information using ap_mpm_query:
local mpm = r.mpm_query(14)
r:scoreboard_process(a) -- Queries the server for information about the process at position <code>a</code>:
r:puts("Server 1 has PID " .. process.pid)
r:scoreboard_worker(a, b) -- Queries for information about the worker thread, <code>b</code>, in process <code>a</code>:
r:puts("Server 1's thread 1 has thread ID " .. thread.tid .. " and is in " .. thread.status .. " status")
r.module_info(module_name) -- Queries the server for information about a module
for k, v in pairs(mod.commands) do
r:runtime_dir_relative(filename) -- Compute the name of a run-time file (e.g., shared memory "file")
r:set_context_info(prefix, docroot) -- Sets the context prefix and context document root for a request
r.strcmp_match(string, pattern) -- Checks if 'string' matches 'pattern' using strcmp_match (globs).
r:puts("foobar.com matches foo*.com")
r:set_keepalive() -- Sets the keepalive status for a request. Returns true if possible, false otherwise.
r:custom_response(status_code, string) -- Construct and set a custom response for a given status code.
r.exists_config_define(string) -- Checks whether a configuration definition exists or not:
if r.exists_config_define("FOO") then
r:puts("This file exists and was last modified at: " .. info.modified)
r:regex(string, pattern [,flags]) -- Runs a regular expression match on a string, returning captures if matched:
r.usleep(number_of_microseconds) -- Puts the script to sleep for a given number of microseconds.
r:dbacquire(dbType[, dbParams]) -- Acquires a connection to a database and returns a database class.
r:touch(file [,mtime]) -- Sets the file modification time to current time or to optional mtime msec value.
local dir = r.context_document_root
local ftype = (info.filetype == 2) and "[dir] " or "[file]"
r:puts( ("%s %s %10i %s\n"):format(ftype, mtime, info.size, f) )
r:setcookie("foo", "bar and stuff", false, os.time() + 86400)
<dt>apache2.PROXYREQ_NONE, apache2.PROXYREQ_PROXY, apache2.PROXYREQ_REVERSE, apache2.PROXYREQ_RESPONSE</dt>
<dd>internal constants used by <code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code></dd>
<dt>apache2.AUTHZ_DENIED, apache2.AUTHZ_GRANTED, apache2.AUTHZ_NEUTRAL, apache2.AUTHZ_GENERAL_ERROR, apache2.AUTHZ_DENIED_NO_USER</dt>
<dd>internal constants used by <code class="module"><a href="/mod/mod_authz_core.html">mod_authz_core</a></code></dd>
Filter functions implemented via <code class="directive"><a href="#luainputfilter">LuaInputFilter</a></code>
coroutine.yield([optional header to be prepended to the content])
coroutine.yield(output) -- Return our new content to the filter chain
coroutine.yield([optional footer to be appended to the content])
<p>The example below shows how to acquire a database handle and return information from a table:</p>
r:puts( string.format("Name: %s, Age: %s<br/>", row[1], row[2]) )
To utilize <code class="module"><a href="/mod/mod_dbd.html">mod_dbd</a></code>, specify <code>mod_dbd</code>
local result, errmsg = statement:select("John Doe", 123) -- inject the values "John Doe" and 123 into the statement
<div class="directive-section"><h2><a name="LuaAuthzProvider" id="LuaAuthzProvider">LuaAuthzProvider</a> <a name="luaauthzprovider" id="luaauthzprovider">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Plug an authorization provider function into <code class="module"><a href="/mod/mod_authz_core.html">mod_authz_core</a></code>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaAuthzProvider provider_name /path/to/lua/script.lua function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>2.4.3 and later</td></tr>
with the <code class="directive"><a href="/mod/mod_authz_core.html#require">Require</a></code> directive:</p>
LuaAuthzProvider foo authz.lua authz_check_foo
return apache2.AUTHZ_GRANTED
<div class="directive-section"><h2><a name="LuaCodeCache" id="LuaCodeCache">LuaCodeCache</a> <a name="luacodecache" id="luacodecache">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Configure the compiled code cache.</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaCodeCache stat|forever|never</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>LuaCodeCache stat</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<div class="directive-section"><h2><a name="LuaHookAccessChecker" id="LuaHookAccessChecker">LuaHookAccessChecker</a> <a name="luahookaccesschecker" id="luahookaccesschecker">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the access_checker phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookAccessChecker /path/to/lua/script.lua hook_function_name [early|late]</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>The optional third argument is supported in 2.3.15 and later</td></tr>
<div class="directive-section"><h2><a name="LuaHookAuthChecker" id="LuaHookAuthChecker">LuaHookAuthChecker</a> <a name="luahookauthchecker" id="luahookauthchecker">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the auth_checker phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookAuthChecker /path/to/lua/script.lua hook_function_name [early|late]</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>The optional third argument is supported in 2.3.15 and later</td></tr>
auth = r.headers_in['Authorization']
r.user = 'foo'
if r.user == nil then
r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
elseif r.user == "foo" then
r:debug("authcheck: user='" .. r.user .. "'")
r.err_headers_out['WWW-Authenticate'] = 'Basic realm="WallyWorld"'
return apache2.OK
<div class="directive-section"><h2><a name="LuaHookCheckUserID" id="LuaHookCheckUserID">LuaHookCheckUserID</a> <a name="luahookcheckuserid" id="luahookcheckuserid">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the check_user_id phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookCheckUserID /path/to/lua/script.lua hook_function_name [early|late]</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>The optional third argument is supported in 2.3.15 and later</td></tr>
<div class="directive-section"><h2><a name="LuaHookFixups" id="LuaHookFixups">LuaHookFixups</a> <a name="luahookfixups" id="luahookfixups">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the fixups phase of a request
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookFixups /path/to/lua/script.lua hook_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<div class="directive-section"><h2><a name="LuaHookInsertFilter" id="LuaHookInsertFilter">LuaHookInsertFilter</a> <a name="luahookinsertfilter" id="luahookinsertfilter">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the insert_filter phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookInsertFilter /path/to/lua/script.lua hook_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<div class="directive-section"><h2><a name="LuaHookLog" id="LuaHookLog">LuaHookLog</a> <a name="luahooklog" id="luahooklog">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the access log phase of a request
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookLog /path/to/lua/script.lua log_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
if math.random(1,2) == 1 then
f:write("Something secret happened at " .. r.uri .. "\n")
return apache2.DONE -- Tell httpd not to use the regular logging functions
return apache2.OK -- tell httpd to log it.
<div class="directive-section"><h2><a name="LuaHookMapToStorage" id="LuaHookMapToStorage">LuaHookMapToStorage</a> <a name="luahookmaptostorage" id="luahookmaptostorage">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the map_to_storage phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookMapToStorage /path/to/lua/script.lua hook_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
local input = io.open(filename, "r")
if r.filename:match("%.png$") then -- Only match PNG files
local file = cached_files[r.filename] -- Check cache entries
file = read_file(r.filename) -- Read file into cache
r.status = 200
r:info(("Sent %s to client from cache"):format(r.filename))
return apache2.DONE -- skip default handler for PNG files
return apache2.DECLINED -- If we had nothing to do, let others serve this.
<div class="directive-section"><h2><a name="LuaHookTranslateName" id="LuaHookTranslateName">LuaHookTranslateName</a> <a name="luahooktranslatename" id="luahooktranslatename">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the translate name phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookTranslateName /path/to/lua/script.lua hook_function_name [early|late]</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>The optional third argument is supported in 2.3.15 and later</td></tr>
until one of them returns apache2.OK. If your hook doesn't
apache2.DECLINED. If the request should stop processing, then
if r.uri == "/" then
return apache2.OK
return apache2.DECLINED
<div class="note"><h3>Context</h3><p>This directive is not valid in <code class="directive"><a href="/mod/core.html#directory"><Directory></a></code>, <code class="directive"><a href="/mod/core.html#files"><Files></a></code>, or htaccess
<div class="directive-section"><h2><a name="LuaHookTypeChecker" id="LuaHookTypeChecker">LuaHookTypeChecker</a> <a name="luahooktypechecker" id="luahooktypechecker">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the type_checker phase of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaHookTypeChecker /path/to/lua/script.lua hook_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
r.handler = "gifWizard" -- tell the gifWizard module to handle this
return apache2.OK
return apache2.DECLINED
<div class="directive-section"><h2><a name="LuaInherit" id="LuaInherit">LuaInherit</a> <a name="luainherit" id="luainherit">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Controls how parent configuration sections are merged into children</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaInherit none|parent-first|parent-last</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>LuaInherit parent-first</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>2.4.0 and later</td></tr>
<div class="directive-section"><h2><a name="LuaInputFilter" id="LuaInputFilter">LuaInputFilter</a> <a name="luainputfilter" id="luainputfilter">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a Lua function for content input filtering</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaInputFilter filter_name /path/to/lua/script.lua function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>2.5.0 and later</td></tr>
coroutine.yield() -- Yield and wait for buckets
local output = string.upper(bucket) -- Convert all POST data to uppercase
coroutine.yield(output) -- Send converted data down the chain
coroutine.yield("&filterSignature=1234") -- Append signature at the end
coroutine.yield() -- wait for buckets
<div class="directive-section"><h2><a name="LuaMapHandler" id="LuaMapHandler">LuaMapHandler</a> <a name="luamaphandler" id="luamaphandler">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Map a path to a lua handler</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
LuaMapHandler /(\w+)/(\w+) /scripts/$1.lua handle_$2
<div class="directive-section"><h2><a name="LuaOutputFilter" id="LuaOutputFilter">LuaOutputFilter</a> <a name="luaoutputfilter" id="luaoutputfilter">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a Lua function for content output filtering</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaOutputFilter filter_name /path/to/lua/script.lua function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>2.5.0 and later</td></tr>
coroutine.yield("(Handled by myOutputFilter)<br/>\n") -- Prepend some data to the output,
coroutine.yield(output) -- Send converted data down the chain
coroutine.yield() -- wait for buckets
<div class="note"><h3>Lua filters with <code class="module"><a href="/mod/mod_filter.html">mod_filter</a></code></h3>
<code class="directive"><a href="/mod/mod_filter.html#filterprovider">FilterProvider</a></code> directive, filtering
<div class="directive-section"><h2><a name="LuaPackageCPath" id="LuaPackageCPath">LuaPackageCPath</a> <a name="luapackagecpath" id="luapackagecpath">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Add a directory to lua's package.cpath</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaPackageCPath /path/to/include/?.soa</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
conventions as lua. This just munges the package.cpath in the
<div class="directive-section"><h2><a name="LuaPackagePath" id="LuaPackagePath">LuaPackagePath</a> <a name="luapackagepath" id="luapackagepath">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Add a directory to lua's package.path</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaPackagePath /path/to/include/?.lua</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
conventions as lua. This just munges the package.path in the
<div class="directive-section"><h2><a name="LuaQuickHandler" id="LuaQuickHandler">LuaQuickHandler</a> <a name="luaquickhandler" id="luaquickhandler">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Provide a hook for the quick handler of request processing</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaQuickHandler /path/to/script.lua hook_function_name</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
As this phase is run before anything else, directives such as <code class="directive"><a href="/mod/core.html#location"><Location></a></code> or <code class="directive"><a href="/mod/core.html#directory"><Directory></a></code> are void in this phase, just as
<div class="note"><h3>Context</h3><p>This directive is not valid in <code class="directive"><a href="/mod/core.html#directory"><Directory></a></code>, <code class="directive"><a href="/mod/core.html#files"><Files></a></code>, or htaccess
<div class="directive-section"><h2><a name="LuaRoot" id="LuaRoot">LuaRoot</a> <a name="luaroot" id="luaroot">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Specify the base path for resolving relative paths for mod_lua directives</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaRoot /path/to/a/directory</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
<div class="directive-section"><h2><a name="LuaScope" id="LuaScope">LuaScope</a> <a name="luascope" id="luascope">Directive</a></h2>
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>One of once, request, conn, thread -- default is once</td></tr>
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LuaScope once|request|conn|thread|server [min] [max]</code></td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>LuaScope once</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
states are pooled, allowing f.x. 1000 threads to share only 100 Lua states,
<p><span>Available Languages: </span><a href="/en/mod/mod_lua.html" title="English"> en </a> |
<a href="/fr/mod/mod_lua.html" hreflang="fr" rel="alternate" title="Fran�ais"> fr </a></p>
</div><div class="top"><a href="#page-header"><img src="/images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
var comments_identifier = 'http://httpd.apache.org/docs/trunk/mod/mod_lua.html';
if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
d.write('<div id="comments_thread"><\/div>');
var s = d.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
(d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
<p class="apache">Copyright 2013 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/quickreference.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--