This ensures scripts execute in the order they appear in the config file,
resolving the TODO in the README. The config format has been changed from
a table with script names as keys to an ordered list of script entries.
Changes:
- ctx.lua: Use ipairs() instead of pairs() to iterate in order
- config.lua: Update validation to handle new list structure
- conf.lua: Update example config to use new format
- README.md: Remove TODO and clarify execution order
New config format:
wantedScripts = {
{name = 'script1', config = {...}},
{name = 'script2', config = {...}}
}
60 lines
1.8 KiB
Lua
60 lines
1.8 KiB
Lua
local util = require("util")
|
|
|
|
function log(msg)
|
|
ngx.log(ngx.STDERR, tostring(msg))
|
|
end
|
|
|
|
local ctx = {}
|
|
|
|
function ctx:setWantedScripts(graph)
|
|
self._wanted_scripts = graph
|
|
end
|
|
|
|
function ctx:loadFromConfig(conf)
|
|
ctx:setWantedScripts(conf.wantedScripts)
|
|
ctx:loadChain()
|
|
end
|
|
|
|
|
|
function ctx:loadChain()
|
|
self.compiled_chain = {}
|
|
for _, script_entry in ipairs(self._wanted_scripts) do
|
|
local module_name = script_entry.name
|
|
local module_config = script_entry.config
|
|
local module = require('scripts.' .. module_name)
|
|
local module_config_readonly = table.readonly(module_config)
|
|
local module_state = module.init(module_config_readonly)
|
|
table.insert(self.compiled_chain, {module, module_config_readonly, module_state})
|
|
end
|
|
end
|
|
|
|
function ctx:onRequest()
|
|
local request_uri = ngx.var.uri
|
|
|
|
-- find out which modules to call based on their regexes
|
|
local callbacks_to_call = {}
|
|
for _, filter in ipairs(self.compiled_chain) do
|
|
local module, module_config, state = unpack(filter)
|
|
|
|
for callback_regex, callback_function in pairs(module.callbacks) do
|
|
local match = ngx.re.match(request_uri, callback_regex)
|
|
if match then
|
|
table.insert(callbacks_to_call, {module, callback_function, module_config, state})
|
|
end
|
|
end
|
|
end
|
|
|
|
for _, tuple in ipairs(callbacks_to_call) do
|
|
local module, callback_function, config, state = unpack(tuple)
|
|
local status_code, body = callback_function(config, state)
|
|
if status_code ~= nil then
|
|
log('filtered by module ' .. module.name)
|
|
ngx.status = status_code
|
|
ngx.say(body or "request denied")
|
|
ngx.exit(status_code)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
return ctx
|