kong--kong
178 行
5.3 KiB
Lua
178 行
5.3 KiB
Lua
local ENVIRONMENT do
|
|
ENVIRONMENT = {}
|
|
|
|
local setmetatable = setmetatable
|
|
local getmetatable = getmetatable
|
|
local require = require
|
|
local package = package
|
|
local rawset = rawset
|
|
local ipairs = ipairs
|
|
local pairs = pairs
|
|
local error = error
|
|
local type = type
|
|
local _G = _G
|
|
|
|
local function wrap_method(self, method)
|
|
return function(_, ...)
|
|
return self[method](self, ...)
|
|
end
|
|
end
|
|
|
|
local function include(env, id)
|
|
-- The code here checks a lot of types and stuff, just to please our test suite
|
|
-- to not error out when used with mocks.
|
|
local m, sm, lf, f = id:match("([^%.]+)%.([^%.]+)%.([^%.]+)%.([^%.]+)")
|
|
if m then
|
|
env[m] = env[m] or {}
|
|
env[m][sm] = env[m][sm] or {}
|
|
env[m][sm][lf] = env[m][sm][lf] or {}
|
|
|
|
if m == "kong" and sm == "db" then
|
|
env[m][sm][lf][f] = type(_G[m]) == "table"
|
|
and type(_G[m][sm]) == "table"
|
|
and type(_G[m][sm][lf]) == "table"
|
|
and type(_G[m][sm][lf][f]) == "function"
|
|
and wrap_method(_G[m][sm][lf], f)
|
|
else
|
|
env[m][sm][lf][f] = type(_G[m]) == "table"
|
|
and type(_G[m][sm]) == "table"
|
|
and type(_G[m][sm][lf]) == "table"
|
|
and _G[m][sm][lf][f]
|
|
end
|
|
|
|
else
|
|
m, sm, f = id:match("([^%.]+)%.([^%.]+)%.([^%.]+)")
|
|
if m then
|
|
env[m] = env[m] or {}
|
|
env[m][sm] = env[m][sm] or {}
|
|
|
|
if m == "kong" and sm == "cache" then
|
|
env[m][sm][f] = type(_G[m]) == "table"
|
|
and type(_G[m][sm]) == "table"
|
|
and type(_G[m][sm][f]) == "function"
|
|
and wrap_method(_G[m][sm], f)
|
|
|
|
else
|
|
env[m][sm][f] = type(_G[m]) == "table"
|
|
and type(_G[m][sm]) == "table"
|
|
and _G[m][sm][f]
|
|
end
|
|
|
|
else
|
|
m, f = id:match("([^%.]+)%.([^%.]+)")
|
|
if m then
|
|
env[m] = env[m] or {}
|
|
env[m][f] = type(_G[m]) == "table" and _G[m][f]
|
|
|
|
else
|
|
env[id] = _G[id]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function protect_module(modname, mod)
|
|
return setmetatable(mod, {
|
|
__newindex = function(_, k, _)
|
|
return error(("Cannot modify %s.%s. Protected by the sandbox."): format(modname, k), -1)
|
|
end
|
|
})
|
|
end
|
|
|
|
local function protect_modules(mod, modname)
|
|
for k, v in pairs(mod) do
|
|
if type(v) == "table" then
|
|
protect_modules(v, modname and (modname .. "." .. k) or k)
|
|
end
|
|
end
|
|
|
|
if modname and modname ~= "ngx" then
|
|
protect_module(modname, mod)
|
|
end
|
|
end
|
|
|
|
local function protect(env)
|
|
protect_modules(env, "_G")
|
|
rawset(env, "_G", env)
|
|
|
|
local kong = kong
|
|
local ngx = ngx
|
|
|
|
if type(ngx) == "table" and type(env.ngx) == "table" then
|
|
-- this is needed for special ngx.{ctx|headers_sent|is_subrequest|status)
|
|
setmetatable(env.ngx, getmetatable(ngx))
|
|
|
|
-- libraries having metatable logic
|
|
rawset(env.ngx, "var", ngx.var)
|
|
rawset(env.ngx, "arg", ngx.arg)
|
|
rawset(env.ngx, "header", ngx.header)
|
|
end
|
|
|
|
if type(kong) == "table" and type(env.kong) == "table" then
|
|
-- __call meta-method for kong log
|
|
if type(kong.log) == "table" and type(env.kong.log) == "table" then
|
|
getmetatable(env.kong.log).__call = (getmetatable(kong.log) or {}).__call
|
|
|
|
if type(kong.log.inspect) == "table" and type(env.kong.log.inspect) == "table" then
|
|
getmetatable(env.kong.log.inspect).__call = (getmetatable(kong.log.inspect) or {}).__call
|
|
end
|
|
if type(kong.log.deprecation) == "table" and type(env.kong.log.deprecation) == "table" then
|
|
getmetatable(env.kong.log.deprecation).__call = (getmetatable(kong.log.deprecation) or {}).__call
|
|
end
|
|
end
|
|
|
|
if type(kong.configuration) == "table" and type(kong.configuration.remove_sensitive) == "function" then
|
|
-- only expose the non-sensitive parts of kong.configuration
|
|
rawset(env.kong, "configuration",
|
|
protect_module("kong.configuration", kong.configuration.remove_sensitive()))
|
|
end
|
|
|
|
if type(kong.ctx) == "table" then
|
|
-- only support kong.ctx.shared and kong.ctx.plugin
|
|
local ctx = kong.ctx
|
|
rawset(env.kong, "ctx", protect_module("kong.ctx", {
|
|
shared = setmetatable({}, {
|
|
__newindex = function(_, k, v)
|
|
ctx.shared[k] = v
|
|
end,
|
|
__index = function(_, k)
|
|
return ctx.shared[k]
|
|
end,
|
|
}),
|
|
plugin = setmetatable({}, {
|
|
__newindex = function(_, k, v)
|
|
ctx.plugin[k] = v
|
|
end,
|
|
__index = function(_, k)
|
|
return ctx.plugin[k]
|
|
end,
|
|
})
|
|
}))
|
|
end
|
|
end
|
|
|
|
return env
|
|
end
|
|
|
|
local sandbox_require = require("kong.tools.sandbox.require")
|
|
|
|
-- the order is from the biggest to the smallest so that package
|
|
-- unloading works properly (just to not leave garbage around)
|
|
for _, t in ipairs({ "handler", "schema", "lua" }) do
|
|
local env = {}
|
|
local package_name = "kong.tools.sandbox.environment." .. t
|
|
require(package_name):gsub("%S+", function(id)
|
|
include(env, id)
|
|
end)
|
|
package.loaded[package_name] = nil
|
|
rawset(env, "require", sandbox_require[t])
|
|
ENVIRONMENT[t] = protect(env)
|
|
end
|
|
|
|
package.loaded["kong.tools.sandbox.require"] = nil
|
|
end
|
|
|
|
|
|
return ENVIRONMENT
|