From 32b70d27a4f055c0c7c2032c6a1b27f133acf5a4 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Andr=C3=A9=20Malo?=
-/* Handler for the "exambleEnabled" directive */ +/* Handler for the "exampleEnabled" directive */ const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) { if(!strcasecmp(arg, "on")) config.enabled = 1; @@ -998,7 +998,7 @@ static example_config config; Our directive handlers: ============================================================================== */ -/* Handler for the "exambleEnabled" directive */ +/* Handler for the "exampleEnabled" directive */ const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) { if(!strcasecmp(arg, "on")) config.enabled = 1; @@ -1295,7 +1295,7 @@ where you have a parent configuration and a child, such as the following:<Directory "/var/www"> - ExampleEnable On + ExampleEnabled On ExamplePath /foo/bar ExampleAction file allow </Directory> @@ -1307,7 +1307,7 @@ where you have a parent configuration and a child, such as the following:In this example, it is natural to assume that the directory
@@ -1489,7 +1489,7 @@ static int example_handler(request_rec *r) /* ======================================================================================================================= - Handler for the "exambleEnabled" directive + Handler for the "exampleEnabled" directive ======================================================================================================================= */ const char *example_set_enabled(cmd_parms *cmd, void *cfg, const char *arg) diff --git a/docs/manual/mod/directives.html.de b/docs/manual/mod/directives.html.de index 2b3a34fb81..d5045ef9a6 100644 --- a/docs/manual/mod/directives.html.de +++ b/docs/manual/mod/directives.html.de @@ -342,6 +342,7 @@/var/www/subdir
should inherit the values set for the/var/www -
directory, as we did not specify anExampleEnable
nor + directory, as we did not specify anExampleEnabled
nor anExamplePath
for this directory. The server does not presume to know if this is true, but cleverly does the following:
This module holds a great deal of power over httpd, which is both a +strength and a potential security risk. It is not recommended +that you use this module on a server that is shared with users you do not +trust, as it can be abused to change the internal workings of httpd.
+.lua
by invoking that file's
handle
function.
+For more flexibility, see LuaMapHandler
.
+
-example.lua +example.lua@@ -187,7 +211,7 @@ without authentication, or if the authenticated user matches the second argument:
-- example handler require "string" @@ -132,19 +148,27 @@ require "string" --]] function handle(r) r.content_type = "text/plain" - r:puts("Hello Lua World!\n") if r.method == 'GET' then + r:puts("Hello Lua World!\n") for k, v in pairs( r:parseargs() ) do r:puts( string.format("%s: %s\n", k, v) ) end elseif r.method == 'POST' then + r:puts("Hello Lua World!\n") for k, v in pairs( r:parsebody() ) do r:puts( string.format("%s: %s\n", k, v) ) end - else + elseif r.method == 'PUT' then +-- use our own Error contents r:puts("Unsupported HTTP method " .. r.method) + r.status = 405 + return apache2.ok + else +-- use the ErrorDocument + return 501 end + return apache2.OK end
-authz_provider.lua +authz_provider.lua
require 'apache2' @@ -221,18 +245,90 @@ LuaAuthzProvider foo authz_provider.lua authz_check_fooHook functions are how modules (and Lua scripts) participate in the processing of requests. Each type of hook exposed by the server exists for -a specific purpose, such as mapping requests to the filesystem, -performing access control, or setting mimetypes. General purpose hooks -that simply run at handy times in the request lifecycle exist as well.
+a specific purpose, such as mapping requests to the file system, +performing access control, or setting mime types: + +
Hook phase | +mod_lua directive | +Description | +
---|---|---|
Quick handler | +LuaQuickHandler |
+ This is the first hook that will be called after a request has + been mapped to a host or virtual host | +
Translate name | +LuaHookTranslateName |
+ This phase translates the requested URI into a filename on the
+ system. Modules such as mod_alias and
+ mod_rewrite operate in this phase. |
+
Map to storage | +LuaHookMapToStorage |
+ This phase maps files to their physical, cached or external/proxied storage. + It can be used by proxy or caching modules | +
Check Access | +LuaHookAccessChecker |
+ This phase checks whether a client has access to a resource. This + phase is run before the user is authenticated, so beware. + | +
Check User ID | +LuaHookCheckUserID |
+ This phase it used to check the negotiated user ID | +
Check Authorization | +LuaHookAuthChecker or
+ LuaAuthzProvider |
+ This phase authorizes a user based on the negotiated credentials, such as + user ID, client certificate etc. + | +
Check Type | +LuaHookTypeChecker |
+ This phase checks the requested file and assigns a content type and + a handler to it | +
Fixups | +LuaHookFixups |
+ This is the final "fix anything" phase before the content handlers + are run. Any last-minute changes to the request should be made here. | +
Content handler | +fx. .lua files or through LuaMapHandler |
+ This is where the content is handled. Files are read, parsed, some are run, + and the result is sent to the client | +
Logging | +(none) | +Once a request has been handled, it enters several logging phases, + which logs the request in either the error or access log | +
Hook functions are passed the request object as their only argument. +
Hook functions are passed the request object as their only argument
+(except for LuaAuthzProvider, which also gets passed the arguments from
+the Require directive).
They can return any value, depending on the hook, but most commonly
-they'll return OK, DONE, or DECLINED, which you can write in lua as
+they'll return OK, DONE, or DECLINED, which you can write in Lua as
apache2.OK
, apache2.DONE
, or
apache2.DECLINED
, or else an HTTP status code.
-translate_name.lua +translate_name.lua+
-- example hook that rewrites the URI to a filesystem path. require 'apache2' @@ -248,15 +344,16 @@ end
-translate_name2.lua +translate_name2.lua
--[[ example hook that rewrites one URI to another URI. It returns a apache2.DECLINED to give other URL mappers a chance to work on the substitution, including the core translate_name hook which maps based on the DocumentRoot. - Note: It is currently undefined as to whether this runs before or after - mod_alias. + Note: Use the early/late flags in the directive to make it run before + or after mod_alias. --]] require 'apache2' @@ -279,176 +376,326 @@ end
The request_rec is mapped in as a userdata. It has a metatable which lets you do useful things with it. For the most part it - has the same fields as the request_rec struct (see httpd.h - until we get better docs here) many of which are writeable as + has the same fields as the request_rec struct, many of which are writable as well as readable. (The table fields' content can be changed, but the fields themselves cannot be set to different tables.)
-Name | Lua type | Writable | +Description | +
---|---|---|---|
allowoverrides |
+ string | +no | +The AllowOverride options applied to the current request. |
ap_auth_type |
string | no | +If an authentication check was made, this is set to the type
+ of authentication (f.x. basic ) |
args |
string | yes | +The query string arguments extracted from the request
+ (f.x. foo=bar&name=johnsmith ) |
assbackwards |
boolean | no | +Set to true if this is an HTTP/0.9 style request
+ (e.g. GET /foo (with no headers) ) |
auth_name |
+ string | +no | +The realm name used for authorization (if applicable). | +
banner |
+ string | +no | +The server banner, f.x. Apache HTTP Server/2.4.3 openssl/0.9.8c |
+
basic_auth_pw |
+ string | +no | +The basic auth password sent with this request, if any | +
canonical_filename |
string | no | +The canonical filename of the request |
content_encoding |
string | no | +The content encoding of the current request |
content_type |
string | yes | +The content type of the current request, as determined in the
+ type_check phase (f.x. image/gif or text/html ) |
context_prefix |
string | no | +|
context_document_root |
string | no | +|
document_root |
string | no | +The document root of the host |
err_headers_out |
table | no | +MIME header environment for the response, printed even on errors and + persist across internal redirects |
filename |
string | yes | +The file name that the request maps to, f.x. /www/example.com/foo.txt. This can be + changed in the translate-name or map-to-storage phases of a request to allow the + default handler (or script handlers) to serve a different file than what was requested. |
handler |
string | yes | +The name of the handler that should serve this request, f.x.
+ lua-script if it is to be served by mod_lua. This is typically set by the
+ AddHandler or SetHandler
+ directives, but could also be set via mod_lua to allow another handler to serve up a specific request
+ that would otherwise not be served by it.
+ |
headers_in |
table | yes | +MIME header environment from the request. This contains headers such as Host,
+ User-Agent, Referer and so on. |
headers_out |
table | yes | +MIME header environment for the response. |
hostname |
string | no | +The host name, as set by the Host: header or by a full URI. |
is_https |
+ boolean | +no | +Whether or not this request is done via HTTPS | +
is_initial_req |
+ boolean | +no | +Whether this request is the initial request or a sub-request | +
limit_req_body |
+ number | +no | +The size limit of the request body for this request, or 0 if no limit. | +
log_id |
string | no | +The ID to identify request in access and error log. |
method |
string | no | +The request method, f.x. GET or POST . |
notes |
table | yes | +A list of notes that can be passed on from one module to another. | +
options |
+ string | +no | +The Options directive applied to the current request. |
path_info |
string | no | +The PATH_INFO extracted from this request. |
port |
+ number | +no | +The server port used by the request. | +
protocol |
string | no | +The protocol used, f.x. HTTP/1.1 |
proxyreq |
string | yes | +Denotes whether this is a proxy request or not. This value is generally set in + the post_read_request/translate_name phase of a request. |
range |
string | no | +The contents of the Range: header. |
+
remaining |
+ number | +no | +The number of bytes remaining to be read from the request body. | +
server_built |
+ string | +no | +The time the server executable was built. | +
server_name |
+ string | +no | +The server name for this request. |
some_auth_required |
+ boolean | +no | +Whether some authorization is/was required for this request. | +
subprocess_env |
table | yes | +The environment variables set for this request. |
started |
+ number | +no | +The time the server was (re)started, in seconds since the epoch (Jan 1st, 1970) | +
status |
number | yes | +The (current) HTTP return code for this request, f.x. 200 or 404 . |
the_request |
string | no | +The request string as sent by the client, f.x. GET /foo/bar HTTP/1.1 . |
unparsed_uri |
string | no | +The unparsed URI of the request |
uri |
string | yes | +The URI after it has been parsed by httpd |
user |
string | yes | +If an authentication check has been made, this is set to the name of the authenticated user. |
useragent_ip |
string | no | +The IP of the user agent making the request |
The request_rec object has (at least) the following methods:
-The request_rec has (at least) the following methods:
++r:flush() -- flushes the output buffer. + -- Returns true if the flush was successful, false otherwise. --- r:addoutputfilter(name|function) -- add an output filter -+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:sleep(0.5) -- fake processing time and repeat +end +
++r:addoutputfilter(name|function) -- add an output filter: + +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: + +if use_sendfile_thing then + r:sendfile("/var/www/large_file.img") +end ++ + +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): @@ -467,23 +714,288 @@ local POST, POSTMULTI = r:parsebody(1024*1024) r:puts("Your name is: " .. POST['name'] or "Unknown")-- r:puts("hello", " world", "!") -- print to response body -++r:puts("hello", " world", "!") -- print to response body, self explanatory +-- r:write("a single string") -- print to response body -- -++ + ++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:base64_encode(string) -- Encodes a string using the Base64 encoding standard: + +local encoded = r:base64_encode("This is a test") -- returns VGhpcyBpcyBhIHRlc3Q= ++ + ++r:base64_decode(string) -- Decodes a Base64-encoded string: + +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): + +local hash = r:md5("This is a test") -- returns ce114e4501d2f4e2dcea3e17b546f339 ++ + ++r:sha1(string) -- Calculates and returns the SHA1 digest of a string (binary safe): + +local hash = r:sha1("This is a test") -- returns a54d88e06612d820bc3be72877c74f257b561b19 ++ + ++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' ++ + ++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:escape(url) -- returns 'http://foo.bar/1 2 3 & 4 + 5' ++ + ++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 ++ + ++r:expr(string) -- Evaluates an expr string. + +if r:expr("%{HTTP_HOST} =~ /^www/") then + r:puts("This host name starts with www") +end ++ + ++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:scoreboard_worker(a, b) -- Queries for information about the worker thread,+ + + +b
, in processa
: + +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:clock() -- Returns the current time with microsecond precision ++ + ++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: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 + +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 ++ + ++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 ++ + ++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: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: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.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 ++ + ++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: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. + -- This works much like the ErrorDocument directive: + +r:custom_response(404, "Baleted!") ++ + ++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 ++ + ++r:state_query(string) -- Queries the server for state information ++ + ++r:stat(filename) -- 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 ++ + ++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 + r:puts("The regex matched, and the last word captured ($2) was: " .. matches[2]) +end + +-- Example ignoring case sensitivity: +local matches = r:regex("FOO bar BAz", [[(foo) bar]], 1) + +-- Flags can be a bitwise combination of: +-- 0x01: Ignore case +-- 0x02: Multiline search ++ + ++r:sleep(number_of_seconds) -- Puts the script to sleep for a given number of seconds. + -- This can be a floating point number like 1.25 for extra accuracy. ++ + +r:dbacquire(dbType[, dbParams]) -- Acquires a connection to a database and returns a database class. - -- See 'Database connectivity' for details. -+ -- See 'Database connectivity' for details. ++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 + -- per process basis (so they won't do much good with a prefork mpm) + +r:ivm_get("key") -- Fetches a variable set by ivm_set. Returns the contents of the variable + -- if it exists or nil if no such variable exists. + +-- An example getter/setter that saves a global variable outside the VM: +function handle(r) + -- First VM to call this will get no value, and will have to create it + local foo = r:ivm_get("cached_data") + if not foo then + foo = do_some_calcs() -- fake some return value + r:ivm_set("cached_data", foo) -- set it globally + end + r:puts("Cached data is: ", foo) +end +- -
mod_proxy
mod_authz_core
(Other HTTP status codes are not yet implemented.)
+
+ Filter functions implemented via LuaInputFilter
+ or LuaOutputFilter
are designed as
+ three-stage non-blocking functions using coroutines to suspend and resume a
+ function as buckets are sent down the filter chain. The core structure of
+ such a function is:
+
+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: + if something_bad then + return -- This would skip this filter. + end + -- Regardless of whether we have data to prepend, a yield MUST be called here. + -- Note that only output filters can prepend data. Input filters must use the + -- final stage to append data to the content. + coroutine.yield([optional header to be prepended to the content]) + + -- After we have yielded, buckets will be sent to us, one by one, and we can + -- do whatever we want with them and then pass on the result. + -- Buckets are stored in the global variable 'bucket', so we create a loop + -- that checks if 'bucket' is not nil: + while bucket ~= nil do + local output = mangle(bucket) -- Do some stuff to the content + coroutine.yield(output) -- Return our new content to the filter chain + end + + -- Once the buckets are gone, 'bucket' is set to nil, which will exit the + -- loop and land us here. Anything extra we want to append to the content + -- 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 ++
Connecting and firing off queries is as easy as:
+The example below shows how to acquire a database handle and return information from a table:
-function handler(r) - local database, err = r:dbacquire("mysql", "server=localhost&user=root&database=mydb") +function handle(r) + -- Acquire a database handle + local database, err = r:dbacquire("mysql", "server=localhost,user=root,dbname=mydb") if not err then + -- Select some information from it local results, err = database:select(r, "SELECT `name`, `age` FROM `people` WHERE 1") if not err then local rows = results(0) -- fetch all rows synchronously @@ -555,7 +1113,7 @@ end
- To utilize mod_dbd
, simply specify mod_dbd
+ To utilize mod_dbd
, specify mod_dbd
as the database type, or leave the field blank:
@@ -579,7 +1137,7 @@ local result, errmsg = database:select(r, "SELECT * FROM `people` WHERE 1") -- 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 + local result, errmsg = statement:query(20) -- run the statement with age > 20 end -- Fetch a prepared statement from a DBDPrepareSQL directive: @@ -707,13 +1265,53 @@ collectgarbage() -- close the handle via GCAfter a lua function has been registered as authorization provider, it can be used with the
-Require
directive:+ ++LuaRoot /usr/local/apache2/lua LuaAuthzProvider foo authz.lua authz_check_foo <Location /> - Require foo bar + Require foo johndoe </Location>+ ++require "apache2" +function authz_check_foo(r, who) + if r.user ~= who then return apache2.AUTHZ_DENIED + return apache2.AUTHZ_GRANTED +end ++ + + + ++LuaCodeCache Directive
++
+ Description: Configure the compiled code cache. + Syntax: LuaCodeCache stat|forever|never
+ Default: LuaCodeCache stat
+ Context: server config, virtual host, directory, .htaccess + Override: All + Status: Experimental + Module: mod_lua + Specify the behavior of the in-memory code cache. The default + is stat, which stats the top level script (not any included + ones) each time that file is needed, and reloads it if the + modified time indicates it is newer than the one it has + already loaded. The other values cause it to keep the file + cached forever (don't stat and replace) or to never cache the + file.
+ +In general stat or forever is good for production, and stat or never + for development.
+ +@@ -805,7 +1403,7 @@ endExamples:
+LuaCodeCache stat +LuaCodeCache forever +LuaCodeCache never +LuaHookFixups Directive
-
Description: Provide a hook for the fixups phase of request + Description: Provide a hook for the fixups phase of a request processing Syntax: LuaHookFixups /path/to/lua/script.lua hook_function_name
@@ -838,7 +1436,48 @@ processing Context: server config, virtual host, directory, .htaccess Override: All Status: Experimental - Module: mod_lua ...
+ +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 ++ ++require"apache2" +cached_files = {} + +function read_file(filename) + local input = io.open(filename, "r") + if input then + local data = input:read("*a") + cached_files[filename] = data + file = cached_files[filename] + input:close() + end + return cached_files[filename] +end + +function check_cache(r) + if r.filename:match("%.png$") then -- Only match PNG files + local file = cached_files[r.filename] -- Check cache entries + if not file then + file = read_file(r.filename) -- Read file into cache + end + if file then -- If file exists, write it out + r.status = 200 + r:write(file) + r:info(("Sent %s to client from cache"):format(r.filename)) + return apache2.DONE -- skip default handler for PNG files + end + end + return apache2.DECLINED -- If we had nothing to do, let others serve this. +end ++ + +LuaHookTranslateName Directive
@@ -903,7 +1542,29 @@ endOverride: All Status: Experimental - Module: mod_lua ...
++ This directive provides a hook for the type_checker phase of the request processing. + 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 ++ ++ 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 + r.filename = r.uri:gsub("%.to_gif$", "") -- fix the filename requested + return apache2.OK + end + + return apache2.DECLINED + end ++ ++ +LuaInherit Directive
@@ -924,6 +1585,162 @@ endIn previous 2.3.x releases, the default was effectively to ignore LuaHook* directives from parent configuration sections.
++ +LuaInputFilter Directive
++
++ Description: Provide a Lua function for content input filtering + Syntax: LuaInputFilter filter_name /path/to/lua/script.lua function_name
+ Context: server config + Status: Experimental + Module: mod_lua + Compatibility: 2.5.0 and later Provides a means of adding a Lua function as an input filter. +As with output filters, input filters work as coroutines, +first yielding before buffers are sent, then yielding whenever +a bucket needs to be passed down the chain, and finally (optionally) +yielding anything that needs to be appended to the input data. The +global variable
+ +bucket
holds the buckets as they are passed +onto the Lua script: ++LuaInputFilter myInputFilter /www/filter.lua input_filter +<FilesMatch "\.lua> + SetInputFilter myInputFilter +</FilesMatch> ++ ++--[[ + Example input filter that converts all POST data to uppercase. +]]-- +function input_filter(r) + print("luaInputFilter called") -- debug print + coroutine.yield() -- Yield and wait for buckets + while bucket do -- For each bucket, do... + local output = string.upper(bucket) -- Convert all POST data to uppercase + coroutine.yield(output) -- Send converted data down the chain + end + -- No more buckets available. + coroutine.yield("&filterSignature=1234") -- Append signature at the end +end ++ ++The input filter supports denying/skipping a filter if it is deemed unwanted: +
++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 ++ ++See "Modifying contents with Lua +filters" for more information. +
+ ++ +LuaMapHandler Directive
++
++ Description: Map a path to a lua handler + Syntax: LuaMapHandler uri-pattern /path/to/lua/script.lua [function-name]
+ Context: server config, virtual host, directory, .htaccess + Override: All + Status: Experimental + Module: mod_lua This directive matches a uri pattern to invoke a specific + handler function in a specific file. It uses PCRE regular + expressions to match the uri, and supports interpolating + 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 ++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 ++ +This would invoke the "handle" function, which + is the default if no specific function name is + provided.
+ +LuaOutputFilter Directive
++
++ Description: Provide a Lua function for content output filtering + Syntax: LuaOutputFilter filter_name /path/to/lua/script.lua function_name
+ Context: server config + Status: Experimental + Module: mod_lua + Compatibility: 2.5.0 and later Provides a means of adding a Lua function as an output filter. +As with input filters, output filters work as coroutines, +first yielding before buffers are sent, then yielding whenever +a bucket needs to be passed down the chain, and finally (optionally) +yielding anything that needs to be appended to the input data. The +global variable
+ +bucket
holds the buckets as they are passed +onto the Lua script: ++LuaOutputFilter myOutputFilter /www/filter.lua output_filter +<FilesMatch "\.lua> + SetOutputFilter myOutputFilter +</FilesMatch> ++ ++--[[ + Example output filter that escapes all HTML entities in the output +]]-- +function output_filter(r) + coroutine.yield("(Handled by myOutputFilter)<br/>\n") -- Prepend some data to the output, + -- yield and wait for buckets. + while bucket do -- For each bucket, do... + local output = r:escape_html(bucket) -- Escape all output + coroutine.yield(output) -- Send converted data down the chain + end + -- No more buckets available. +end ++ ++As with the input filter, the output filter supports denying/skipping a filter +if it is deemed unwanted: +
++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 ++ ++See "Modifying contents with Lua filters" for more +information. +
+diff --git a/docs/manual/mod/mod_lua.html.fr b/docs/manual/mod/mod_lua.html.fr index 21c9d9b245..f1caa79ed2 100644 --- a/docs/manual/mod/mod_lua.html.fr +++ b/docs/manual/mod/mod_lua.html.fr @@ -27,6 +27,8 @@LuaPackageCPath Directive
@@ -970,7 +1787,14 @@ LuaPackagePath /scripts/lib/?/init.luaOverride: All Status: Experimental - Module: mod_lua ...
+ ++ This phase is run immediately after the request has been mapped to a virtal host, + and can be used to either do some request processing before the other phases kick + in, or to serve a request without the need to translate, map to storage et cetera. + As this phase is run before anything else, directives such as
<Location>
or<Directory>
are void in this phase, just as + URIs have not been properly parsed yet. +@@ -995,14 +1819,14 @@ LuaPackagePath /scripts/lib/?/init.luaContext
This directive is not valid in
<Directory>
,<Files>
, or htaccess context.LuaScope Directive
-
- Description: One of once, request, conn, thread -- default is once + Syntax: LuaScope once|request|conn|thread
Syntax: LuaScope once|request|conn|thread|server [min] [max]
Default: LuaScope once
Context: server config, virtual host, directory, .htaccess Override: All Status: Experimental Module: mod_lua Specify the lifecycle scope of the Lua interpreter which will +
Specify the life cycle scope of the Lua interpreter which will be used by handlers in this "Directory." The default is "once"
@@ -1013,10 +1837,30 @@ LuaPackagePath /scripts/lib/?/init.lua request scoped.
+- conn:
- Same as request but attached to the connection_rec
+- thread:
- Use the interpreter for the lifetime of the thread handling the request (only available with threaded MPMs).
+- server:
- This one is different than others because the + server scope is quite long lived, and multiple threads + will have the same server_rec. To accommodate this, + server scoped Lua states are stored in an apr + resource list. The
min
andmax
arguments + specify the minimum and maximum number of Lua states to keep in the + pool.+ Generally speaking, the
thread
andserver
scopes + execute roughly 2-3 times faster than the rest, because they don't have to + spawn new Lua states on every request (especially with the event MPM, as + even keepalive requests will use a new thread for each request). If you are + satisfied that your scripts will not have problems reusing a state, then + thethread
orserver
scopes should be used for + maximum performance. While thethread
scope will provide the + fastest responses, theserver
scope will use less memory, as + states are pooled, allowing f.x. 1000 threads to share only 100 Lua states, + thus using only 10% of the memory required by thethread
scope. +Cette traduction peut être périmée. Vérifiez la version + anglaise pour les changements récents.
Description: | Fournit des points d'entrée Lua dans différentes parties du traitement des requêtes httpd | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Statut: | Expérimental |
Description: | Configure the compiled code cache. |
---|---|
Syntaxe: | LuaCodeCache stat|forever|never |
Défaut: | LuaCodeCache stat |
Contexte: | configuration du serveur, serveur virtuel, répertoire, .htaccess |
AllowOverride: | All |
Statut: | Expérimental |
Module: | mod_lua |
La documentation de cette directive + n'a pas encore t traduite. Veuillez vous reporter la version + en langue anglaise.
Description: | Fournit un point d'entrée pour la phase access_checker du
@@ -991,6 +1010,42 @@ parentes sont fusionn
configuration parentes.
+LuaInputFilter Directive+
La documentation de cette directive + n'a pas encore t traduite. Veuillez vous reporter la version + en langue anglaise. LuaMapHandler Directive+
La documentation de cette directive + n'a pas encore t traduite. Veuillez vous reporter la version + en langue anglaise. LuaOutputFilter Directive+
La documentation de cette directive + n'a pas encore t traduite. Veuillez vous reporter la version + en langue anglaise. LuaPackageCPath Directive
|
---|