#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use t::APISIX 'no_plan';
no_long_string();
no_shuffle();
no_root_location();
add_block_preprocessor(sub {
my ($block) = @_;
if (!$block->request) {
$block->set_value("request", "GET /t");
}
});
run_tests;
__DATA__
=== TEST 1: simulate simple SOAP proxy
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local xml2lua = require("xml2lua")
local xmlhandler = require("xmlhandler.tree")
local handler = xmlhandler:new()
local parser = xml2lua.parser(handler)
parser:parse(body)
ngx.print(string.format([[
%s
46704314
Madrid
EUR
]], handler.root["soap-env:Envelope"]["soap-env:Body"]["ns0:getCountryRequest"]["ns0:name"]))
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local req_template = ngx.encode_base64[[
{{_escape_xml(name)}}
]]
local rsp_template = ngx.encode_base64[[
{% if Envelope.Body.Fault == nil then %}
{
"status":"{{_ctx.var.status}}",
"currency":"{{Envelope.Body.getCountryResponse.country.currency}}",
"population":{{Envelope.Body.getCountryResponse.country.population}},
"capital":"{{Envelope.Body.getCountryResponse.country.capital}}",
"name":"{{Envelope.Body.getCountryResponse.country.name}}"
}
{% else %}
{
"message":{*_escape_json(Envelope.Body.Fault.faultstring[1])*},
"code":"{{Envelope.Body.Fault.faultcode}}"
{% if Envelope.Body.Fault.faultactor ~= nil then %}
, "actor":"{{Envelope.Body.Fault.faultactor}}"
{% end %}
}
{% end %}
]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/ws",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template": "%s"
},
"response": {
"input_format": "xml",
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template, rsp_template, ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/ws"
local body = [[{"name": "Spain"}]]
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/json"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
local data1 = core.json.decode(res.body)
local data2 = core.json.decode[[{"status":"200","currency":"EUR","population":46704314,"capital":"Madrid","name":"Spain"}]]
assert(core.json.stably_encode(data1) == core.json.stably_encode(data2))
}
}
=== TEST 2: test JSON-to-JSON
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
assert(data.foo == "hello world" and data.bar == 30)
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foo":"{{name .. " world"}}","bar":{{age+10}}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local body = [[{"name":"hello","age":20}]]
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/json"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 3: specify wrong input_format
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foo":"{{name .. " world"}}","bar":{{age+10}}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"input_format": "xml",
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local body = [[{"name":"hello","age":20}]]
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/json"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 400)
}
}
--- error_log
Error Parsing XML
=== TEST 4: invalid reference in template
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foo":"{{name() .. " world"}}","bar":{{age+10}}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local body = [[{"name":"hello","age":20}]]
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/json"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 503)
}
}
--- grep_error_log eval
qr/transform\(\): request template rendering:.*/
--- grep_error_log_out eval
qr/attempt to call global 'name' \(a string value\)/
=== TEST 5: generate request body from scratch
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
assert(data.foo == "hello world")
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{
"foo":"{{_ctx.var.arg_name .. " world"}}"
}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo",
"method": "POST"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar?name=hello"
local opt = {method = "GET"}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 6: html escape in template
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
if (data == nil) or (data.agent:find("ngx_lua/", 0, true) == nil) then
return ngx.exit(400)
end
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
-- html escape would escape '/' to '/' in string, which may be unexpected.
-- 'lua-resty-http/0.16.1 (Lua) ngx_lua/10021'
-- would be escaped into
-- 'lua-resty-http/0.16.1 (Lua) ngx_lua/10021'
local req_template = [[{
"agent":"{{_ctx.var.http_user_agent}}"
}]]
local admin_body = [[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo",
"method": "POST"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format(admin_body, req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar?name=hello"
local opt = {method = "GET"}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 400)
-- disable html escape, now it's ok
local req_template = [[{"agent":"{*_ctx.var.http_user_agent*}"}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format(admin_body, req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 7: parse body in yaml format
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
if data == nil or data.foobar ~= "hello world" then
return ngx.exit(400)
end
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[
{%
local yaml = require("lyaml")
local body = yaml.load(_body)
%}
{"foobar":"{{body.foobar.foo .. " " .. body.foobar.bar}}"}
]]
local admin_body = [[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo",
"method": "POST"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format(admin_body, req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local body = [[
foobar:
foo: hello
bar: world
]]
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local opt = {method = "POST", body = body}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 8: test _escape_json
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
if data == nil or data.foobar ~= [[hello "world"]] then
return ngx.exit(400)
end
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foobar":{*_escape_json(name)*}}]]
local admin_body = [[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo",
"method": "POST"
},
"body-transformer": {
"request": {
"input_format": "json",
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format(admin_body, req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local body = [[{"name":"hello \"world\""}]]
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local opt = {method = "POST", body = body}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 9: test _escape_xml
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local xml2lua = require("xml2lua")
local xmlhandler = require("xmlhandler.tree")
local handler = xmlhandler:new()
local parser = xml2lua.parser(handler)
parser:parse(body)
assert(handler.root.foobar == "")
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{*_escape_xml(name)*}]]
local admin_body = [[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo",
"method": "POST"
},
"body-transformer": {
"request": {
"input_format": "json",
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format(admin_body, req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local body = [[{"name":""}]]
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local opt = {method = "POST", body = body}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 10: cooperation of proxy-cache plugin
--- http_config
lua_shared_dict memory_cache 50m;
--- config
location /demo {
content_by_lua_block {
ngx.say([[
hello
]])
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local req_template = ngx.encode_base64[[
{{_escape_xml(country)}}
]]
local rsp_template = ngx.encode_base64[[
{"result": {*_escape_json(Envelope.Body.CapitalCityResponse.CapitalCityResult)*}}
]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/capital",
"plugins": {
"proxy-rewrite": {
"set": {
"Accept-Encoding": "identity",
"Content-Type": "text/xml"
},
"uri": "/demo"
},
"proxy-cache":{
"cache_strategy": "memory",
"cache_bypass": ["$arg_bypass"],
"cache_http_status": [200],
"cache_key": ["$uri", "-cache-id"],
"cache_method": ["POST"],
"hide_cache_headers": true,
"no_cache": ["$arg_test"],
"cache_zone": "memory_cache"
},
"body-transformer": {
"request": {
"input_format": "json",
"template": "%s"
},
"response": {
"input_format": "xml",
"template": "%s"
}
},
"response-rewrite":{
"headers": {
"set": {
"Content-Type": "application/json"
}
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template, rsp_template, ngx.var.server_port)
)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/capital"
local body = [[{"country": "foo"}]]
local opt = {method = "POST", body = body}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
local data = core.json.decode(res.body)
assert(data.result == "hello")
assert(res.headers["Apisix-Cache-Status"] == "MISS")
local res2 = httpc:request_uri(uri, opt)
assert(res2.status == 200)
local data2 = core.json.decode(res2.body)
assert(data2.result == "hello")
assert(res2.headers["Apisix-Cache-Status"] == "HIT")
}
}
=== TEST 11: return raw body with _body anytime
--- http_config
--- config
location /demo {
content_by_lua_block {
ngx.header.content_type = "application/json"
ngx.print('{"result": "hello world"}')
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local rsp_template = ngx.encode_base64[[
{"raw_body": {*_escape_json(_body)*}, "result": {*_escape_json(result)*}}
]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/capital",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"response": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], rsp_template, ngx.var.server_port)
)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/capital"
local opt = {method = "GET", headers = {["Content-Type"] = "application/json"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
local data = core.json.decode(res.body)
assert(data.result == "hello world")
assert(data.raw_body == '{"result": "hello world"}')
}
}
=== TEST 12: empty xml value should be rendered as empty string
--- config
location /demo {
content_by_lua_block {
ngx.print([[
33333333333
33333333333
]])
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local rsp_template = ngx.encode_base64[[
{ "KOVKood":"{{Envelope.Body.RR58isikEpiletResponse.response.KOVKood}}" }
]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/ws",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"response": {
"input_format": "xml",
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], rsp_template, ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/ws"
local opt = {method = "GET"}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
local data1 = core.json.decode(res.body)
local data2 = core.json.decode[[{"KOVKood":""}]]
assert(core.json.stably_encode(data1) == core.json.stably_encode(data2))
}
}
=== TEST 13: test x-www-form-urlencoded to JSON
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
assert(data.foo == "hello world" and data.bar == 30)
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foo":"{{name .. " world"}}","bar":{{age+10}}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local data = {name = "hello", age = 20}
local body = ngx.encode_args(data)
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/x-www-form-urlencoded"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 14: test get request to JSON
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = core.json.decode(body)
assert(data.foo == "hello world" and data.bar == 30)
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = [[{"foo":"{{name .. " world"}}","bar":{{age+10}}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar" .. "?name=hello&age=20"
local opt = {method = "GET"}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 15: test input is in base64-encoded urlencoded format
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
local data = ngx.decode_args(body)
assert(data.foo == "hello world" and data.bar == "30")
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local req_template = ngx.encode_base64[[foo={{name .. " world"}}&bar={{age+10}}]]
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"template_is_base64": true,
"template": "%s"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], req_template:gsub('"', '\\"'), ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local core = require("apisix.core")
local http = require("resty.http")
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/foobar"
local data = {name = "hello", age = 20}
local body = ngx.encode_args(data)
local opt = {method = "POST", body = body, headers = {["Content-Type"] = "application/x-www-form-urlencoded"}}
local httpc = http.new()
local res = httpc:request_uri(uri, opt)
assert(res.status == 200)
}
}
=== TEST 16: test for missing Content-Type and skip body parsing
--- config
location /demo {
content_by_lua_block {
local core = require("apisix.core")
local body = core.request.get_body()
assert(body == "{\"message\": \"actually json\"}")
}
}
location /t {
content_by_lua_block {
local t = require("lib.test_admin")
local core = require("apisix.core")
local code, body = t.test('/apisix/admin/routes/1',
ngx.HTTP_PUT,
string.format([[{
"uri": "/foobar",
"plugins": {
"proxy-rewrite": {
"uri": "/demo"
},
"body-transformer": {
"request": {
"input_format": "plain",
"template": "{\"message\": \"{* string.gsub(_body, 'not ', '') *}\"}"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:%d": 1
}
}
}]], ngx.var.server_port)
)
if code >= 300 then
ngx.status = code
return
end
ngx.sleep(0.5)
local http = require("resty.http")
local httpc = http.new()
local res, err = httpc:request_uri("http://127.0.0.1:" .. ngx.var.server_port .. "/foobar", {
method = "POST",
body = "not actually json",
})
assert(res.status == 200)
}
}
--- no_error_log
no input format to parse