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

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,
}