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

142 lines
3.4 KiB
Lua

local pl_template = require "pl.template"
local cycle_aware_deep_copy = require("kong.tools.table").cycle_aware_deep_copy
local typedefs = require "kong.db.schema.typedefs"
local validate_header_name = require("kong.tools.http").validate_header_name
local compile_opts = {
escape = "\xff", -- disable '#' as a valid template escape
}
-- entries must have colons to set the key and value apart
local function check_for_value(entry)
local name, value = entry:match("^([^:]+):*(.-)$")
if not name or not value or value == "" then
return false, "key '" ..name.. "' has no value"
end
local status, res, err = pcall(pl_template.compile, value, compile_opts)
if not status or err then
return false, "value '" .. value ..
"' is not in supported format, error:" ..
(status and res or err)
end
return true
end
local function validate_headers(pair, validate_value)
local name, value = pair:match("^([^:]+):*(.-)$")
if validate_header_name(name) == nil then
return nil, string.format("'%s' is not a valid header", tostring(name))
end
if validate_value then
if validate_header_name(value) == nil then
return nil, string.format("'%s' is not a valid header", tostring(value))
end
end
return true
end
local function validate_colon_headers(pair)
return validate_headers(pair, true)
end
local strings_array = {
type = "array",
default = {},
required = true,
elements = { type = "string" },
}
local headers_array = {
type = "array",
default = {},
required = true,
elements = { type = "string", custom_validator = validate_headers },
}
local strings_array_record = {
type = "record",
fields = {
{ body = strings_array },
{ headers = headers_array },
{ querystring = strings_array },
},
}
local colon_strings_array = {
type = "array",
default = {},
required = true,
elements = { type = "string", custom_validator = check_for_value }
}
local colon_header_value_array = {
type = "array",
default = {},
required = true,
elements = { type = "string", match = "^[^:]+:.*$", custom_validator = validate_headers },
}
local colon_strings_array_record = {
type = "record",
fields = {
{ body = colon_strings_array },
{ headers = colon_header_value_array },
{ querystring = colon_strings_array },
},
}
local colon_headers_array = {
type = "array",
default = {},
required = true,
elements = { type = "string", match = "^[^:]+:.*$", custom_validator = validate_colon_headers },
}
local colon_rename_strings_array_record = {
type = "record",
fields = {
{ body = colon_strings_array },
{ headers = colon_headers_array },
{ querystring = colon_strings_array },
},
}
local colon_strings_array_record_plus_uri = cycle_aware_deep_copy(colon_strings_array_record)
local uri = { uri = { type = "string" } }
table.insert(colon_strings_array_record_plus_uri.fields, uri)
return {
name = "request-transformer",
fields = {
{ protocols = typedefs.protocols },
{ config = {
type = "record",
fields = {
{ http_method = typedefs.http_method },
{ remove = strings_array_record },
{ rename = colon_rename_strings_array_record },
{ replace = colon_strings_array_record_plus_uri },
{ add = colon_strings_array_record },
{ append = colon_strings_array_record },
}
},
},
}
}