From 2a463b3cd73c32ee9dcd508248d0194923f435f4 Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Sat, 29 Mar 2014 21:56:19 +0100 Subject: Imported Upstream version 2.4.9 --- docs/manual/mod/mod_lua.html.en | 518 ++++++++++++++-------------------------- 1 file changed, 177 insertions(+), 341 deletions(-) (limited to 'docs/manual/mod/mod_lua.html.en') diff --git a/docs/manual/mod/mod_lua.html.en b/docs/manual/mod/mod_lua.html.en index 0264de8a..8fbe093f 100644 --- a/docs/manual/mod/mod_lua.html.en +++ b/docs/manual/mod/mod_lua.html.en @@ -9,7 +9,7 @@ - @@ -100,18 +100,17 @@ trust, as it can be abused to change the internal workings of httpd.

The basic module loading directive is

-
-    LoadModule lua_module modules/mod_lua.so
-
+
LoadModule lua_module modules/mod_lua.so

mod_lua provides a handler named lua-script, -which can be used with an AddHandler directive:

+which can be used with a SetHandler or +AddHandler directive:

-
-AddHandler lua-script .lua
-
+
<Files *.lua>
+    SetHandler lua-script
+</Files>

@@ -170,8 +169,7 @@ function handle(r) return 501 end return apache2.OK -end - +end

@@ -226,18 +224,15 @@ function authz_check_foo(r, ip, user) else return apache2.AUTHZ_DENIED end -end - +end

The following configuration registers this function as provider foo and configures it for URL /:

-
-LuaAuthzProvider foo authz_provider.lua authz_check_foo
+
LuaAuthzProvider foo authz_provider.lua authz_check_foo
 <Location />
   Require foo 10.1.2.3 john_doe
-</Location>
-
+</Location>
top
@@ -342,8 +337,7 @@ function translate_name(r) end -- we don't care about this URL, give another module a chance return apache2.DECLINED -end - +end @@ -366,8 +360,7 @@ function translate_name(r) return apache2.DECLINED end return apache2.DECLINED -end - +end
top
@@ -669,293 +662,216 @@ end

The request_rec object has (at least) the following methods:

-
-r:flush()   -- flushes the output buffer.
+
r:flush()   -- flushes the output buffer.
             -- Returns true if the flush was successful, false otherwise.
 
 while we_have_stuff_to_send do
     r:puts("Bla bla bla\n") -- print something to client
     r:flush() -- flush the buffer (send to client)
     r.usleep(500000) -- fake processing time for 0.5 sec. and repeat
-end
-
+end
-
-r:addoutputfilter(name|function) -- add an output filter:
+
r:addoutputfilter(name|function) -- add an output filter:
 
-r:addoutputfilter("fooFilter") -- add the fooFilter to the output stream
-
+r:addoutputfilter("fooFilter") -- add the fooFilter to the output stream
-
-r:sendfile(filename) -- sends an entire file to the client, using sendfile if supported by the current platform:
+
r:sendfile(filename) -- sends an entire file to the client, using sendfile if supported by the current platform:
 
 if use_sendfile_thing then
     r:sendfile("/var/www/large_file.img")
-end
-
+end
-
-r:parseargs() -- returns two tables; one standard key/value table for regular GET data, 
+
r:parseargs() -- returns two tables; one standard key/value table for regular GET data, 
               -- and one for multi-value data (fx. foo=1&foo=2&foo=3):
 
 local GET, GETMULTI = r:parseargs()
-r:puts("Your name is: " .. GET['name'] or "Unknown")
-
+r:puts("Your name is: " .. GET['name'] or "Unknown")
-
-r:parsebody([sizeLimit]) -- parse the request body as a POST and return two lua tables,
+
r:parsebody([sizeLimit]) -- parse the request body as a POST and return two lua tables,
                          -- just like r:parseargs().
                          -- An optional number may be passed to specify the maximum number 
                          -- of bytes to parse. Default is 8192 bytes:
                  
 local POST, POSTMULTI = r:parsebody(1024*1024)
-r:puts("Your name is: " .. POST['name'] or "Unknown")
-
+r:puts("Your name is: " .. POST['name'] or "Unknown")
-
-r:puts("hello", " world", "!") -- print to response body, self explanatory
-
+
r:puts("hello", " world", "!") -- print to response body, self explanatory
-
-r:write("a single string") -- print to response body, self explanatory
-
+
r:write("a single string") -- print to response body, self explanatory
-
-r:escape_html("<html>test</html>") -- Escapes HTML code and returns the escaped result
-
+
r:escape_html("<html>test</html>") -- Escapes HTML code and returns the escaped result
-
-r:base64_encode(string) -- Encodes a string using the Base64 encoding standard:
+
r:base64_encode(string) -- Encodes a string using the Base64 encoding standard:
 
-local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q=
-
+local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q=
-
-r:base64_decode(string) -- Decodes a Base64-encoded string:
+
r:base64_decode(string) -- Decodes a Base64-encoded string:
 
-local decoded = r:base64_decode("VGhpcyBpcyBhIHRlc3Q=") -- returns 'This is a test'
-
+local decoded = r:base64_decode("VGhpcyBpcyBhIHRlc3Q=") -- returns 'This is a test'
-
-r:md5(string) -- Calculates and returns the MD5 digest of a string (binary safe):
+
r:md5(string) -- Calculates and returns the MD5 digest of a string (binary safe):
 
-local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339
-
+local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339
-
-r:sha1(string) -- Calculates and returns the SHA1 digest of a string (binary safe):
+
r:sha1(string) -- Calculates and returns the SHA1 digest of a string (binary safe):
 
-local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19
-
+local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19
-
-r:escape(string) -- URL-Escapes a string:
+
r:escape(string) -- URL-Escapes a string:
 
 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 escaped = r:escape(url) -- returns 'http%3a%2f%2ffoo.bar%2f1+2+3+%26+4+%2b+5'
-
-r:unescape(string) -- Unescapes an URL-escaped string:
+
r:unescape(string) -- Unescapes an URL-escaped string:
 
 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 unescaped = r:unescape(url) -- returns 'http://foo.bar/1 2 3 & 4 + 5'
-
-r:construct_url(string) -- Constructs an URL from an URI
+
r:construct_url(string) -- Constructs an URL from an URI
 
-local url = r:construct_url(r.uri) 
-
+local url = r:construct_url(r.uri)
-
-r.mpm_query(number) -- Queries the server for MPM information using ap_mpm_query:
+
r.mpm_query(number) -- Queries the server for MPM information using ap_mpm_query:
 
 local mpm = r.mpm_query(14)
 if mpm == 1 then
     r:puts("This server uses the Event MPM")
-end
-
+end
-
-r:expr(string) -- Evaluates an expr string.
+
r:expr(string) -- Evaluates an expr string.
 
 if r:expr("%{HTTP_HOST} =~ /^www/") then
     r:puts("This host name starts with www")
-end
-
+end
-
-r:scoreboard_process(a) -- Queries the server for information about the process at position a:
+
r:scoreboard_process(a) -- Queries the server for information about the process at position a:
 
 local process = r:scoreboard_process(1)
-r:puts("Server 1 has PID " .. process.pid)
-
+r:puts("Server 1 has PID " .. process.pid)
-
-r:scoreboard_worker(a, b) -- Queries for information about the worker thread, b, in process a:
+
r:scoreboard_worker(a, b) -- Queries for information about the worker thread, b, in process a:
 
 local thread = r:scoreboard_worker(1, 1)
-r:puts("Server 1's thread 1 has thread ID " .. thread.tid .. " and is in " .. thread.status .. " status")
-
+r:puts("Server 1's thread 1 has thread ID " .. thread.tid .. " and is in " .. thread.status .. " status")
-
-r:clock() -- Returns the current time with microsecond precision
-
+
r:clock() -- Returns the current time with microsecond precision
-
-r:requestbody(filename) -- Reads and returns the request body of a request.
+
r:requestbody(filename) -- Reads and returns the request body of a request.
                 -- If 'filename' is specified, it instead saves the
                 -- contents to that file:
                 
 local input = r:requestbody()
 r:puts("You sent the following request body to me:\n")
-r:puts(input)
-
+r:puts(input)
-
-r:add_input_filter(filter_name) -- Adds 'filter_name' as an input filter
-
+
r:add_input_filter(filter_name) -- Adds 'filter_name' as an input filter
-
-r.module_info(module_name) -- Queries the server for information about a module
+
r.module_info(module_name) -- Queries the server for information about a module
 
 local mod = r.module_info("mod_lua.c")
 if mod then
     for k, v in pairs(mod.commands) do
        r:puts( ("%s: %s\n"):format(k,v)) -- print out all directives accepted by this module
     end
-end
-
+end
-
-r:loaded_modules() -- Returns a list of modules loaded by httpd:
+
r:loaded_modules() -- Returns a list of modules loaded by httpd:
 
 for k, module in pairs(r:loaded_modules()) do
     r:puts("I have loaded module " .. module .. "\n")
-end
-
+end
-
-r:runtime_dir_relative(filename) -- Compute the name of a run-time file (e.g., shared memory "file") 
-                         -- relative to the appropriate run-time directory. 
-
+
r:runtime_dir_relative(filename) -- Compute the name of a run-time file (e.g., shared memory "file") 
+                         -- relative to the appropriate run-time directory.
-
-r:server_info() -- Returns a table containing server information, such as 
-                -- the name of the httpd executable file, mpm used etc.
-
+
r:server_info() -- Returns a table containing server information, such as 
+                -- the name of the httpd executable file, mpm used etc.
-
-r:set_document_root(file_path) -- Sets the document root for the request to file_path
-
+
r:set_document_root(file_path) -- Sets the document root for the request to file_path
-
-r:set_context_info(prefix, docroot) -- Sets the context prefix and context document root for a request
-
+
r:set_context_info(prefix, docroot) -- Sets the context prefix and context document root for a request
-
-r:os_escape_path(file_path) -- Converts an OS path to a URL in an OS dependent way
-
+
r:os_escape_path(file_path) -- Converts an OS path to a URL in an OS dependent way
-
-r:escape_logitem(string) -- Escapes a string for logging
-
+
r:escape_logitem(string) -- Escapes a string for logging
-
-r.strcmp_match(string, pattern) -- Checks if 'string' matches 'pattern' using strcmp_match (globs).
+
r.strcmp_match(string, pattern) -- Checks if 'string' matches 'pattern' using strcmp_match (globs).
                         -- fx. whether 'www.example.com' matches '*.example.com':
                         
 local match = r.strcmp_match("foobar.com", "foo*.com")
 if match then 
     r:puts("foobar.com matches foo*.com")
-end
-
+end
-
-r:set_keepalive() -- Sets the keepalive status for a request. Returns true if possible, false otherwise.
-
+
r:set_keepalive() -- Sets the keepalive status for a request. Returns true if possible, false otherwise.
-
-r:make_etag() -- Constructs and returns the etag for the current request.
-
+
r:make_etag() -- Constructs and returns the etag for the current request.
-
-r:send_interim_response(clear) -- Sends an interim (1xx) response to the client.
-                       -- if 'clear' is true, available headers will be sent and cleared.
-
+
r:send_interim_response(clear) -- Sends an interim (1xx) response to the client.
+                       -- if 'clear' is true, available headers will be sent and cleared.
-
-r:custom_response(status_code, string) -- Construct and set a custom response for a given status code.
+
r:custom_response(status_code, string) -- Construct and set a custom response for a given status code.
                                -- This works much like the ErrorDocument directive:
                                
-r:custom_response(404, "Baleted!")
-
+r:custom_response(404, "Baleted!")
-
-r.exists_config_define(string) -- Checks whether a configuration definition exists or not:
+
r.exists_config_define(string) -- Checks whether a configuration definition exists or not:
 
 if r.exists_config_define("FOO") then
     r:puts("httpd was probably run with -DFOO, or it was defined in the configuration")
-end
-
+end
-
-r:state_query(string) -- Queries the server for state information
-
+
r:state_query(string) -- Queries the server for state information
-
-r:stat(filename [,wanted]) -- Runs stat() on a file, and returns a table with file information:
+
r:stat(filename [,wanted]) -- Runs stat() on a file, and returns a table with file information:
 
 local info = r:stat("/var/www/foo.txt")
 if info then
     r:puts("This file exists and was last modified at: " .. info.modified)
-end
-
+end
-
-r:regex(string, pattern [,flags]) -- Runs a regular expression match on a string, returning captures if matched:
+
r:regex(string, pattern [,flags]) -- Runs a regular expression match on a string, returning captures if matched:
 
 local matches = r:regex("foo bar baz", [[foo (\w+) (\S*)]])
 if matches then
@@ -967,23 +883,17 @@ local matches = r:regex("FOO bar BAz", [[(foo) bar]], 1)
 
 -- Flags can be a bitwise combination of:
 -- 0x01: Ignore case
--- 0x02: Multiline search
-
+-- 0x02: Multiline search
-
-r.usleep(number_of_microseconds) -- Puts the script to sleep for a given number of microseconds.
-
+
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.
-                        -- See 'Database connectivity' for details.
-
+
r:dbacquire(dbType[, dbParams]) -- Acquires a connection to a database and returns a database class.
+                        -- See 'Database connectivity' for details.
-
-r:ivm_set("key", value) -- Set an Inter-VM variable to hold a specific value.
+
r:ivm_set("key", value) -- Set an Inter-VM variable to hold a specific value.
                         -- These values persist even though the VM is gone or not being used,
                         -- and so should only be used if MaxConnectionsPerChild is > 0
                         -- Values can be numbers, strings and booleans, and are stored on a 
@@ -1001,39 +911,27 @@ function handle(r)
         r:ivm_set("cached_data", foo) -- set it globally
     end
     r:puts("Cached data is: ", foo)
-end
-
+end
-
-r:htpassword(string [,algorithm [,cost]]) -- Creates a password hash from a string.
+
r:htpassword(string [,algorithm [,cost]]) -- Creates a password hash from a string.
                                           -- algorithm: 0 = APMD5 (default), 1 = SHA, 2 = BCRYPT, 3 = CRYPT.
-                                          -- cost: only valid with BCRYPT algorithm (default = 5).
-
+ -- cost: only valid with BCRYPT algorithm (default = 5).
-
-r:mkdir(dir [,mode]) -- Creates a directory and sets mode to optional mode paramter.
-
+
r:mkdir(dir [,mode]) -- Creates a directory and sets mode to optional mode paramter.
-
-r:mkrdir(dir [,mode]) -- Creates directories recursive and sets mode to optional mode paramter.
-
+
r:mkrdir(dir [,mode]) -- Creates directories recursive and sets mode to optional mode paramter.
-
-r:rmdir(dir) -- Removes a directory.
-
+
r:rmdir(dir) -- Removes a directory.
-
-r:touch(file [,mtime]) -- Sets the file modification time to current time or to optional mtime msec value.
-
+
r:touch(file [,mtime]) -- Sets the file modification time to current time or to optional mtime msec value.
-
-r:get_direntries(dir) -- Returns a table with all directory entries.
+
r:get_direntries(dir) -- Returns a table with all directory entries.
 
 function handle(r)
   local dir = r.context_document_root
@@ -1045,52 +943,52 @@ function handle(r)
       r:puts( ("%s %s %10i %s\n"):format(ftype, mtime, info.size, f) )
     end
   end
-end
-
+end
-
-r.date_parse_rfc(string) -- Parses a date/time string and returns seconds since epoche.
-
+
r.date_parse_rfc(string) -- Parses a date/time string and returns seconds since epoche.
-
-r:getcookie(key) -- Gets a HTTP cookie
-
+
r:getcookie(key) -- Gets a HTTP cookie
-
-r:setcookie(key, value, secure, expires) -- Sets a HTTP cookie, for instance:
-r:setcookie("foo", "bar and stuff", false, os.time() + 86400)
-
+
r:setcookie{
+  key = [key],
+  value = [value],
+  expires = [expiry],
+  secure = [boolean],
+  httponly = [boolean],
+  path = [path],
+  domain = [domain]
+} -- Sets a HTTP cookie, for instance:
 
+r:setcookie{
+  key = "cookie1",
+  value = "HDHfa9eyffh396rt",
+  expires = os.time() + 86400,
+  secure = true
+}
-
-r:wsupgrade() -- Upgrades a connection to WebSockets if possible (and requested):
+
+
r:wsupgrade() -- Upgrades a connection to WebSockets if possible (and requested):
 if r:wsupgrade() then -- if we can upgrade:
     r:wswrite("Welcome to websockets!") -- write something to the client
     r:wsclose()  -- goodbye!
-end
-
+end
-
-r:wsread() -- Reads a WebSocket frame from a WebSocket upgraded connection (see above):
+
r:wsread() -- Reads a WebSocket frame from a WebSocket upgraded connection (see above):
 
 local line, isFinal = r:wsread() -- isFinal denotes whether this is the final frame.
                                  -- If it isn't, then more frames can be read
-r:wswrite("You wrote: " .. line)
-
+r:wswrite("You wrote: " .. line)
-
-r:wswrite(line) -- Writes a frame to a WebSocket client:
-r:wswrite("Hello, world!")
-
+
r:wswrite(line) -- Writes a frame to a WebSocket client:
+r:wswrite("Hello, world!")
-
-r:wsclose() -- Closes a WebSocket request and terminates it for httpd:
+
r:wsclose() -- Closes a WebSocket request and terminates it for httpd:
 
 if r:wsupgrade() then
     r:wswrite("Write something: ")
@@ -1098,16 +996,14 @@ if r:wsupgrade() then
     r:wswrite("You wrote: " .. line);
     r:wswrite("Goodbye!")
     r:wsclose()
-end
-
+end
top

Logging Functions

-
-        -- examples of logging messages
+
        -- examples of logging messages
r:trace1("This is a trace log message") -- trace1 through trace8 can be used
r:debug("This is a debug log message")
r:info("This is an info log message")
@@ -1155,8 +1051,7 @@ end function as buckets are sent down the filter chain. The core structure of such a function is:

-
-function filter(r)
+    
function filter(r)
     -- Our first yield is to signal that we are ready to receive buckets.
     -- Before this yield, we can set up our environment, check for conditions,
     -- and, if we deem it necessary, decline filtering a request alltogether:
@@ -1182,8 +1077,7 @@ function filter(r)
     -- can be done by doing a final yield here. Both input and output filters 
     -- can append data to the content in this phase.
     coroutine.yield([optional footer to be appended to the content])
-end
-    
+end
top
@@ -1195,10 +1089,9 @@ end as well as mod_dbd.

The example below shows how to acquire a database handle and return information from a table:

-
-function handle(r)
+    
function handle(r)
     -- Acquire a database handle
-    local database, err = r:dbacquire("mysql", "server=localhost,user=root,dbname=mydb")
+    local database, err = r:dbacquire("mysql", "server=localhost,user=someuser,pass=somepass,dbname=mydb")
     if not err then
         -- Select some information from it
         local results, err = database:select(r, "SELECT `name`, `age` FROM `people` WHERE 1")
@@ -1214,32 +1107,26 @@ function handle(r)
     else
         r:puts("Could not connect to the database: " .. err)
     end
-end
-    
+end

To utilize mod_dbd, specify mod_dbd as the database type, or leave the field blank:

-
-    local database = r:dbacquire("mod_dbd")
-    
+
local database = r:dbacquire("mod_dbd")

Database object and contained functions

The database object returned by dbacquire has the following methods:

Normal select and query from a database:

-
--- Run a statement and return the number of rows affected:
+    
-- Run a statement and return the number of rows affected:
 local affected, errmsg = database:query(r, "DELETE FROM `tbl` WHERE 1")
 
 -- Run a statement and return a result set that can be used synchronously or async:
-local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1")
-    
+local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1")

Using prepared statements (recommended):

-
--- Create and run a prepared statement:
+    
-- Create and run a prepared statement:
 local statement, errmsg = database:prepare(r, "DELETE FROM `tbl` WHERE `age` > %u")
 if not errmsg then
     local result, errmsg = statement:query(20) -- run the statement with age > 20
@@ -1249,21 +1136,17 @@ end
 local statement, errmsg = database:prepared(r, "someTag")
 if not errmsg then
     local result, errmsg = statement:select("John Doe", 123) -- inject the values "John Doe" and 123 into the statement
-end
-
-
+end

Escaping values, closing databases etc:

-
--- Escape a value for use in a statement:
+    
-- Escape a value for use in a statement:
 local escaped = database:escape(r, [["'|blabla]])
 
 -- Close a database connection and free up handles:
 database:close()
 
 -- Check whether a database connection is up and running:
-local connected = database:active()
-    
+local connected = database:active()

Working with result sets

@@ -1275,20 +1158,18 @@ local connected = database:active() result(-1) fetches the next available row in the set, asynchronously.
result(N) fetches row number N, asynchronously:

-
--- fetch a result set using a regular query:
+    
-- fetch a result set using a regular query:
 local result, err = db:select(r, "SELECT * FROM `tbl` WHERE 1")
 
 local rows = result(0) -- Fetch ALL rows synchronously
 local row = result(-1) -- Fetch the next available row, asynchronously
 local row = result(1234) -- Fetch row number 1234, asynchronously
-    
+local row = result(-1, true) -- Fetch the next available row, using row names as key indexes.

One can construct a function that returns an iterative function to iterate over all rows in a synchronous or asynchronous way, depending on the async argument:

-
-function rows(resultset, async)
+    
function rows(resultset, async)
     local a = 0
     local function getnext()
         a = a + 1
@@ -1319,8 +1200,7 @@ if not err then
             ....
         end
     end
-end
-    
+end

Closing a database connection

@@ -1332,16 +1212,14 @@ end if you leave the closing up to mod_lua. Essentially, the following two measures are the same:

-
--- Method 1: Manually close a handle
+    
-- Method 1: Manually close a handle
 local database = r:dbacquire("mod_dbd")
 database:close() -- All done
 
 -- Method 2: Letting the garbage collector close it
 local database = r:dbacquire("mod_dbd")
 database = nil -- throw away the reference
-collectgarbage() -- close the handle via GC
-
+collectgarbage() -- close the handle via GC

Precautions when working with databases

@@ -1370,21 +1248,17 @@ collectgarbage() -- close the handle via GC

After a lua function has been registered as authorization provider, it can be used with the Require directive:

-
-LuaRoot /usr/local/apache2/lua
+
LuaRoot /usr/local/apache2/lua
 LuaAuthzProvider foo authz.lua authz_check_foo
 <Location />
   Require foo johndoe
-</Location>
-
+</Location>
-
-require "apache2"
+
require "apache2"
 function authz_check_foo(r, who)
     if r.user ~= who then return apache2.AUTHZ_DENIED
     return apache2.AUTHZ_GRANTED
-end
-
+end
@@ -1412,11 +1286,9 @@ end

In general stat or forever is good for production, and stat or never for development.

-

Examples:

-LuaCodeCache stat
+    

Examples:

LuaCodeCache stat
 LuaCodeCache forever
-LuaCodeCache never
-    
+LuaCodeCache never
@@ -1453,8 +1325,7 @@ hook function usually returns OK, DECLINED, or HTTP_FORBIDDEN.

a request. This can be used to implement arbitrary authentication and authorization checking. A very simple example:

-
-require 'apache2'
+
require 'apache2'
 
 -- fake authcheck hook
 -- If request has no auth info, set the response header and
@@ -1483,8 +1354,7 @@ function authcheck_hook(r)
       return 401
    end
    return apache2.OK
-end
-
+end

Ordering

The optional arguments "early" or "late" control when this script runs relative to other modules.

@@ -1552,12 +1422,9 @@ processing apache2.OK to tell httpd to log as normal.

Example:

-
-LuaHookLog /path/to/script.lua logger
-
+
LuaHookLog /path/to/script.lua logger
-
--- /path/to/script.lua --
+
-- /path/to/script.lua --
 function logger(r)
     -- flip a coin:
     -- If 1, then we write to our own Lua log and tell httpd not to log
@@ -1577,8 +1444,7 @@ function logger(r)
         r.uri = r.uri:gsub("somesecretstuff", "") -- sanitize the URI
         return apache2.OK -- tell httpd to log it.
     end
-end
-
+end
@@ -1595,12 +1461,9 @@ end

Like LuaHookTranslateName but executed at the map-to-storage phase of a request. Modules like mod_cache run at this phase, which makes for an interesting example on what to do here:

-
-    LuaHookMapToStorage /path/to/lua/script.lua check_cache
-    
+
LuaHookMapToStorage /path/to/lua/script.lua check_cache
-
-require"apache2"
+    
require"apache2"
 cached_files = {}
 
 function read_file(filename) 
@@ -1628,8 +1491,7 @@ function check_cache(r)
         end
     end
     return apache2.DECLINED -- If we had nothing to do, let others serve this.
-end
-    
+end
@@ -1660,14 +1522,11 @@ end

Example:

-
-# httpd.conf
-LuaHookTranslateName /scripts/conf/hooks.lua silly_mapper
-
+
# httpd.conf
+LuaHookTranslateName /scripts/conf/hooks.lua silly_mapper
-
--- /scripts/conf/hooks.lua --
+
-- /scripts/conf/hooks.lua --
 require "apache2"
 function silly_mapper(r)
     if r.uri == "/" then
@@ -1676,8 +1535,7 @@ function silly_mapper(r)
     else
         return apache2.DECLINED
     end
-end
-
+end

Context

This directive is not valid in <Directory>, <Files>, or htaccess @@ -1702,12 +1560,9 @@ end This phase is where requests are assigned a content type and a handler, and thus can be used to modify the type and handler based on input:

-
-    LuaHookTypeChecker /path/to/lua/script.lua type_checker
-    
+
LuaHookTypeChecker /path/to/lua/script.lua type_checker
-
-    function type_checker(r)
+    
    function type_checker(r)
         if r.uri:match("%.to_gif$") then -- match foo.png.to_gif
             r.content_type = "image/gif" -- assign it the image/gif type
             r.handler = "gifWizard"      -- tell the gifWizard module to handle this
@@ -1716,8 +1571,7 @@ end
         end
 
         return apache2.DECLINED
-    end
-    
+ end
@@ -1760,15 +1614,12 @@ global variable bucket holds the buckets as they are passed onto the Lua script:

-
-LuaInputFilter myInputFilter /www/filter.lua input_filter
-<FilesMatch "\.lua>
+
LuaInputFilter myInputFilter /www/filter.lua input_filter
+<Files *.lua>
   SetInputFilter myInputFilter
-</FilesMatch>
-
+</Files>
-
---[[
+
--[[
     Example input filter that converts all POST data to uppercase.
 ]]--
 function input_filter(r)
@@ -1780,21 +1631,18 @@ function input_filter(r)
     end
     -- No more buckets available.
     coroutine.yield("&filterSignature=1234") -- Append signature at the end
-end
-
+end

The input filter supports denying/skipping a filter if it is deemed unwanted:

-
-function input_filter(r)
+
function input_filter(r)
     if not good then
         return -- Simply deny filtering, passing on the original content instead
     end
     coroutine.yield() -- wait for buckets
     ... -- insert filter stuff here
-end
-
+end

See "Modifying contents with Lua @@ -1818,18 +1666,14 @@ filters" for more information. match groups into both the file path and the function name. Be careful writing your regular expressions to avoid security issues.

-

Examples:

-    LuaMapHandler /(\w+)/(\w+) /scripts/$1.lua handle_$2
-    
+

Examples:

LuaMapHandler /(\w+)/(\w+) /scripts/$1.lua handle_$2

This would match uri's such as /photos/show?id=9 to the file /scripts/photos.lua and invoke the handler function handle_show on the lua vm after loading that file.

-
-    LuaMapHandler /bingo /scripts/wombat.lua
-
+
LuaMapHandler /bingo /scripts/wombat.lua

This would invoke the "handle" function, which is the default if no specific function name is @@ -1855,15 +1699,12 @@ global variable bucket holds the buckets as they are passed onto the Lua script:

-
-LuaOutputFilter myOutputFilter /www/filter.lua output_filter
-<FilesMatch "\.lua>
+
LuaOutputFilter myOutputFilter /www/filter.lua output_filter
+<Files *.lua>
   SetOutputFilter myOutputFilter
-</FilesMatch>
-
+</Files>
-
---[[
+
--[[
     Example output filter that escapes all HTML entities in the output
 ]]--
 function output_filter(r)
@@ -1874,22 +1715,19 @@ function output_filter(r)
         coroutine.yield(output) -- Send converted data down the chain
     end
     -- No more buckets available.
-end
-
+end

As with the input filter, the output filter supports denying/skipping a filter if it is deemed unwanted:

-
-function output_filter(r)
+
function output_filter(r)
     if not r.content_type:match("text/html") then
         return -- Simply deny filtering, passing on the original content instead
     end
     coroutine.yield() -- wait for buckets
     ... -- insert filter stuff here
-end
-
+end

Lua filters with mod_filter

When a Lua filter is used as the underlying provider via the @@ -1933,10 +1771,8 @@ information. conventions as lua. This just munges the package.path in the lua vms.

-

Examples:

-LuaPackagePath /scripts/lib/?.lua
-LuaPackagePath /scripts/lib/?/init.lua
-    
+

Examples:

LuaPackagePath /scripts/lib/?.lua
+LuaPackagePath /scripts/lib/?/init.lua
@@ -2047,7 +1883,7 @@ var comments_identifier = 'http://httpd.apache.org/docs/2.4/mod/mod_lua.html'; } })(window, document); //-->