117 lines
2.7 KiB
Lua
117 lines
2.7 KiB
Lua
local fmt = string.format
|
|
local ipairs = ipairs
|
|
local type = type
|
|
local pairs = pairs
|
|
local sort = table.sort
|
|
local insert = table.insert
|
|
local concat = table.concat
|
|
|
|
local sha256_hex = require("kong.tools.sha256").sha256_hex
|
|
|
|
local _M = {}
|
|
|
|
|
|
local EMPTY = require("kong.tools.table").EMPTY
|
|
|
|
|
|
local function keys(t)
|
|
local res = {}
|
|
for k, _ in pairs(t) do
|
|
res[#res+1] = k
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
|
|
-- Return a string with the format "key=value(:key=value)*" of the
|
|
-- actual keys and values in args that are in vary_fields.
|
|
--
|
|
-- The elements are sorted so we get consistent cache actual_keys no matter
|
|
-- the order in which params came in the request
|
|
local function generate_key_from(args, vary_fields)
|
|
local cache_key = {}
|
|
|
|
for _, field in ipairs(vary_fields or {}) do
|
|
local arg = args[field]
|
|
if arg then
|
|
if type(arg) == "table" then
|
|
sort(arg)
|
|
insert(cache_key, field .. "=" .. concat(arg, ","))
|
|
|
|
elseif arg == true then
|
|
insert(cache_key, field)
|
|
|
|
else
|
|
insert(cache_key, field .. "=" .. tostring(arg))
|
|
end
|
|
end
|
|
end
|
|
|
|
return concat(cache_key, ":")
|
|
end
|
|
|
|
|
|
-- Return the component of cache_key for vary_query_params in params
|
|
--
|
|
-- If no vary_query_params are configured in the plugin, return
|
|
-- all of them.
|
|
local function params_key(params, plugin_config)
|
|
if not (plugin_config.vary_query_params or EMPTY)[1] then
|
|
local actual_keys = keys(params)
|
|
sort(actual_keys)
|
|
return generate_key_from(params, actual_keys)
|
|
end
|
|
|
|
return generate_key_from(params, plugin_config.vary_query_params)
|
|
end
|
|
_M.params_key = params_key
|
|
|
|
|
|
-- Return the component of cache_key for vary_headers in params
|
|
--
|
|
-- If no vary_query_params are configured in the plugin, return
|
|
-- the empty string.
|
|
local function headers_key(headers, plugin_config)
|
|
if not (plugin_config.vary_headers or EMPTY)[1] then
|
|
return ""
|
|
end
|
|
|
|
return generate_key_from(headers, plugin_config.vary_headers)
|
|
end
|
|
_M.headers_key = headers_key
|
|
|
|
|
|
local function prefix_uuid(consumer_id, route_id)
|
|
|
|
-- authenticated route
|
|
if consumer_id and route_id then
|
|
return fmt("%s:%s", consumer_id, route_id)
|
|
end
|
|
|
|
-- unauthenticated route
|
|
if route_id then
|
|
return route_id
|
|
end
|
|
|
|
-- global default
|
|
return "default"
|
|
end
|
|
_M.prefix_uuid = prefix_uuid
|
|
|
|
|
|
function _M.build_cache_key(consumer_id, route_id, method, uri,
|
|
params_table, headers_table, conf)
|
|
|
|
-- obtain cache key components
|
|
local prefix_digest = prefix_uuid(consumer_id, route_id)
|
|
local params_digest = params_key(params_table, conf)
|
|
local headers_digest = headers_key(headers_table, conf)
|
|
|
|
return sha256_hex(fmt("%s|%s|%s|%s|%s", prefix_digest, method, uri,
|
|
params_digest, headers_digest))
|
|
end
|
|
|
|
|
|
return _M
|