Skip to content

Commit

Permalink
fix(admin-api): nested parameters can be parsed correctly when using …
Browse files Browse the repository at this point in the history
…form-urlencoded requests (#13668)

When using curl to send a form-urlencoded request with nested parameters, such as

$ curl -X POST http://localhost:8001/parsed_params \
   --data 'items[1]=foo' \
   --data 'items[2]=bar'
the expected response is {"items":["foo","bar"]}, but instead, it returns {"items":{}}.

This is actually an EE issue, but I see that there is a risk of this in CE even though it doesn't currently occur. So I initiated that fix on CE.

The cause of the problem is due to the fact that nested parameters are lost when the decode_args method is called twice, without this fix.

FTI-6165
  • Loading branch information
ms2008 authored Oct 31, 2024
1 parent d1069e6 commit 5cab556
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/kong/fix-parse-nested-parameters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
message: Fixed an issue where nested parameters can not be parsed correctly when using form-urlencoded requests.
type: bugfix
scope: Admin API
4 changes: 3 additions & 1 deletion kong/tools/http.lua
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ do
end


-- { ["1"] = "a", ["2"] = "b" } becomes {"a", "b"}
-- { "a", "b" } becomes { "a", "b" }
local function decode_array(t)
local keys = {}
local len = 0
Expand All @@ -160,7 +162,7 @@ do
if keys[i] ~= i then
return nil
end
new_t[i] = t[tostring(i)]
new_t[i] = t[tostring(i)] or t[i]
end

return new_t
Expand Down
16 changes: 15 additions & 1 deletion spec/02-integration/04-admin_api/13-plugin-endpoints_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,23 @@ describe("Admin API endpoints added via plugins #" .. strategy, function()
path = "/method_without_exit",
headers = { ["Content-Type"] = "application/json" }
})
local body = assert.res_status(201 , res)
local body = assert.res_status(201, res)
assert.same("hello", body)
end)

it("nested parameters can be parsed correctly when using form-urlencoded requests", function()
local res = assert(client:send{
method = "POST",
path = "/parsed_params",
body = ngx.encode_args{
["items[1]"] = "foo",
["items[2]"] = "bar",
},
headers = { ["Content-Type"] = "application/x-www-form-urlencoded" }
})
local body = assert.res_status(200, res)
assert.same('{"items":["foo","bar"]}', body)
end)
end)

end
10 changes: 10 additions & 0 deletions spec/fixtures/custom_plugins/kong/plugins/admin-api-method/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ return {
ngx.print("hello")
end,
},
["/parsed_params"] = {
-- The purpose of the dummy filter is to let `parse_params`
-- of api/api_helpers.lua to be called twice.
before = function(self, db, helpers, parent)
end,

POST = function(self, db, helpers, parent)
kong.response.exit(200, self.params)
end,
},
}

1 comment on commit 5cab556

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bazel Build

Docker image available kong/kong:5cab556adc6b0c74c11b83baeb2b81010881e8dc
Artifacts available https://github.com/Kong/kong/actions/runs/11607298625

Please sign in to comment.