diff --git a/changelog/unreleased/kong/fix-grpc-gateway-json-decode-bug.yml b/changelog/unreleased/kong/fix-grpc-gateway-json-decode-bug.yml new file mode 100644 index 000000000000..5b170cb20c56 --- /dev/null +++ b/changelog/unreleased/kong/fix-grpc-gateway-json-decode-bug.yml @@ -0,0 +1,3 @@ +message: "**grpc-gateway**: When there is a JSON decoding error, respond with status 400 and error information in the body instead of status 500." +type: bugfix +scope: Plugin diff --git a/kong/plugins/grpc-gateway/deco.lua b/kong/plugins/grpc-gateway/deco.lua index 25cff2adda3f..92742f9f53b4 100644 --- a/kong/plugins/grpc-gateway/deco.lua +++ b/kong/plugins/grpc-gateway/deco.lua @@ -1,6 +1,6 @@ -- Copyright (c) Kong Inc. 2020 -local cjson = require "cjson" +local cjson = require "cjson.safe".new() local buffer = require "string.buffer" local pb = require "pb" local grpc_tools = require "kong.tools.grpc" @@ -227,7 +227,10 @@ function deco:upstream(body) local body_variable = self.endpoint.body_variable if body_variable then if body and #body > 0 then - local body_decoded = decode_json(body) + local body_decoded, err = decode_json(body) + if err then + return nil, "decode json err: " .. err + end if body_variable ~= "*" then --[[ // For HTTP methods that allow a request body, the `body` field diff --git a/kong/plugins/grpc-gateway/handler.lua b/kong/plugins/grpc-gateway/handler.lua index fdff4ed7e66e..a92c210aa699 100644 --- a/kong/plugins/grpc-gateway/handler.lua +++ b/kong/plugins/grpc-gateway/handler.lua @@ -120,7 +120,7 @@ function grpc_gateway:body_filter(conf) if not ret or #ret == 0 then if ngx_arg[2] then -- it's eof and we still cannot decode, fall through - ret = deco:get_raw_downstream_body() + ret = dec:get_raw_downstream_body() else -- clear output if we cannot decode, it could be body is not complete yet ret = nil diff --git a/spec/03-plugins/28-grpc-gateway/01-proxy_spec.lua b/spec/03-plugins/28-grpc-gateway/01-proxy_spec.lua index ab81ea106b9d..0f5d9530fd1d 100644 --- a/spec/03-plugins/28-grpc-gateway/01-proxy_spec.lua +++ b/spec/03-plugins/28-grpc-gateway/01-proxy_spec.lua @@ -208,6 +208,24 @@ for _, strategy in helpers.each_strategy() do assert.equal(400, res.status) end) + test("invalid json", function() + local res, _ = proxy_client:post("/bounce", { + headers = { ["Content-Type"] = "application/json" }, + body = [[{"message":"invalid}]] + }) + assert.equal(400, res.status) + assert.same(res:read_body(),"decode json err: Expected value but found unexpected end of string at character 21") + end) + + test("field type mismatch", function() + local res, _ = proxy_client:post("/bounce", { + headers = { ["Content-Type"] = "application/json" }, + body = [[{"message":1}]] + }) + assert.equal(400, res.status) + assert.same(res:read_body(),"failed to encode payload") + end) + describe("regression", function() test("empty array in json #10801", function() local req_body = { array = {}, nullable = "ahaha" }