Files
2026-07-13 12:32:21 +08:00

119 lines
3.4 KiB
Lua

local sandbox = require "kong.tools.sandbox"
local kong_meta = require "kong.meta"
-- handler file for both the pre-function and post-function plugin
local config_cache do
local no_op = function() end
-- compiles the array for a phase into a single function
local function compile_phase_array(phase_funcs)
if not phase_funcs or #phase_funcs == 0 then
-- nothing to do for this phase
return no_op
else
-- compile the functions we got
local compiled = {}
for i, func_string in ipairs(phase_funcs) do
local func = assert(sandbox.sandbox(func_string))
local first_run_complete = false
compiled[i] = function()
-- this is a temporary closure, that will replace itself
if not first_run_complete then
first_run_complete = true
local result = func() --> this might call ngx.exit()
-- if we ever get here, then there was NO early exit from a 0.1.0
-- type config
if type(result) == "function" then
-- this is a new function (0.2.0+), with upvalues
-- the first call to func above only initialized it, so run again
func = result
compiled[i] = func
func() --> this again, may do an early exit
end
-- if we ever get here, then there was no early exit from either
-- 0.1.0 or 0.2.0+ code
-- Replace the entry of this closure in the array with the actual
-- function, since the closure is no longer needed.
compiled[i] = func
else
-- first run is marked as complete, but we (this temporary closure)
-- are being called again. So we are here only if the initial
-- function call did an early exit.
-- So replace this closure now;
compiled[i] = func
-- And call it again, for this 2nd run;
func()
end
-- unreachable
end
end
-- now return a function that executes the entire array
return function()
for _, f in ipairs(compiled) do f() end
end
end
end
local phases = { "certificate", "rewrite", "access",
"header_filter", "body_filter", "log" }
config_cache = setmetatable({}, {
__mode = "k",
__index = function(self, config)
-- config was not found yet, so go and compile our config functions
local runtime_funcs = {}
for _, phase in ipairs(phases) do
local func = compile_phase_array(config[phase])
runtime_funcs[phase] = func
end
-- store compiled results in cache, and return them
self[config] = runtime_funcs
return runtime_funcs
end
})
end
return function(priority)
local ServerlessFunction = {
PRIORITY = priority,
VERSION = kong_meta.version,
}
function ServerlessFunction:certificate(config)
config_cache[config].certificate()
end
function ServerlessFunction:rewrite(config)
config_cache[config].rewrite()
end
function ServerlessFunction:access(config)
config_cache[config].access()
end
function ServerlessFunction:header_filter(config)
config_cache[config].header_filter()
end
function ServerlessFunction:body_filter(config)
config_cache[config].body_filter()
end
function ServerlessFunction:log(config)
config_cache[config].log()
end
return ServerlessFunction
end