This is an automated email from the ASF dual-hosted git repository.
shreemaan-abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 34941173a fix(redis-schema): copy policy schemas instead of mutating
shared tables (#13555)
34941173a is described below
commit 34941173a5e1203b979bfe1d7d157b3260b1d57e
Author: Mohammad Izzraff Janius
<[email protected]>
AuthorDate: Mon Jun 22 15:40:46 2026 +0900
fix(redis-schema): copy policy schemas instead of mutating shared tables
(#13555)
---
apisix/plugins/limit-req.lua | 2 +-
apisix/utils/redis-schema.lua | 8 ++-
t/utils/redis-schema.t | 154 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 161 insertions(+), 3 deletions(-)
diff --git a/apisix/plugins/limit-req.lua b/apisix/plugins/limit-req.lua
index 6c5b85621..dd3c1dcf8 100644
--- a/apisix/plugins/limit-req.lua
+++ b/apisix/plugins/limit-req.lua
@@ -17,7 +17,7 @@
local limit_req_new = require("resty.limit.req").new
local core = require("apisix.core")
local redis_schema = require("apisix.utils.redis-schema")
-local policy_to_additional_properties = redis_schema.schema
+local policy_to_additional_properties =
core.table.deepcopy(redis_schema.schema)
local plugin_name = "limit-req"
local sleep = core.sleep
local apisix_plugin = require("apisix.plugin")
diff --git a/apisix/utils/redis-schema.lua b/apisix/utils/redis-schema.lua
index 0a884ca81..991919a2a 100644
--- a/apisix/utils/redis-schema.lua
+++ b/apisix/utils/redis-schema.lua
@@ -15,6 +15,8 @@
-- limitations under the License.
--
+local core = require("apisix.core")
+
local policy_to_additional_properties = {
redis = {
properties = {
@@ -86,12 +88,14 @@ local policy_to_additional_properties = {
},
}
-local limit_conn_redis_cluster_schema =
policy_to_additional_properties["redis-cluster"]
+local limit_conn_redis_cluster_schema =
+ core.table.deepcopy(policy_to_additional_properties["redis-cluster"])
limit_conn_redis_cluster_schema.properties.key_ttl = {
type = "integer", default = 3600,
}
-local limit_conn_redis_schema = policy_to_additional_properties["redis"]
+local limit_conn_redis_schema =
+ core.table.deepcopy(policy_to_additional_properties["redis"])
limit_conn_redis_schema.properties.key_ttl = {
type = "integer", default = 3600,
}
diff --git a/t/utils/redis-schema.t b/t/utils/redis-schema.t
new file mode 100644
index 000000000..493aedcb9
--- /dev/null
+++ b/t/utils/redis-schema.t
@@ -0,0 +1,154 @@
+#
+# 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';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!defined $block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: limit-count/limit-req validation must not pick up limit-conn's
key_ttl
+--- config
+ location /t {
+ content_by_lua_block {
+ -- limit-conn extends the shared redis/redis-cluster schemas with
+ -- key_ttl. Load it first so that any leak of key_ttl into the
+ -- shared tables of apisix.utils.redis-schema would be visible
+ -- to the other rate limiting plugins below.
+ require("apisix.plugins.limit-conn")
+
+ local cases = {
+ {
+ plugin = "limit-count",
+ conf = {
+ count = 2,
+ time_window = 60,
+ policy = "redis",
+ redis_host = "127.0.0.1",
+ },
+ },
+ {
+ plugin = "limit-count",
+ conf = {
+ count = 2,
+ time_window = 60,
+ policy = "redis-cluster",
+ redis_cluster_nodes = {"127.0.0.1:5000",
"127.0.0.1:5001"},
+ redis_cluster_name = "redis-cluster-1",
+ },
+ },
+ {
+ plugin = "limit-req",
+ conf = {
+ rate = 1,
+ burst = 0,
+ key = "remote_addr",
+ policy = "redis",
+ redis_host = "127.0.0.1",
+ },
+ },
+ {
+ plugin = "limit-req",
+ conf = {
+ rate = 1,
+ burst = 0,
+ key = "remote_addr",
+ policy = "redis-cluster",
+ redis_cluster_nodes = {"127.0.0.1:5000",
"127.0.0.1:5001"},
+ redis_cluster_name = "redis-cluster-1",
+ },
+ },
+ }
+
+ for _, case in ipairs(cases) do
+ local plugin = require("apisix.plugins." .. case.plugin)
+ local ok, err = plugin.check_schema(case.conf)
+ if not ok then
+ ngx.say(err)
+ elseif case.conf.key_ttl ~= nil then
+ ngx.say(case.plugin, " ", case.conf.policy,
+ " got key_ttl: ", case.conf.key_ttl)
+ else
+ ngx.say("passed")
+ end
+ end
+ ngx.say("done")
+ }
+ }
+--- response_body
+passed
+passed
+passed
+passed
+done
+
+
+
+=== TEST 2: limit-conn still defaults key_ttl to 3600 and honors an explicit
value
+--- config
+ location /t {
+ content_by_lua_block {
+ local plugin = require("apisix.plugins.limit-conn")
+
+ local conf = {
+ conn = 1,
+ burst = 0,
+ default_conn_delay = 0.1,
+ key = "remote_addr",
+ policy = "redis",
+ redis_host = "127.0.0.1",
+ }
+ local ok, err = plugin.check_schema(conf)
+ if not ok then
+ ngx.say(err)
+ return
+ end
+ ngx.say(conf.key_ttl)
+
+ conf = {
+ conn = 1,
+ burst = 0,
+ default_conn_delay = 0.1,
+ key = "remote_addr",
+ policy = "redis-cluster",
+ redis_cluster_nodes = {"127.0.0.1:5000", "127.0.0.1:5001"},
+ redis_cluster_name = "redis-cluster-1",
+ key_ttl = 60,
+ }
+ ok, err = plugin.check_schema(conf)
+ if not ok then
+ ngx.say(err)
+ return
+ end
+ ngx.say(conf.key_ttl)
+ }
+ }
+--- response_body
+3600
+60