150 lines
4.0 KiB
Lua
150 lines
4.0 KiB
Lua
--- Contextual data for the current request.
|
|
--
|
|
-- @module kong.ctx
|
|
local get_request = require("resty.core.base").get_request
|
|
|
|
|
|
local setmetatable = setmetatable
|
|
local ngx = ngx
|
|
|
|
|
|
-- shared between all global instances
|
|
local _CTX_SHARED_KEY = {}
|
|
local _CTX_CORE_KEY = {}
|
|
|
|
|
|
---
|
|
-- A table that has the same lifetime as the current request. This table is shared
|
|
-- between all plugins. It can be used to share data between several plugins in a
|
|
-- given request.
|
|
--
|
|
-- This table is only relevant in the context of a request and cannot be
|
|
-- accessed from the top-level chunk of Lua modules. Instead, it can only be
|
|
-- accessed in request phases, which are represented by the `rewrite`,
|
|
-- `access`, `header_filter`, `response`, `body_filter`, `log`, and `preread` phases of
|
|
-- the plugin interfaces. Accessing this table in those functions (and their
|
|
-- callees) is fine.
|
|
--
|
|
-- Values inserted in this table by a plugin are visible by all other
|
|
-- plugins. Be careful when interacting with values in this table, as a naming
|
|
-- conflict could result in the overwrite of data.
|
|
--
|
|
-- @table kong.ctx.shared
|
|
-- @phases rewrite, access, header_filter, response, body_filter, log, preread
|
|
-- @usage
|
|
-- -- Two plugins A and B, and if plugin A has a higher priority than B's
|
|
-- -- (it executes before B):
|
|
--
|
|
-- -- plugin A handler.lua
|
|
-- function plugin_a_handler:access(conf)
|
|
-- kong.ctx.shared.foo = "hello world"
|
|
--
|
|
-- kong.ctx.shared.tab = {
|
|
-- bar = "baz"
|
|
-- }
|
|
-- end
|
|
--
|
|
-- -- plugin B handler.lua
|
|
-- function plugin_b_handler:access(conf)
|
|
-- kong.log(kong.ctx.shared.foo) -- "hello world"
|
|
-- kong.log(kong.ctx.shared.tab.bar) -- "baz"
|
|
-- end
|
|
|
|
|
|
---
|
|
-- A table that has the same lifetime as the current request. Unlike
|
|
-- `kong.ctx.shared`, this table is **not** shared between plugins.
|
|
-- Instead, it is only visible for the current plugin instance.
|
|
-- For example, if several instances of the Rate Limiting plugin
|
|
-- are configured on different Services, each instance has its
|
|
-- own table for every request.
|
|
--
|
|
-- Because of its namespaced nature, this table is safer for a plugin to use
|
|
-- than `kong.ctx.shared` since it avoids potential naming conflicts, which
|
|
-- could lead to several plugins unknowingly overwriting each other's data.
|
|
--
|
|
-- This table is only relevant in the context of a request and cannot be
|
|
-- accessed from the top-level chunk of Lua modules. Instead, it can only be
|
|
-- accessed in request phases, which are represented by the `rewrite`,
|
|
-- `access`, `header_filter`, `body_filter`, `log`, and `preread` phases
|
|
-- of the plugin interfaces. Accessing this table in those functions (and
|
|
-- their callees) is fine.
|
|
--
|
|
-- Values inserted in this table by a plugin are visible in successful
|
|
-- phases of this plugin's instance only.
|
|
--
|
|
-- @table kong.ctx.plugin
|
|
-- @phases rewrite, access, header_filter, response, body_filter, log, preread
|
|
-- @usage
|
|
-- -- plugin handler.lua
|
|
--
|
|
-- -- For example, if a plugin wants to
|
|
-- -- save some value for post-processing during the `log` phase:
|
|
--
|
|
-- function plugin_handler:access(conf)
|
|
-- kong.ctx.plugin.val_1 = "hello"
|
|
-- kong.ctx.plugin.val_2 = "world"
|
|
-- end
|
|
--
|
|
-- function plugin_handler:log(conf)
|
|
-- local value = kong.ctx.plugin.val_1 .. " " .. kong.ctx.plugin.val_2
|
|
--
|
|
-- kong.log(value) -- "hello world"
|
|
-- end
|
|
|
|
|
|
local function get_namespace(ctx, k)
|
|
if not ctx then
|
|
ctx = ngx.ctx
|
|
end
|
|
|
|
local namespaces = ctx.KONG_NAMESPACES
|
|
if not namespaces then
|
|
return
|
|
end
|
|
|
|
return namespaces[k]
|
|
end
|
|
|
|
|
|
local function new()
|
|
local _CTX = {}
|
|
local _ctx_mt = {}
|
|
|
|
function _ctx_mt.__index(_, k)
|
|
if not get_request() then
|
|
return
|
|
end
|
|
|
|
local nctx = ngx.ctx
|
|
local key
|
|
|
|
if k == "core" then
|
|
key = _CTX_CORE_KEY
|
|
|
|
elseif k == "shared" then
|
|
key = _CTX_SHARED_KEY
|
|
|
|
else
|
|
key = get_namespace(nctx, k)
|
|
end
|
|
|
|
if key then
|
|
local ctx = nctx[key]
|
|
if not ctx then
|
|
ctx = {}
|
|
nctx[key] = ctx
|
|
end
|
|
|
|
return ctx
|
|
end
|
|
end
|
|
|
|
return setmetatable(_CTX, _ctx_mt)
|
|
end
|
|
|
|
|
|
return {
|
|
new = new,
|
|
}
|