diff --git a/docs/manual/mod/directives.html.en b/docs/manual/mod/directives.html.en index ba286b0f48..09db20e271 100644 --- a/docs/manual/mod/directives.html.en +++ b/docs/manual/mod/directives.html.en @@ -358,7 +358,9 @@
LuaHookTranslateName
LuaHookTypeChecker
LuaInherit
LuaInputFilter
LuaMapHandler
LuaOutputFilter
LuaPackageCPath
LuaPackagePath
LuaQuickHandler
Data Structures
Logging Functions
apache2 Package
Modifying contents with Lua filters
- r:parsebody() -- parse any POST data in the request and return it as a Lua table
+r:parsebody([sizeLimit]) -- parse the request body as a POST and return a lua table.
+ -- An optional number may be passed to specify the maximum number
+ -- of bytes to parse. Default is 8192 bytes.
@@ -733,6 +738,47 @@ end
(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 ++
After a lua function has been registered as authorization provider, it can be used
with the Require directive:
In previous 2.3.x releases, the default was effectively to ignore LuaHook* directives from parent configuration sections.
+| 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. +
+| 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. +
+