Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pdk): response.set_header support header argument with table array of string #12164

Merged
merged 13 commits into from
Dec 25, 2023
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
message: "response.set_header support header argument with table array of string"
type: bugfix
scope: PDK
12 changes: 10 additions & 2 deletions kong/pdk/private/checks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,19 @@ function checks.validate_header(name, value)

local tvalue = type(value)
if tvalue ~= "string" then
if tvalue == "number" or tvalue == "boolean" then
if tvalue == "table" then
for _, vv in ipairs(value) do
local tvv = type(vv)
if tvv ~= "string" then
windmgc marked this conversation as resolved.
Show resolved Hide resolved
error(fmt("invalid header value in array %q: got %s, " ..
"expected string", name, tvv), 3)
end
end
elseif tvalue == "number" or tvalue == "boolean" then
value = tostring(value)
else
error(fmt("invalid header value for %q: got %s, expected " ..
"string, number or boolean", name, tvalue), 3)
"array of string, string, number or boolean", name, tvalue), 3)
end
end
return value
Expand Down
5 changes: 2 additions & 3 deletions kong/pdk/response.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ local error = error
local pairs = pairs
local coroutine = coroutine
local cjson_encode = cjson.encode
local normalize_header = checks.normalize_header
local normalize_multi_header = checks.normalize_multi_header
local validate_header = checks.validate_header
local validate_headers = checks.validate_headers
Expand Down Expand Up @@ -431,7 +430,7 @@ local function new(self, major_version)
return
end

ngx.header[name] = normalize_header(value)
ngx.header[name] = normalize_multi_header(value)
end


Expand Down Expand Up @@ -463,7 +462,7 @@ local function new(self, major_version)

validate_header(name, value)

add_header(name, normalize_header(value))
add_header(name, normalize_multi_header(value))
end


Expand Down
5 changes: 2 additions & 3 deletions kong/pdk/service/request.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ local string_find = string.find
local string_sub = string.sub
local string_byte = string.byte
local string_lower = string.lower
local normalize_header = checks.normalize_header
local normalize_multi_header = checks.normalize_multi_header
local validate_header = checks.validate_header
local validate_headers = checks.validate_headers
Expand Down Expand Up @@ -312,7 +311,7 @@ local function new(self)
end
end

ngx.req.set_header(header, normalize_header(value))
ngx.req.set_header(header, normalize_multi_header(value))
end

---
Expand Down Expand Up @@ -343,7 +342,7 @@ local function new(self)
headers = { headers }
end

table_insert(headers, normalize_header(value))
table_insert(headers, normalize_multi_header(value))

ngx.req.set_header(header, headers)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ describe("Plugin: response-transformer", function()
header_transformer.transform_headers(conf, headers)
assert.same({}, headers)
end)
it("header rename when same header being set twice", function()
local headers = get_headers({ h1 = { "v1", "v2"}})
header_transformer.transform_headers(conf, headers)
assert.same({h2 = { "v1", "v2" }}, headers)
end)
end)
describe("replace", function()
local conf = {
Expand Down
4 changes: 2 additions & 2 deletions t/01-pdk/06-service-request/09-set_header.t
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ invalid header name "127001": got number, expected string
--- request
GET /t
--- response_body
invalid header value for "foo": got function, expected string, number or boolean
invalid header value for "foo": got function, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand All @@ -89,7 +89,7 @@ invalid header value for "foo": got function, expected string, number or boolean
--- request
GET /t
--- response_body
invalid header value for "foo": got nil, expected string, number or boolean
invalid header value for "foo": got nil, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand Down
4 changes: 2 additions & 2 deletions t/01-pdk/06-service-request/10-add_header.t
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ invalid header name "127001": got number, expected string
--- request
GET /t
--- response_body
invalid header value for "foo": got function, expected string, number or boolean
invalid header value for "foo": got function, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand All @@ -89,7 +89,7 @@ invalid header value for "foo": got function, expected string, number or boolean
--- request
GET /t
--- response_body
invalid header value for "foo": got nil, expected string, number or boolean
invalid header value for "foo": got nil, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand Down
43 changes: 39 additions & 4 deletions t/01-pdk/08-response/05-set_header.t
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ invalid header name "127001": got number, expected string



=== TEST 3: response.set_header() errors if value is not a string
=== TEST 3: response.set_header() errors if value is not a table contain array of string
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
Expand All @@ -89,8 +89,9 @@ invalid header name "127001": got number, expected string

local PDK = require "kong.pdk"
local pdk = PDK.new()
local set_header = { {} }

local ok, err = pcall(pdk.response.set_header, "foo", {})
local ok, err = pcall(pdk.response.set_header, "foo", set_header)
if not ok then
ngx.ctx.err = err
end
Expand All @@ -104,7 +105,7 @@ invalid header name "127001": got number, expected string
--- request
GET /t
--- response_body chop
invalid header value for "foo": got table, expected string, number or boolean
invalid header value in array "foo": got table, expected string
--- no_error_log
[error]

Expand Down Expand Up @@ -137,7 +138,7 @@ invalid header value for "foo": got table, expected string, number or boolean
--- request
GET /t
--- response_body chop
invalid header value for "foo": got nil, expected string, number or boolean
invalid header value for "foo": got nil, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand Down Expand Up @@ -277,3 +278,37 @@ GET /t
Transfer-Encoding: chunked
--- error_log
manually setting Transfer-Encoding. Ignored.


=== TEST 8: response.set_header() with header table
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
content_by_lua_block {
}

header_filter_by_lua_block {
ngx.header.content_length = nil

local PDK = require "kong.pdk"
local pdk = PDK.new()
local set_header = {"a", "b"}

pdk.response.set_header("X-Foo", set_header)
}

body_filter_by_lua_block {
local new_headers = ngx.resp.get_headers()

local cjson = require("cjson")
ngx.arg[1] = "X-Foo: {" .. new_headers["X-Foo"][1] .. "," .. new_headers["X-Foo"][2] .. "}"

ngx.arg[2] = true
}
}
--- request
GET /t
--- response_body chop
X-Foo: {a,b}
--- no_error_log
[error]
6 changes: 3 additions & 3 deletions t/01-pdk/08-response/06-add_header.t
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ invalid header name "127001": got number, expected string
local PDK = require "kong.pdk"
local pdk = PDK.new()

local ok, err = pcall(pdk.response.add_header, "foo", {})
local ok, err = pcall(pdk.response.add_header, "foo", {{}})
if not ok then
ngx.ctx.err = err
end
Expand All @@ -104,7 +104,7 @@ invalid header name "127001": got number, expected string
--- request
GET /t
--- response_body chop
invalid header value for "foo": got table, expected string, number or boolean
invalid header value in array "foo": got table, expected string
--- no_error_log
[error]

Expand Down Expand Up @@ -137,7 +137,7 @@ invalid header value for "foo": got table, expected string, number or boolean
--- request
GET /t
--- response_body chop
invalid header value for "foo": got nil, expected string, number or boolean
invalid header value for "foo": got nil, expected array of string, string, number or boolean
--- no_error_log
[error]

Expand Down
Loading