diff --git a/apisix/core/config_util.lua b/apisix/core/config_util.lua index 7313e0116ad2..96217293b041 100644 --- a/apisix/core/config_util.lua +++ b/apisix/core/config_util.lua @@ -58,6 +58,10 @@ end -- or cancelled. Note that Nginx worker exit doesn't trigger the clean handler. -- Return an index so that we can cancel it later. function _M.add_clean_handler(item, func) + if not item.clean_handlers then + return nil, "clean handlers for the item are nil" + end + if not item.clean_handlers._id then item.clean_handlers._id = 1 end diff --git a/apisix/plugins/body-transformer.lua b/apisix/plugins/body-transformer.lua index 571bba1f9784..7e1242e52e79 100644 --- a/apisix/plugins/body-transformer.lua +++ b/apisix/plugins/body-transformer.lua @@ -30,6 +30,7 @@ local pcall = pcall local pairs = pairs local next = next local multipart = require("multipart") +local setmetatable = setmetatable local transform_schema = { type = "object", @@ -169,11 +170,14 @@ local function transform(conf, body, typ, ctx, request_method) return nil, 503, err end - out._ctx = ctx - out._body = body - out._escape_xml = escape_xml - out._escape_json = escape_json - out._multipart = _multipart + setmetatable(out, {__index = { + _ctx = ctx, + _body = body, + _escape_xml = escape_xml, + _escape_json = escape_json, + _multipart = _multipart + }}) + local ok, render_out = pcall(render, out) if not ok then local err = str_format("%s template rendering: %s", typ, render_out) diff --git a/apisix/upstream.lua b/apisix/upstream.lua index eb5e467daaca..3853623e5615 100644 --- a/apisix/upstream.lua +++ b/apisix/upstream.lua @@ -155,10 +155,20 @@ local function create_checker(upstream) end end + local check_idx, err = core.config_util.add_clean_handler(healthcheck_parent, release_checker) + if not check_idx then + upstream.is_creating_checker = nil + checker:clear() + checker:stop() + core.log.error("failed to add clean handler, err:", + err, " healthcheck parent:", core.json.delay_encode(healthcheck_parent, true)) + + return nil + end + healthcheck_parent.checker = checker healthcheck_parent.checker_upstream = upstream - healthcheck_parent.checker_idx = - core.config_util.add_clean_handler(healthcheck_parent, release_checker) + healthcheck_parent.checker_idx = check_idx upstream.is_creating_checker = nil diff --git a/t/plugin/body-transformer2.t b/t/plugin/body-transformer2.t new file mode 100644 index 000000000000..748b1fd1fbb4 --- /dev/null +++ b/t/plugin/body-transformer2.t @@ -0,0 +1,89 @@ +# +# 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: body transformer with decoded body (keyword: context) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin") + local core = require("apisix.core") + + local req_template = ngx.encode_base64[[ + {% + local core = require 'apisix.core' + local cjson = require 'cjson' + context.name = "bar" + context.address = nil + context.age = context.age + 1 + local body = core.json.encode(context) + %}{* body *} + ]] + + local code, body = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + string.format([[{ + "uri": "/echo", + "plugins": { + "body-transformer": { + "request": { + "template": "%s" + } + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } + }]], req_template) + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 2: verify the transformed body +--- request +POST /echo +{"name": "foo", "address":"LA", "age": 18} +-- response_body +{"name": "bar", "age": 19}