LuaFilter
This chapter provides an introduction to the LuaFilter. For a detailed description of the nevisProxy LuaFilter, see the LuaFilter Developer Guide. For more details about Lua itself, see the Official Lua Reference Guide.
The LuaFilter can be used for advanced scripting, including the rewriting of body data and/or headers of request and/or response.
A sample Lua script should visualize the idea:
function output(request, response, chunk)
if chunk == nil then
return "hello world"
end
end
The Script.OutputFunctionName
parameter must be output
. For every chunk of data from the backend, the script is called. The nil
chunk marks the end of the stream. The sample script replaces the response body with hello world
. Beside the body data there are two objects request
and response
(of course you can name this different). With these two objects, you access headers, environment variables and attributes.
The LuaFilter can call a Lua function that is defined in the init parameter Script.OutputHeaderFunctionName
. This function will be called once for every response before the body data, and can be used to add/set header attributes.
function outputHeader(req, resp)
resp:setHeader("outputHeader","called")
end
ch::nevis::isiweb4::filter::lua::LuaFilter
libLuaFilter.so.1
+NEEDS_PARAMS
Configuration
Script
Type: string
Usage Constraints: optional, basic
Lua script with implemented hook function. Be aware that every <
, >
and &
must be HTML-encoded like <
, >
, &
.
Script.Path
Type: string
Usage Constraints: optional, basic
Path to a Lua script file with implemented hook function(s).
Script.InputFunctionName
Type: string
Usage Constraints: optional, basic
Defines the Lua function name which is called on input. If the function name is not defined, nothing is called. The method's syntax expects three arguments:
- the request object
- the response object
- the request body chunk object
Script.InputHeaderFunctionName
Type: string
Usage Constraints: optional, basic
Defines the Lua function name which is called on input headers. This function does not need to deal with a possible request body. It is called once on every request. The method's syntax expects two arguments:
- the request object
- the response object
Script.OutputFunctionName
Type: string
Usage Constraints: optional, basic
Defines the Lua function name which is called on output. If the function name is not defined, nothing is called. The method's syntax expects three arguments:
- the request object
- the response object
- the response body chunk object
Script.OutputHeaderFunctionName
Type: string
Usage Constraints: optional, basic
Defines the Lua function name which is called on output headers. If it is not defined nothing is called. It is called once for every response. The method's syntax expects two arguments:
- the request object
- the response object.
Script.InputWebSocketFrameFunctionName
Type: string
Usage Constraints: optional, advanced
Defines the Lua function name which is called on websocket communication. If it is not defined nothing is called. It is called once for each websocket frame coming from the frontend. The method's syntax expects two arguments:
- the websocket frame object
- the websocket data
Script.OutputWebSocketFrameFunctionName
Type: string
Usage Constraints: optional, advanced
Defines the Lua function name which is called on websocket communication. If it is not defined nothing is called. It is called once for each websocket frame coming from the backend. The method's syntax expects two arguments:
- the websocket frame object
- the websocket data
Script.NotifySessionInvalidateFunctionName
Type: string
Usage Constraints: optional, advanced
Defines the function name which is called if a session is invalidated. For this function to be called, the LuaFilter has to be mapped to the same path as the filter which creates the session, e.g., the IdentityCreationFilter or AuthenticationFilter. The function has an input parameter of type session.
Script.GlobalStoreAttributeTimeoutFunctionName
Type: string
Usage Constraints: optional, advanced
Defines the function that will be called if an attribute in the global store expires. The called function has three input-parameters:
- the name of the expired attribute
- the value of the expired attribute
- the name of the servlet used for the global store
Script.Namespace
Type: string
Usage Constraints: optional, advanced
Define a namespace for filter attributes which will be propagated to the Lua script. The attributes are accessible in the Lua script with the prefixing namespace as global variables. Currently, dots are not allowed in the variable names.
If the parameter Script.OutputFunctionName is set, then the content-length header coming from the backend will be removed. This happens because the LuaFilter does not know whether the body will remain unchanged.
If the parameter Script.InputFunctionName is set, the content-length header will NOT be removed because of security issues: The body coming from the frontend (usually from the user) must not be modified, because it may contain an amount to transfer, etc. If you want to modify the body anyway, then either remove the content-length header in the script or adapt the header to the new length.
The following code block illustrates the use of script namespacing:
<filter>
<filter-name>LuaFilterTest</filter-name>
<filter-class>ch::nevis::isiweb4::filter::lua::LuaFilter</filter-class>
<init-param>
<param-name>Script.Namespace</param-name>
<param-value>My</param-value>
</init-param>
<init-param>
<param-name>MyParameter</param-name>
<param-value>my stuff</param-value>
</init-param>
<init-param>
<param-name>Script.OutputFunctionName</param-name>
<param-value>outputStream</param-value>
</init-param>
<init-param>
<param-name>Script</param-name>
<param-value>
firstHit = false
function outputStream(req, resp, chunk)
trace = req:getTracer()
if not firstHit then
firstHit = true
-- this should trace "This is my
-- parameter: my stuff"
trace:info("This is my parameter: "..MyParameter)
end
return chunk
end
</param-value>
</init-param>
</filter>