Skip to content

Commit

Permalink
fix(response-transformer): fix the bug that response-transformer (#9463)
Browse files Browse the repository at this point in the history
Fix the error that the response from upstream is a plain string with Header Content-Type: application/json, the response transformer throw exception when transforming.

FTI-4352
  • Loading branch information
liverpool8056 authored Nov 4, 2022
1 parent 3aa2a96 commit c8d1f85
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@
[#9626](https://github.com/Kong/kong/pull/9626)


#### Plugins

- **Response-Transformer**: Fix the bug that Response-Transformer plugin
breaks when receiving an unexcepted boy.
[#9463](https://github.com/Kong/kong/pull/9463)

## [3.0.0]

> Released 2022/09/12
Expand Down
14 changes: 10 additions & 4 deletions kong/plugins/response-transformer/body_transformer.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local cjson = require("cjson.safe").new()
local cjson_decode = cjson.decode


local insert = table.insert
Expand All @@ -8,6 +9,8 @@ local sub = string.sub
local gsub = string.gsub
local match = string.match
local lower = string.lower
local tonumber = tonumber
local pcall = pcall


cjson.decode_array_with_array_mt(true)
Expand Down Expand Up @@ -39,9 +42,12 @@ local function cast_value(value, value_type)
end


local function read_json_body(body)
local function parse_json(body)
if body then
return cjson.decode(body)
local ok, res = pcall(cjson_decode, body)
if ok then
return res
end
end
end

Expand Down Expand Up @@ -90,9 +96,9 @@ end


function _M.transform_json_body(conf, buffered_data)
local json_body = read_json_body(buffered_data)
local json_body = parse_json(buffered_data)
if json_body == nil then
return
return nil, "failed parsing json body"
end

-- remove key:value to body
Expand Down
9 changes: 7 additions & 2 deletions kong/plugins/response-transformer/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,21 @@ end


function ResponseTransformerHandler:body_filter(conf)

if not is_body_transform_set(conf)
or not is_json_body(kong.response.get_header("Content-Type"))
then
return
end

local body = kong.response.get_raw_body()
if body then
return kong.response.set_raw_body(body_transformer.transform_json_body(conf, body))

local json_body, err = body_transformer.transform_json_body(conf, body)
if err then
kong.log.warn("body transform failed: " .. err)
return
end
return kong.response.set_raw_body(json_body)
end


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,68 @@ describe("Plugin: response-transformer", function()
assert.are.same(body, result)
end)
end)

describe("handle unexpected body type", function()
-- Related to issue https://github.com/Kong/kong/issues/9461

local old_kong, handler

lazy_setup(function()
old_kong = _G.kong
_G.kong = {
response = {
get_header = function(header)
if header == "Content-Type" then
return "application/json"
end
end,
get_raw_body = function()
return "not a json value"
end,
set_raw_body = function() end
},
log = {
warn = function() end
}
}

-- force module reload to use mock `_G.kong`
package.loaded["kong.plugins.response-transformer.handler"] = nil
handler = require("kong.plugins.response-transformer.handler")
end)

lazy_teardown(function()
_G.kong = old_kong
end)

it("gracefully fails transforming invalid json body", function()
local conf = {
remove = {
headers = {},
json = { "foo" }
},
add = {
headers = {},
json = {},
},
append = {
headers = {},
json = {},
},
replace = {
headers = {},
json = {},
},
}

local spy_response_get_header = spy.on(kong.response, "get_header")
local spy_response_get_raw_body = spy.on(kong.response, "get_raw_body")
local spy_response_set_raw_body = spy.on(kong.response, "set_raw_body")

assert.is_nil(handler:body_filter(conf))
assert.spy(spy_response_get_header).was_called_with("Content-Type")
assert.spy(spy_response_get_raw_body).was_called()
assert.spy(spy_response_set_raw_body).was_not_called()
end)
end)
end)

0 comments on commit c8d1f85

Please sign in to comment.