170 lines
3.5 KiB
Lua
170 lines
3.5 KiB
Lua
local cjson = require("cjson.safe").new()
|
|
local cjson_encode = cjson.encode
|
|
local cjson_decode = cjson.decode
|
|
|
|
|
|
local insert = table.insert
|
|
local type = type
|
|
local sub = string.sub
|
|
local gsub = string.gsub
|
|
local byte = string.byte
|
|
local match = string.match
|
|
local tonumber = tonumber
|
|
local pcall = pcall
|
|
|
|
|
|
cjson.decode_array_with_array_mt(true)
|
|
|
|
|
|
local noop = function() end
|
|
|
|
|
|
local QUOTE = byte([["]])
|
|
|
|
|
|
local _M = {}
|
|
|
|
|
|
local function toboolean(value)
|
|
if value == "true" then
|
|
return true
|
|
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
|
|
local function cast_value(value, value_type)
|
|
if value_type == "number" then
|
|
return tonumber(value)
|
|
|
|
elseif value_type == "boolean" then
|
|
return toboolean(value)
|
|
|
|
else
|
|
return value
|
|
end
|
|
end
|
|
|
|
|
|
local function json_value(value, json_type)
|
|
local v = cjson_encode(value)
|
|
if v and byte(v, 1) == QUOTE and byte(v, -1) == QUOTE then
|
|
v = gsub(sub(v, 2, -2), [[\"]], [["]]) -- To prevent having double encoded quotes
|
|
end
|
|
|
|
v = v and gsub(v, [[\/]], [[/]]) -- To prevent having double encoded slashes
|
|
|
|
if json_type then
|
|
v = cast_value(v, json_type)
|
|
end
|
|
|
|
return v
|
|
end
|
|
|
|
|
|
local function parse_json(body)
|
|
if body then
|
|
local ok, res = pcall(cjson_decode, body)
|
|
if ok then
|
|
return res
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function append_value(current_value, value)
|
|
local current_value_type = type(current_value)
|
|
|
|
if current_value_type == "string" then
|
|
return { current_value, value }
|
|
end
|
|
|
|
if current_value_type == "table" then
|
|
insert(current_value, value)
|
|
return current_value
|
|
end
|
|
|
|
return { value }
|
|
end
|
|
|
|
local function iter(config_array)
|
|
if type(config_array) ~= "table" then
|
|
return noop
|
|
end
|
|
|
|
return function(config_array, i)
|
|
i = i + 1
|
|
|
|
local current_pair = config_array[i]
|
|
if current_pair == nil then -- n + 1
|
|
return nil
|
|
end
|
|
|
|
local current_name, current_value = match(current_pair, "^([^:]+):*(.-)$")
|
|
if current_value == "" then
|
|
current_value = nil
|
|
end
|
|
|
|
return i, current_name, current_value
|
|
end, config_array, 0
|
|
end
|
|
|
|
|
|
function _M.transform_json_body(conf, buffered_data)
|
|
local json_body = parse_json(buffered_data)
|
|
if json_body == nil then
|
|
return nil, "failed parsing json body"
|
|
end
|
|
|
|
-- remove key:value to body
|
|
for _, name in iter(conf.remove.json) do
|
|
json_body[name] = nil
|
|
end
|
|
|
|
-- rename key to body
|
|
for _, old_name, new_name in iter(conf.rename.json) do
|
|
if json_body[old_name] ~= nil and new_name then
|
|
local value = json_body[old_name]
|
|
json_body[new_name] = value
|
|
json_body[old_name] = nil
|
|
end
|
|
end
|
|
|
|
-- replace key:value to body
|
|
local replace_json_types = conf.replace.json_types
|
|
for i, name, value in iter(conf.replace.json) do
|
|
local v = json_value(value, replace_json_types and replace_json_types[i])
|
|
|
|
if json_body[name] and v ~= nil then
|
|
json_body[name] = v
|
|
end
|
|
end
|
|
|
|
-- add new key:value to body
|
|
local add_json_types = conf.add.json_types
|
|
for i, name, value in iter(conf.add.json) do
|
|
local v = json_value(value, add_json_types and add_json_types[i])
|
|
|
|
if not json_body[name] and v ~= nil then
|
|
json_body[name] = v
|
|
end
|
|
end
|
|
|
|
-- append new key:value or value to existing key
|
|
local append_json_types = conf.append.json_types
|
|
for i, name, value in iter(conf.append.json) do
|
|
local v = json_value(value, append_json_types and append_json_types[i])
|
|
|
|
if v ~= nil then
|
|
json_body[name] = append_value(json_body[name], v)
|
|
end
|
|
end
|
|
|
|
return cjson_encode(json_body)
|
|
end
|
|
|
|
|
|
return _M
|