diff --git a/kong/plugins/response-transformer/body_transformer.lua b/kong/plugins/response-transformer/body_transformer.lua index 32694f616a7b..668f591e0ba2 100644 --- a/kong/plugins/response-transformer/body_transformer.lua +++ b/kong/plugins/response-transformer/body_transformer.lua @@ -92,7 +92,7 @@ end function _M.transform_json_body(conf, buffered_data) local json_body = read_json_body(buffered_data) if json_body == nil then - return + return nil, "failed reading json body" end -- remove key:value to body diff --git a/kong/plugins/response-transformer/handler.lua b/kong/plugins/response-transformer/handler.lua index 240501953b7f..04b5146849ce 100644 --- a/kong/plugins/response-transformer/handler.lua +++ b/kong/plugins/response-transformer/handler.lua @@ -28,7 +28,12 @@ function ResponseTransformerHandler:body_filter(conf) local body = kong.response.get_raw_body() if body then - return kong.response.set_raw_body(body_transformer.transform_json_body(conf, body)) + local transf_body, err = body_transformer.transform_json_body(conf, body) + if err then + kong.log.warn("body transformation failed: ", err) + return + end + return kong.response.set_raw_body(transf_body) end end diff --git a/spec/03-plugins/15-response-transformer/02-body_transformer_spec.lua b/spec/03-plugins/15-response-transformer/02-body_transformer_spec.lua index 41d7df53b1c7..5430bbdf7307 100644 --- a/spec/03-plugins/15-response-transformer/02-body_transformer_spec.lua +++ b/spec/03-plugins/15-response-transformer/02-body_transformer_spec.lua @@ -322,4 +322,69 @@ 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)