Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions apisix/patch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -414,20 +414,22 @@ function _M.patch()
end

-- Patch ngx.req.set_body_data to invalidate the parsed request body cache
-- in api_ctx. This ensures that body lookups and post_arg.* variable
-- lookups after a body rewrite always reflect the new body content.
-- in api_ctx. This ensures that body lookups, get_post_args(), and post_arg.* /
-- post_arg_* variable lookups after a body rewrite always reflect the new body content.
local _orig_set_body_data = ngx.req.set_body_data
ngx.req.set_body_data = function(data)
local api_ctx = ngx.ctx.api_ctx
if api_ctx and api_ctx._request_body_table then
if api_ctx then
api_ctx._request_body_table = nil
api_ctx._request_body_type = nil
api_ctx.req_post_args = nil
local var = api_ctx.var
local cache = var and var._cache
if cache then
local keys_to_clear = {}
for key in pairs(cache) do
if type(key) == "string" and key:sub(1, 9) == "post_arg." then
if type(key) == "string" and
(key:sub(1, 9) == "post_arg." or key:sub(1, 9) == "post_arg_") then
keys_to_clear[#keys_to_clear + 1] = key
end
end
Expand Down
55 changes: 55 additions & 0 deletions t/core/request.t
Original file line number Diff line number Diff line change
Expand Up @@ -611,3 +611,58 @@ header: new
body: nil
err: request size 17 is greater than the maximum size 8 allowed
kind: too_large



=== TEST 20: set_body_data invalidates req_post_args and post_arg.* / post_arg_* cache
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local ngx_ctx = ngx.ctx
local api_ctx = ngx_ctx.api_ctx
if api_ctx == nil then
api_ctx = core.tablepool.fetch("api_ctx", 0, 32)
ngx_ctx.api_ctx = api_ctx
end

core.ctx.set_vars_meta(api_ctx)

-- 1. Read post args using core.request.get_post_args
local args1 = core.request.get_post_args(api_ctx)
ngx.say("args1 foo: ", args1["foo"])

-- 2. Read post_arg.foo and post_arg_foo variables via api_ctx.var (populates var._cache)
ngx.say("var post_arg.foo: ", api_ctx.var["post_arg.foo"])
ngx.say("var post_arg_foo: ", api_ctx.var["post_arg_foo"])

-- 3. Rewrite body using ngx.req.set_body_data
ngx.req.set_body_data("foo=updated&bar=new")

-- 4. Re-read post args: should reflect updated body
local args2 = core.request.get_post_args(api_ctx)
ngx.say("args2 foo: ", args2["foo"])
ngx.say("args2 bar: ", args2["bar"])

-- 5. Re-read post_arg variables: should reflect updated body
ngx.say("updated var post_arg.foo: ", api_ctx.var["post_arg.foo"])
ngx.say("updated var post_arg.bar: ", api_ctx.var["post_arg.bar"])
ngx.say("updated var post_arg_foo: ", api_ctx.var["post_arg_foo"])
ngx.say("updated var post_arg_bar: ", api_ctx.var["post_arg_bar"])
}
}
--- request
POST /t
foo=initial&bar=original
--- more_headers
Content-Type: application/x-www-form-urlencoded
--- response_body
args1 foo: initial
var post_arg.foo: initial
var post_arg_foo: initial
args2 foo: updated
args2 bar: new
updated var post_arg.foo: updated
updated var post_arg.bar: new
updated var post_arg_foo: updated
updated var post_arg_bar: new
Loading