kong/spec/03-plugins/36-request-transformer/02-access_spec.lua (2,193 lines of code) (raw):
local admin_api = require "spec.fixtures.admin_api"
local helpers = require "spec.helpers"
local cjson = require "cjson"
local pl_file = require "pl.file"
local function count_log_lines(pattern)
local cfg = helpers.test_conf
local logs = pl_file.read(cfg.prefix .. "/" .. cfg.proxy_error_log)
local _, count = logs:gsub(pattern, "")
return count
end
for _, strategy in helpers.each_strategy() do
describe("Plugin: request-transformer(access) [#" .. strategy .. "]", function()
local client
lazy_setup(function()
local bp = helpers.get_db_utils(strategy, {
"routes",
"services",
"plugins",
})
local route1 = bp.routes:insert({
hosts = { "test1.test" }
})
local route2 = bp.routes:insert({
hosts = { "test2.test" },
preserve_host = true,
})
local route3 = bp.routes:insert({
hosts = { "test3.test" }
})
local route4 = bp.routes:insert({
hosts = { "test4.test" }
})
local route5 = bp.routes:insert({
hosts = { "test5.test" }
})
local route6 = bp.routes:insert({
hosts = { "test6.test" }
})
local route7 = bp.routes:insert({
hosts = { "test7.test" }
})
local route8 = bp.routes:insert({
hosts = { "test8.test" }
})
local route9 = bp.routes:insert({
hosts = { "test9.test" }
})
local route10 = bp.routes:insert({
hosts = { "test10.test" },
paths = { "~/requests/user1/(?P<user1>\\w+)/user2/(?P<user2>\\S+)" },
strip_path = false
})
local route11 = bp.routes:insert({
hosts = { "test11.test" },
paths = { "~/requests/user1/(?P<user1>\\w+)/user2/(?P<user2>\\S+)" }
})
local route12 = bp.routes:insert({
hosts = { "test12.test" },
paths = { "/requests/" },
strip_path = false
})
local route13 = bp.routes:insert({
hosts = { "test13.test" },
paths = { "~/requests/user1/(?P<user1>\\w+)/user2/(?P<user2>\\S+)" }
})
local route14 = bp.routes:insert({
hosts = { "test14.test" },
paths = { "~/user1/(?P<user1>\\w+)/user2/(?P<user2>\\S+)" }
})
local route15 = bp.routes:insert({
hosts = { "test15.test" },
paths = { "~/requests/user1/(?<user1>\\w+)/user2/(?<user2>\\S+)" },
strip_path = false
})
local route16 = bp.routes:insert({
hosts = { "test16.test" },
paths = { "~/requests/user1/(?<user1>\\w+)/user2/(?<user2>\\S+)" },
strip_path = false
})
local route17 = bp.routes:insert({
hosts = { "test17.test" },
paths = { "~/requests/user1/(?<user1>\\w+)/user2/(?<user2>\\S+)" },
strip_path = false
})
local route18 = bp.routes:insert({
hosts = { "test18.test" },
paths = { "~/requests/user1/(?<user1>\\w+)/user2/(?<user2>\\S+)" },
strip_path = false
})
local route19 = bp.routes:insert({
hosts = { "test19.test" },
paths = { "~/requests/user1/(?<user1>\\w+)/user2/(?<user2>\\S+)" },
strip_path = false
})
local route20 = bp.routes:insert({
hosts = { "test20.test" }
})
local route21 = bp.routes:insert({
hosts = { "test21.test" }
})
local route22 = bp.routes:insert({
hosts = { "test22.test" }
})
local route23 = bp.routes:insert({
hosts = { "test23.test" },
paths = { "/request" }
})
local route24 = bp.routes:insert({
hosts = { "test24.test" }
})
local route25 = bp.routes:insert({
hosts = { "test25.test" }
})
local route26 = bp.routes:insert({
hosts = { "test26.test" }
})
local route27 = bp.routes:insert({
hosts = { "test27.test" }
})
local route28 = bp.routes:insert({
hosts = { "test28.test" }
})
bp.plugins:insert {
route = { id = route1.id },
name = "request-transformer",
config = {
add = {
headers = {"h1:v1", "h2:value:2"}, -- payload containing a colon
querystring = {"q1:v1"},
body = {"p1:v1"}
}
}
}
bp.plugins:insert {
route = { id = route2.id },
name = "request-transformer",
config = {
add = {
headers = {"host:mark"}
}
}
}
bp.plugins:insert {
route = { id = route3.id },
name = "request-transformer",
config = {
add = {
headers = {"x-added:a1", "x-added2:b1", "x-added3:c2"},
querystring = {"query-added:newvalue", "p1:anything:1"}, -- payload containing a colon
body = {"newformparam:newvalue"}
},
remove = {
headers = {"x-to-remove"},
querystring = {"toremovequery"}
},
append = {
headers = {"x-added:a2", "x-added:a3"},
querystring = {"p1:a2", "p2:b1"}
},
replace = {
headers = {"x-to-replace:false"},
querystring = {"toreplacequery:no"}
}
}
}
bp.plugins:insert {
route = { id = route4.id },
name = "request-transformer",
config = {
remove = {
headers = {"x-to-remove"},
querystring = {"q1"},
body = {"toremoveform"}
}
}
}
bp.plugins:insert {
route = { id = route5.id },
name = "request-transformer",
config = {
replace = {
headers = {"h1:v1"},
querystring = {"q1:v1"},
body = {"p1:v1"}
}
}
}
bp.plugins:insert {
route = { id = route6.id },
name = "request-transformer",
config = {
append = {
headers = {"h1:v1", "h1:v2", "h2:v1",},
querystring = {"q1:v1", "q1:v2", "q2:v1"},
body = {"p1:v1", "p1:v2", "p2:value:1"} -- payload containing a colon
}
}
}
bp.plugins:insert {
route = { id = route7.id },
name = "request-transformer",
config = {
http_method = "POST"
}
}
bp.plugins:insert {
route = { id = route8.id },
name = "request-transformer",
config = {
http_method = "GET"
}
}
bp.plugins:insert {
route = { id = route9.id },
name = "request-transformer",
config = {
rename = {
headers = {"x-to-rename:x-is-renamed"},
querystring = {"originalparam:renamedparam"},
body = {"originalparam:renamedparam"}
}
}
}
bp.plugins:insert {
route = { id = route10.id },
name = "request-transformer",
config = {
add = {
querystring = {"uri_param1:$(uri_captures.user1)", "uri_param2[some_index][1]:$(uri_captures.user2)"},
}
}
}
bp.plugins:insert {
route = { id = route11.id },
name = "request-transformer",
config = {
replace = {
uri = "/requests/user2/$(uri_captures.user2)/user1/$(uri_captures.user1)",
}
}
}
bp.plugins:insert {
route = { id = route12.id },
name = "request-transformer",
config = {
add = {
querystring = {"uri_param1:$(uri_captures.user1 or 'default1')", "uri_param2:$(uri_captures.user2 or 'default2')"},
}
}
}
bp.plugins:insert {
route = { id = route13.id },
name = "request-transformer",
config = {
replace = {
uri = "/requests/user2/$(10 * uri_captures.user1)",
}
}
}
bp.plugins:insert {
route = { id = route14.id },
name = "request-transformer",
config = {
replace = {
uri = "/requests$(uri_captures[0])",
}
}
}
bp.plugins:insert {
route = { id = route15.id },
name = "request-transformer",
config = {
add = {
querystring = {"uri_param1:$(uri_captures.user1)", "uri_param2:$(headers.host)"},
headers = {"x-test-header:$(query_params.q1)"}
},
remove = {
querystring = {"q1"},
}
}
}
bp.plugins:insert {
route = { id = route16.id },
name = "request-transformer",
config = {
replace = {
querystring = {"q2:$(headers['x-remove-header'])"},
},
add = {
querystring = {"q1:$(uri_captures.user1)"},
headers = {"x-test-header:$(headers['x-remove-header'])"}
},
remove = {
headers = {"x-remove-header"}
},
}
}
bp.plugins:insert {
route = { id = route17.id },
name = "request-transformer",
config = {
replace = {
querystring = {"q2:$(headers['x-replace-header'])"},
headers = {"x-replace-header:the new value"}
},
add = {
querystring = {"q1:$(uri_captures.user1)"},
headers = {"x-test-header:$(headers['x-replace-header'])"}
}
}
}
bp.plugins:insert {
route = { id = route18.id },
name = "request-transformer",
config = {
add = {
querystring = {[[q1:$('$(uri_captures.user1)')]]},
}
}
}
bp.plugins:insert {
route = { id = route19.id },
name = "request-transformer",
config = {
add = {
-- will trigger a runtime error
querystring = {[[q1:$(ERROR())]]},
}
}
}
bp.plugins:insert {
route = { id = route20.id },
name = "request-transformer",
config = {
http_method = "POST",
add = {
headers = {
"Content-Type:application/json"
},
body = { "body:somecontent" }
},
}
}
do
-- 2 plugins:
-- pre-function: plugin to inject a shared value in the kong.ctx.shared table
-- transformer: pick up the injected value and add to the query string
bp.plugins:insert {
route = { id = route21.id },
name = "pre-function",
config = {
access = {
[[
kong.ctx.shared.my_version = "1.2.3"
]]
},
}
}
bp.plugins:insert {
route = { id = route21.id },
name = "request-transformer",
config = {
add = {
querystring = {"shared_param1:$(shared.my_version)"},
}
}
}
end
bp.plugins:insert {
route = { id = route22.id },
name = "request-transformer",
config = {
http_method = "POST",
remove = {
headers = { "Authorization" },
},
add = {
headers = { "Authorization:Basic test" },
},
},
}
bp.plugins:insert {
route = { id = route23.id },
name = "request-transformer",
config = {}
}
bp.plugins:insert {
route = { id = route24.id },
name = "request-transformer",
config = {
add = {
headers = { "x-user-agent:$(foo(headers[\"User-Agent\"]) == \"table\" and headers[\"User-Agent\"][1] or headers[\"User-Agent\"])", },
},
}
}
bp.plugins:insert {
route = { id = route25.id },
name = "request-transformer",
config = {
add = {
headers = { "X-Foo-Transformed:$(type(headers[\"X-Foo\"]) == \"table\" and headers[\"X-Foo\"][1] .. \"-first\" or headers[\"X-Foo\"])", },
},
}
}
bp.plugins:insert {
route = { id = route26.id },
name = "request-transformer",
config = {
add = {
headers = {"X-aDDed:a1", "x-aDDed2:b1", "x-Added3:c2"},
},
remove = {
headers = {"X-To-Remove"},
},
append = {
headers = {"X-aDDed:a2", "X-aDDed:a3"},
},
replace = {
headers = {"x-to-Replace:false"},
}
}
}
bp.plugins:insert {
route = { id = route27.id },
name = "request-transformer",
config = {
replace = {
uri = "/requests/tést",
}
}
}
-- transformer attempts to inject a value in ngx.ctx.shared, but that will result in an invalid template
-- which provokes a failure
bp.plugins:insert {
route = { id = route28.id },
name = "request-transformer",
config = {
add = {
headers = { "X-Write-Attempt:$(shared.written = true)" },
}
}
}
assert(helpers.start_kong({
database = strategy,
plugins = "bundled, request-transformer",
nginx_conf = "spec/fixtures/custom_nginx.template",
}))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
before_each(function()
client = helpers.proxy_client()
end)
after_each(function()
if client then client:close() end
end)
describe("http method", function()
it("changes the HTTP method from GET to POST", function()
local r = assert(client:send {
method = "GET",
path = "/request?hello=world&name=marco",
headers = {
host = "test7.test"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equal("POST", json.vars.request_method)
assert.equal("world", json.uri_args.hello)
assert.equal("marco", json.uri_args.name)
end)
it("changes the HTTP method from POST to GET", function()
local r = assert(client:send {
method = "POST",
path = "/request?hello=world",
body = {
name = "marco"
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test8.test"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equal("GET", json.vars.request_method)
assert.equal("world", json.uri_args.hello)
assert.equal("marco", json.uri_args.name)
end)
it("changes the HTTP method from GET to POST and adds JSON body", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test20.test",
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.request(r).has.jsonbody()
assert.equal("POST", json.vars.request_method)
assert.is_nil(json.post_data.error)
local header_content_type = assert.request(r).has.header("Content-Type")
assert.equals("application/json", header_content_type)
end)
end)
describe("remove", function()
it("specified header", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test4.test",
["x-to-remove"] = "true",
["x-another-header"] = "true"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("x-to-remove")
assert.request(r).has.header("x-another-header")
end)
it("parameters on url encoded form POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["toremoveform"] = "yes",
["nottoremove"] = "yes"
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test4.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("toremoveform")
local value = assert.request(r).has.formparam("nottoremove")
assert.equals("yes", value)
end)
it("parameters from JSON body in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["toremoveform"] = "yes",
["nottoremove"] = "yes"
},
headers = {
host = "test4.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local json = assert.request(r).has.jsonbody()
assert.is_nil(json.params["toremoveform"])
assert.equals("yes", json.params["nottoremove"])
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test4.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equals("json (error)", json.post_data.kind)
assert.not_nil(json.post_data.error)
end)
it("does not fail if body is empty and content type is application/json in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {},
headers = {
host = "test4.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equals('{}', json.post_data.text)
assert.equals("2", json.headers["content-length"])
end)
it("does not fail if body is empty in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "",
headers = {
host = "test4.test"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.same(cjson.null, json.post_data.params)
assert.equal('', json.post_data.text)
local value = assert.request(r).has.header("content-length")
assert.equal("0", value)
end)
it("parameters on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["toremoveform"] = "yes",
["nottoremove"] = "yes"
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test4.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("toremoveform")
local value = assert.request(r).has.formparam("nottoremove")
assert.equals("yes", value)
end)
it("args on GET if it exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
q1 = "v1",
q2 = "v2",
},
body = {
hello = "world"
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test4.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.queryparam("q1")
local value = assert.request(r).has.queryparam("q2")
assert.equals("v2", value)
end)
end)
describe("rename", function()
it("specified header", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test9.test",
["x-to-rename"] = "true",
["x-another-header"] = "true"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("x-to-rename")
assert.request(r).has.header("x-is-renamed")
assert.request(r).has.header("x-another-header")
end)
it("does not add as new header if header does not exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
body = {},
headers = {
host = "test9.test",
["x-a-header"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("renamedparam")
local h_a_header = assert.request(r).has.header("x-a-header")
assert.equals("true", h_a_header)
end)
it("specified parameters in url encoded body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
originalparam = "yes",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("originalparam")
local value = assert.request(r).has.formparam("renamedparam")
assert.equals("yes", value)
end)
it("does not add as new parameter in url encoded body if parameter does not exist on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["x-a-header"] = "true",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.formparam("renamedparam")
local value = assert.request(r).has.formparam("x-a-header")
assert.equals("true", value)
end)
it("parameters from JSON body in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["originalparam"] = "yes",
["nottorename"] = "yes"
},
headers = {
host = "test9.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local json = assert.request(r).has.jsonbody()
assert.is_nil(json.params["originalparam"])
assert.is_not_nil(json.params["renamedparam"])
assert.equals("yes", json.params["renamedparam"])
assert.equals("yes", json.params["nottorename"])
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test9.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equals("json (error)", json.post_data.kind)
assert.is_not_nil(json.post_data.error)
end)
it("parameters on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["originalparam"] = "yes",
["nottorename"] = "yes"
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("originalparam")
local value = assert.request(r).has.formparam("renamedparam")
assert.equals("yes", value)
local value2 = assert.request(r).has.formparam("nottorename")
assert.equals("yes", value2)
end)
it("args on GET if it exists", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
originalparam = "true",
nottorename = "true",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.queryparam("originalparam")
local value1 = assert.request(r).has.queryparam("renamedparam")
assert.equals("true", value1)
local value2 = assert.request(r).has.queryparam("nottorename")
assert.equals("true", value2)
end)
end)
describe("rename", function()
it("specified header", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test9.test",
["x-to-rename"] = "true",
["x-another-header"] = "true"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("x-to-rename")
assert.request(r).has.header("x-is-renamed")
assert.request(r).has.header("x-another-header")
end)
it("does not add as new header if header does not exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
body = {},
headers = {
host = "test9.test",
["x-a-header"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("renamedparam")
local h_a_header = assert.request(r).has.header("x-a-header")
assert.equals("true", h_a_header)
end)
it("specified parameters in url encoded body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
originalparam = "yes",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("originalparam")
local value = assert.request(r).has.formparam("renamedparam")
assert.equals("yes", value)
end)
it("does not add as new parameter in url encoded body if parameter does not exist on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["x-a-header"] = "true",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.formparam("renamedparam")
local value = assert.request(r).has.formparam("x-a-header")
assert.equals("true", value)
end)
it("parameters from JSON body in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["originalparam"] = "yes",
["nottorename"] = "yes"
},
headers = {
host = "test9.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local json = assert.request(r).has.jsonbody()
assert.is_nil(json.params["originalparam"])
assert.is_not_nil(json.params["renamedparam"])
assert.equals("yes", json.params["renamedparam"])
assert.equals("yes", json.params["nottorename"])
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test9.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equals("json (error)", json.post_data.kind)
assert.is_not_nil(json.post_data.error)
end)
it("parameters on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
["originalparam"] = "yes",
["nottorename"] = "yes"
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("originalparam")
local value = assert.request(r).has.formparam("renamedparam")
assert.equals("yes", value)
local value2 = assert.request(r).has.formparam("nottorename")
assert.equals("yes", value2)
end)
it("args on GET if it exists", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
originalparam = "true",
nottorename = "true",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test9.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.queryparam("originalparam")
local value1 = assert.request(r).has.queryparam("renamedparam")
assert.equals("true", value1)
local value2 = assert.request(r).has.queryparam("nottorename")
assert.equals("true", value2)
end)
end)
describe("replace", function()
it("specified header if it exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
body = {},
headers = {
host = "test5.test",
h1 = "V",
h2 = "v2",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("h1")
assert.equals("v1", h_h1)
local h_h2 = assert.request(r).has.header("h2")
assert.equals("v2", h_h2)
end)
it("does not add as new header if header does not exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
body = {},
headers = {
host = "test5.test",
h2 = "v2",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("h1")
local h_h2 = assert.request(r).has.header("h2")
assert.equals("v2", h_h2)
end)
it("specified parameters in url encoded body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "v",
p2 = "v1",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test5.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.formparam("p1")
assert.equals("v1", value)
local value = assert.request(r).has.formparam("p2")
assert.equals("v1", value)
end)
it("does not add as new parameter in url encoded body if parameter does not exist on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p2 = "v1",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test5.test"
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.formparam("p1")
local value = assert.request(r).has.formparam("p2")
assert.equals("v1", value)
end)
it("specified parameters in json body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "v",
p2 = "v1"
},
headers = {
host = "test5.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.request(r).has.jsonbody()
assert.equals("v1", json.params.p1)
assert.equals("v1", json.params.p2)
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test5.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equal("json (error)", json.post_data.kind)
assert.is_not_nil(json.post_data.error)
end)
it("does not add as new parameter in json if parameter does not exist on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p2 = "v1",
},
headers = {
host = "test5.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.request(r).has.jsonbody()
assert.is_nil(json.params.p1)
assert.equals("v1", json.params.p2)
end)
it("specified parameters on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "v",
p2 = "v1",
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test5.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.equals("v1", value)
local value2 = assert.request(r).has.formparam("p2")
assert.equals("v1", value2)
end)
it("does not add as new parameter if parameter does not exist on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p2 = "v1",
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test5.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.formparam("p1")
local value = assert.request(r).has.formparam("p2")
assert.equals("v1", value)
end)
it("args on POST if it exist", function()
local r = assert(client:send {
method = "POST",
path = "/request",
query = {
q1 = "v",
q2 = "v2",
},
body = {
hello = "world"
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test5.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q1")
assert.equals("v1", value)
local value = assert.request(r).has.queryparam("q2")
assert.equals("v2", value)
end)
it("does not add new args on POST if it does not exist", function()
local r = assert(client:send {
method = "POST",
path = "/request",
query = {
q2 = "v2",
},
body = {
hello = "world"
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test5.test"
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.queryparam("q1")
local value = assert.request(r).has.queryparam("q2")
assert.equals("v2", value)
end)
pending("escape UTF-8 characters when replacing upstream path - enable after Kong 2.4", function()
local r = assert(client:send {
method = "GET",
path = "/requests/wrong_path",
headers = {
host = "test27.test"
}
})
assert.response(r).has.status(200)
local body = assert(assert.response(r).has.jsonbody())
assert.equals(helpers.mock_upstream_url ..
"/requests/t%C3%A9st", body.url)
end)
end)
describe("add", function()
it("new headers", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test1.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("h1")
assert.equals("v1", h_h1)
local h_h2 = assert.request(r).has.header("h2")
assert.equals("value:2", h_h2)
end)
it("does not change or append value if header already exists", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
h1 = "v3",
host = "test1.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("h1")
assert.equals("v3", h_h1)
local h_h2 = assert.request(r).has.header("h2")
assert.equals("value:2", h_h2)
end)
it("new parameter in url encoded body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.formparam("hello")
assert.equals("world", value)
local value = assert.request(r).has.formparam("p1")
assert.equals("v1", value)
end)
it("does not change or append value to parameter in url encoded body on POST when parameter exists", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "should not change",
hello = "world",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.formparam("p1")
assert.equals("should not change", value)
local value = assert.request(r).has.formparam("hello")
assert.equals("world", value)
end)
it("new parameter in JSON body on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
["Content-Type"] = "application/json",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local params = assert.request(r).has.jsonbody().params
assert.equals("world", params.hello)
assert.equals("v1", params.p1)
end)
it("does not change or append value to parameter in JSON on POST when parameter exists", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "this should not change",
hello = "world",
},
headers = {
["Content-Type"] = "application/json",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local params = assert.request(r).has.jsonbody().params
assert.equals("world", params.hello)
assert.equals("this should not change", params.p1)
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test1.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equal("json (error)", json.post_data.kind)
assert.is_not_nil(json.post_data.error)
end)
it("new parameter on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test1.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.equals("v1", value)
end)
it("does not change or append value to parameter on multipart POST when parameter exists", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "this should not change",
hello = "world",
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test1.test"
},
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.equals("this should not change", value)
local value2 = assert.request(r).has.formparam("hello")
assert.equals("world", value2)
end)
it("new querystring on GET", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
q2 = "v2",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q2")
assert.equals("v2", value)
local value = assert.request(r).has.queryparam("q1")
assert.equals("v1", value)
end)
it("does not change or append value to querystring on GET if querystring exists", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
q1 = "v2",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test1.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q1")
assert.equals("v2", value)
end)
it("should not change the host header", function()
local r = assert(client:send {
method = "GET",
path = "/get",
headers = {
["Content-Type"] = "application/json",
host = "test2.test"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
local value = assert.has.header("host", json)
assert.equals("test2.test", value)
end)
end)
describe("append ", function()
it("new header if header does not exists", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test6.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h2 = assert.request(r).has.header("h2")
assert.equals("v1", h_h2)
end)
it("values to existing headers", function()
local r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test6.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("h1")
assert.same({"v1", "v2"}, h_h1)
end)
it("can append a value with '#' (regression test for #29)", function()
local route = admin_api.routes:insert({
hosts = { "test_append_hash.test" }
})
admin_api.plugins:insert {
route = { id = route.id },
name = "request-transformer",
config = {
append = {
headers = {"h1:v1", "h1:v2", "h1:#value_with_hash", "h2:v1",},
querystring = {"q1:v1", "q1:v2", "q2:v1"},
body = {"p1:v1", "p1:v2", "p2:value:1"} -- payload containing a colon
}
}
}
local r
helpers.wait_until(function()
r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test_append_hash.test"
}
})
local body = r:read_body()
return string.find(body, "h1", 1, true)
end, 10)
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("h1")
assert.same({"v1", "v2", "#value_with_hash"}, h_h1)
end)
it("new querystring if querystring does not exists", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test6.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q2")
assert.equals("v1", value)
end)
it("values to existing querystring", function()
local r = assert(client:send {
method = "POST",
path = "/request",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test6.test"
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q1")
assert.are.same({"v1", "v2"}, value)
end)
it("new parameter in url encoded body on POST if it does not exist", function()
local r = assert( client:send {
method = "POST",
path = "/request",
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test6.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.same({"v1", "v2"}, value)
local value2 = assert.request(r).has.formparam("p2")
assert.same("value:1", value2)
end)
it("values to existing parameter in url encoded body if parameter already exist on POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "v0",
},
headers = {
["Content-Type"] = "application/x-www-form-urlencoded",
host = "test6.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.same({"v0", "v1", "v2"}, value)
local value2 = assert.request(r).has.formparam("p2")
assert.are.same("value:1", value2)
end)
it("does not fail if JSON body is malformed in POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = "malformed json body",
headers = {
host = "test6.test",
["content-type"] = "application/json"
}
})
assert.response(r).has.status(200)
local json = assert.response(r).has.jsonbody()
assert.equal("json (error)", json.post_data.kind)
assert.is_not_nil(json.post_data.error)
end)
it("does not change or append value to parameter on multipart POST", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
p1 = "This should not change",
},
headers = {
["Content-Type"] = "multipart/form-data",
host = "test6.test"
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local value = assert.request(r).has.formparam("p1")
assert.equals("This should not change", value)
end)
end)
describe("remove, replace, add and append ", function()
it("removes a header", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["x-to-remove"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("x-to-remove")
end)
it("replaces value of header, if header exist", function()
local r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["x-to-replace"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-to-replace")
assert.equals("false", hval)
end)
it("does not add new header if to be replaced header does not exist", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("x-to-replace")
end)
it("add new header if missing", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-added2")
assert.equals("b1", hval)
end)
it("does not add new header if it already exist", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["x-added3"] = "c1",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-added3")
assert.equals("c1", hval)
end)
it("appends values to existing headers", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-added")
assert.same({"a1", "a2", "a3"}, hval)
end)
it("adds new parameters on POST when query string key missing", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("p2")
assert.equals("b1", value)
end)
it("removes parameters on GET", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
toremovequery = "yes",
nottoremove = "yes",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.queryparam("toremovequery")
local value = assert.request(r).has.queryparam("nottoremove")
assert.equals("yes", value)
end)
it("replaces parameters on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
toreplacequery = "yes",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("toreplacequery")
assert.equals("no", value)
end)
it("does not add new parameter if to be replaced parameters does not exist on GET", function()
local r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.formparam("toreplacequery")
end)
it("adds parameters on GET if it does not exist", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("query-added")
assert.equals("newvalue", value)
end)
it("does not add new parameter if to be added parameters already exist on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
["query-added"] = "oldvalue",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("query-added")
assert.equals("oldvalue", value)
end)
it("appends parameters on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
q1 = "20",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("p1")
assert.equals("anything:1", value[1])
assert.equals("a2", value[2])
local value = assert.request(r).has.queryparam("q1")
assert.equals("20", value)
end)
it("removes a header -- ignore case", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
["x-to-remove"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.header("X-To-Remove")
end)
it("replaces value of header, if header exist -- don't change header case", function()
local r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
["x-to-replace"] = "true",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-to-Replace")
assert.equals("false", hval)
end)
it("add new header if missing -- keep configured case", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-aDDed2")
assert.equals("b1", hval)
end)
it("does not add new header if it already exist -- keep request case", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
["x-added3"] = "c1",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("x-added3")
assert.equals("c1", hval)
end)
it("appends values to existing headers -- keep config case", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
["X-addeD"] = "a0",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("X-aDDed")
assert.same({"a0", "a2", "a3"}, hval)
end)
it("appends values to added headers -- keep 'add' config case", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test26.test",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local hval = assert.request(r).has.header("X-Added")
assert.same({"a1", "a2", "a3"}, hval)
end)
it("adds new parameters on POST when query string key missing", function()
local r = assert(client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("p2")
assert.equals("b1", value)
end)
it("removes parameters on GET", function()
local r = assert( client:send {
method = "GET",
path = "/request",
query = {
toremovequery = "yes",
nottoremove = "yes",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
assert.request(r).has.no.queryparam("toremovequery")
local value = assert.request(r).has.queryparam("nottoremove")
assert.equals("yes", value)
end)
it("replaces parameters on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
toreplacequery = "yes",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("toreplacequery")
assert.equals("no", value)
end)
it("does not add new parameter if to be replaced parameters does not exist on GET", function()
local r = assert( client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.formparam("toreplacequery")
end)
it("adds parameters on GET if it does not exist", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("query-added")
assert.equals("newvalue", value)
end)
it("does not add new parameter if to be added parameters already exist on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
["query-added"] = "oldvalue",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("query-added")
assert.equals("oldvalue", value)
end)
it("appends parameters on GET", function()
local r = assert(client:send {
method = "GET",
path = "/request",
query = {
q1 = "20",
},
body = {
hello = "world",
},
headers = {
host = "test3.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("p1")
assert.equals("anything:1", value[1])
assert.equals("a2", value[2])
local value = assert.request(r).has.queryparam("q1")
assert.equals("20", value)
end)
end)
describe("request rewrite using template", function()
it("template as querystring parameters on GET", function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q1 = "20",
},
body = {
hello = "world",
},
headers = {
host = "test10.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
local body = assert.response(r).has.status(200)
local json_body = cjson.decode(body)
local value = assert.request(r).has.queryparam("uri_param1")
assert.equals("foo", value)
assert.equals("/requests/user1/foo/user2/bar?q1=20&uri_param1=foo&uri_param2%5Bsome_index%5D%5B1%5D=bar",
json_body.vars.request_uri)
end)
it("should update request path using hash", function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
headers = {
host = "test11.test",
}
})
assert.response(r).has.status(200)
local body = assert(assert.response(r).has.jsonbody())
assert.equals(helpers.mock_upstream_url ..
"/requests/user2/bar/user1/foo", body.url)
end)
it("should not add querystring if hash missing", function()
local r = assert(client:send {
method = "GET",
path = "/requests/",
query = {
q1 = "20",
},
headers = {
host = "test12.test",
}
})
assert.response(r).has.status(200)
assert.request(r).has.queryparam("q1")
local value = assert.request(r).has.queryparam("uri_param1")
assert.equals("default1", value)
value = assert.request(r).has.queryparam("uri_param2")
assert.equals("default2", value)
end)
it("should fail when uri template is not a proper expression", function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
headers = {
host = "test13.test",
}
})
assert.response(r).has.status(500)
end)
it("should not fail when uri template rendered using index", function()
local r = assert(client:send {
method = "GET",
path = "/user1/foo/user2/bar",
headers = {
host = "test14.test",
}
})
assert.response(r).has.status(200)
local body = assert(assert.response(r).has.jsonbody())
assert.equals(helpers.mock_upstream_url ..
"/requests/user1/foo/user2/bar", body.url)
end)
it("validate using headers/req_querystring for rendering templates",
function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q1 = "20",
},
headers = {
host = "test15.test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.queryparam("q1")
local value = assert.request(r).has.queryparam("uri_param1")
assert.equals("foo", value)
value = assert.request(r).has.queryparam("uri_param2")
assert.equals("test15.test", value)
value = assert.request(r).has.header("x-test-header")
assert.equals("20", value)
end)
it("validate that removed header can be used as template", function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q2 = "20",
},
headers = {
host = "test16.test",
["x-remove-header"] = "its a test",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
assert.request(r).has.no.header("x-remove-header")
local value = assert.request(r).has.queryparam("q1")
assert.equals("foo", value)
value = assert.request(r).has.queryparam("q2")
assert.equals("its a test", value)
value = assert.request(r).has.header("x-test-header")
assert.equals("its a test", value)
end)
it("validate template will be rendered with old value of replaced header",
function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q2 = "20",
},
headers = {
host = "test17.test",
["x-replace-header"] = "the old value",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q1")
assert.equals("foo", value)
value = assert.request(r).has.queryparam("q2")
assert.equals("the old value", value)
value = assert.request(r).has.header("x-test-header")
assert.equals("the old value", value)
value = assert.request(r).has.header("x-replace-header")
assert.equals("the new value", value)
end)
it("validate template can be escaped",
function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q2 = "20",
},
headers = {
host = "test18.test",
["x-replace-header"] = "the old value",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("q1")
assert.equals([[$(uri_captures.user1)]], value)
value = assert.request(r).has.queryparam("q2")
assert.equals("20", value)
end)
it("rendering error (query) should fail when rendering errors out", function()
local r = assert(client:send {
method = "GET",
path = "/requests/user1/foo/user2/bar",
query = {
q2 = "20",
},
headers = {
host = "test19.test",
["x-replace-header"] = "the old value",
["Content-Type"] = "application/x-www-form-urlencoded",
}
})
assert.response(r).has.status(500)
end)
it("rendering error (header) is correctly propagated in error.log, issue #25", function()
local pattern = [[error:%[string "TMP"%]:4: attempt to call global 'foo' %(a nil value%)]]
local start_count = count_log_lines(pattern)
local r = assert(client:send {
method = "GET",
path = "/",
headers = {
host = "test24.test",
}
})
assert.response(r).has.status(500)
helpers.wait_until(function()
local count = count_log_lines(pattern)
return count - start_count >= 1 -- Kong 2.2+ == 1, Pre 2.2 == 2
end, 5)
end)
it("type function is available in template environment", function()
local r = assert(client:send {
method = "GET",
path = "/request",
headers = {
host = "test25.test",
["X-Foo"] = { "1", "2", },
}
})
assert.response(r).has.status(200)
assert.response(r).has.jsonbody()
local h_h1 = assert.request(r).has.header("X-Foo-Transformed")
assert.equals("1-first", h_h1)
end)
it("can inject a value from 'kong.ctx.shared'", function()
local r = assert(client:send {
method = "GET",
path = "/",
headers = {
host = "test21.test",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.queryparam("shared_param1")
assert.equals("1.2.3", value)
end)
it("cannot write a value in `kong.ctx.shared`", function()
local r = client:send {
method = "GET",
path = "/",
headers = {
host = "test28.test",
}
}
assert.response(r).has.status(500)
end)
end)
describe("remove then add header (regression test)", function()
it("header already exists in request", function()
local r = assert(client:send {
method = "GET",
path = "/",
headers = {
host = "test22.test",
["Authorization"] = "Basic dGVzdDp0ZXN0",
["Content-Type"] = "application/json",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.header("authorization")
assert.equals("Basic test", value)
end)
it("header does not exist in request", function()
local r = assert(client:send {
method = "GET",
path = "/",
headers = {
host = "test22.test",
["Content-Type"] = "application/json",
}
})
assert.response(r).has.status(200)
local value = assert.request(r).has.header("authorization")
assert.equals("Basic test", value)
end)
end)
describe("query parameters are not #urlencoded to upstream URL", function()
local expected = "$&+,/:;?@"
it("when plugin is not configured", function()
local r = assert(client:send {
method = "GET",
path = "/request?expected=" .. expected, -- Use inline to keep from getting URL encoded
headers = {
host = "test23.test"
}
})
local res = assert.response(r).has.status(200)
local body = cjson.decode(res)
local expected_url = helpers.mock_upstream_url .. "/?expected=" .. expected
assert.equals(expected_url, body.url)
end)
end)
end)
end