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 module_name, module_config in pairs(self._wanted_scripts) do local module = require('scripts.' .. module_name) local module_state = module.init(module_config) -- TODO is it possible to make module_config readonly? table.insert(self.compiled_chain, {module, module_config, 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, error = 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) end end end return ctx