This is an automated email from the ASF dual-hosted git repository. shreemaanabhishek pushed a commit to branch revert-10874-feat/add_redis_in_limit_req in repository https://gitbox.apache.org/repos/asf/apisix.git
commit 10e32536d89196be203f5aad5a8665933506ff65 Author: Abhishek Choudhary <[email protected]> AuthorDate: Fri Feb 23 13:54:05 2024 +0545 Revert "feat: add redis and redis-cluster in limit-req (#10874)" This reverts commit 1439b1325a0409154d1157a23cf390007b9a6023. --- apisix/cli/ngx_tpl.lua | 1 - apisix/plugins/limit-req.lua | 61 +- .../plugins/limit-req/limit-req-redis-cluster.lua | 50 -- apisix/plugins/limit-req/limit-req-redis.lua | 54 -- apisix/plugins/limit-req/util.lua | 78 --- conf/config-default.yaml | 1 - docs/en/latest/plugins/limit-req.md | 13 - docs/zh/latest/plugins/limit-req.md | 13 - t/APISIX.pm | 1 - t/plugin/limit-req-redis-cluster.t | 605 ------------------- t/plugin/limit-req-redis.t | 653 --------------------- 11 files changed, 6 insertions(+), 1524 deletions(-) diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua index d4d78a219..f1b10499c 100644 --- a/apisix/cli/ngx_tpl.lua +++ b/apisix/cli/ngx_tpl.lua @@ -293,7 +293,6 @@ http { {% end %} {% if enabled_plugins["limit-req"] then %} - lua_shared_dict plugin-limit-req-redis-cluster-slot-lock {* http.lua_shared_dict["plugin-limit-req-redis-cluster-slot-lock"] *}; lua_shared_dict plugin-limit-req {* http.lua_shared_dict["plugin-limit-req"] *}; {% end %} diff --git a/apisix/plugins/limit-req.lua b/apisix/plugins/limit-req.lua index 641eed4bc..536d06176 100644 --- a/apisix/plugins/limit-req.lua +++ b/apisix/plugins/limit-req.lua @@ -14,29 +14,16 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -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 plugin_name = "limit-req" +local limit_req_new = require("resty.limit.req").new +local core = require("apisix.core") +local plugin_name = "limit-req" local sleep = core.sleep -local redis_single_new -local redis_cluster_new -do - local redis_src = "apisix.plugins.limit-req.limit-req-redis" - redis_single_new = require(redis_src).new - - local cluster_src = "apisix.plugins.limit-req.limit-req-redis-cluster" - redis_cluster_new = require(cluster_src).new -end - local lrucache = core.lrucache.new({ type = "plugin", }) - local schema = { type = "object", properties = { @@ -47,11 +34,6 @@ local schema = { enum = {"var", "var_combination"}, default = "var", }, - policy = { - type = "string", - enum = {"redis", "redis-cluster", "local"}, - default = "local", - }, rejected_code = { type = "integer", minimum = 200, maximum = 599, default = 503 }, @@ -63,25 +45,7 @@ local schema = { }, allow_degradation = {type = "boolean", default = false} }, - required = {"rate", "burst", "key"}, - ["if"] = { - properties = { - policy = { - enum = {"redis"}, - }, - }, - }, - ["then"] = policy_to_additional_properties.redis, - ["else"] = { - ["if"] = { - properties = { - policy = { - enum = {"redis-cluster"}, - }, - }, - }, - ["then"] = policy_to_additional_properties["redis-cluster"], - } + required = {"rate", "burst", "key"} } @@ -104,21 +68,8 @@ end local function create_limit_obj(conf) - if conf.policy == "local" then - core.log.info("create new limit-req plugin instance") - return limit_req_new("plugin-limit-req", conf.rate, conf.burst) - - elseif conf.policy == "redis" then - core.log.info("create new limit-req redis plugin instance") - return redis_single_new("plugin-limit-req", conf, conf.rate, conf.burst) - - elseif conf.policy == "redis-cluster" then - core.log.info("create new limit-req redis-cluster plugin instance") - return redis_cluster_new("plugin-limit-req", conf, conf.rate, conf.burst) - - else - return nil, "policy enum not match" - end + core.log.info("create new limit-req plugin instance") + return limit_req_new("plugin-limit-req", conf.rate, conf.burst) end diff --git a/apisix/plugins/limit-req/limit-req-redis-cluster.lua b/apisix/plugins/limit-req/limit-req-redis-cluster.lua deleted file mode 100644 index 21ae635c1..000000000 --- a/apisix/plugins/limit-req/limit-req-redis-cluster.lua +++ /dev/null @@ -1,50 +0,0 @@ --- --- 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. --- -local redis_cluster = require("apisix.utils.rediscluster") -local setmetatable = setmetatable -local util = require("apisix.plugins.limit-req.util") - -local _M = {version = 0.1} - - -local mt = { - __index = _M -} - - -function _M.new(plugin_name, conf, rate, burst) - local red_cli, err = redis_cluster.new(conf, "plugin-limit-req-redis-cluster-slot-lock") - if not red_cli then - return nil, err - end - local self = { - conf = conf, - plugin_name = plugin_name, - burst = burst * 1000, - rate = rate * 1000, - red_cli = red_cli, - } - return setmetatable(self, mt) -end - - -function _M.incoming(self, key, commit) - return util.incoming(self, self.red_cli, key, commit) -end - - -return _M diff --git a/apisix/plugins/limit-req/limit-req-redis.lua b/apisix/plugins/limit-req/limit-req-redis.lua deleted file mode 100644 index e09780068..000000000 --- a/apisix/plugins/limit-req/limit-req-redis.lua +++ /dev/null @@ -1,54 +0,0 @@ --- --- 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. --- -local redis = require("apisix.utils.redis") -local setmetatable = setmetatable -local util = require("apisix.plugins.limit-req.util") - -local setmetatable = setmetatable - - -local _M = {version = 0.1} - - -local mt = { - __index = _M -} - - -function _M.new(plugin_name, conf, rate, burst) - local self = { - conf = conf, - plugin_name = plugin_name, - burst = burst * 1000, - rate = rate * 1000, - } - return setmetatable(self, mt) -end - - -function _M.incoming(self, key, commit) - local conf = self.conf - local red, err = redis.new(conf) - if not red then - return red, err - end - - return util.incoming(self, red, key, commit) -end - - -return _M diff --git a/apisix/plugins/limit-req/util.lua b/apisix/plugins/limit-req/util.lua deleted file mode 100644 index 282c04cf9..000000000 --- a/apisix/plugins/limit-req/util.lua +++ /dev/null @@ -1,78 +0,0 @@ --- --- 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. --- -local math = require "math" -local abs = math.abs -local max = math.max -local ngx_now = ngx.now -local ngx_null = ngx.null -local tonumber = tonumber - - -local _M = {version = 0.1} - - --- the "commit" argument controls whether should we record the event in shm. -function _M.incoming(self, red, key, commit) - local rate = self.rate - local now = ngx_now() * 1000 - - key = "limit_req" .. ":" .. key - local excess_key = key .. "excess" - local last_key = key .. "last" - - local excess, err = red:get(excess_key) - if err then - return nil, err - end - local last, err = red:get(last_key) - if err then - return nil, err - end - - if excess ~= ngx_null and last ~= ngx_null then - excess = tonumber(excess) - last = tonumber(last) - local elapsed = now - last - excess = max(excess - rate * abs(elapsed) / 1000 + 1000, 0) - - if excess > self.burst then - return nil, "rejected" - end - else - excess = 0 - end - - if commit then - local ok - local err - ok, err = red:set(excess_key, excess) - if not ok then - return nil, err - end - - ok, err = red:set(last_key, now) - if not ok then - return nil, err - end - end - - -- return the delay in seconds, as well as excess - return excess / rate, excess / 1000 -end - - -return _M diff --git a/conf/config-default.yaml b/conf/config-default.yaml index 245e68f2b..bb85ea845 100755 --- a/conf/config-default.yaml +++ b/conf/config-default.yaml @@ -259,7 +259,6 @@ nginx_config: # Config for render the template to generate n balancer-ewma: 10m balancer-ewma-locks: 10m balancer-ewma-last-touched-at: 10m - plugin-limit-req-redis-cluster-slot-lock: 1m plugin-limit-count-redis-cluster-slot-lock: 1m plugin-limit-conn-redis-cluster-slot-lock: 1m tracing_buffer: 10m diff --git a/docs/en/latest/plugins/limit-req.md b/docs/en/latest/plugins/limit-req.md index b9e1ce5b6..77fd1cf18 100644 --- a/docs/en/latest/plugins/limit-req.md +++ b/docs/en/latest/plugins/limit-req.md @@ -43,19 +43,6 @@ The `limit-req` Plugin limits the number of requests to your service using the [ | rejected_msg | string | False | | non-empty | Body of the response returned when the requests exceeding the threshold are rejected. | | nodelay | boolean | False | false | | If set to `true`, requests within the burst threshold would not be delayed. | | allow_degradation | boolean | False | false | | When set to `true` enables Plugin degradation when the Plugin is temporarily unavailable and allows requests to continue. | -| policy | string | False | "local" | ["local", "redis", "redis-cluster"] | Rate-limiting policies to use for retrieving and increment the limit count. When set to `local` the counters will be locally stored in memory on the node. When set to `redis` counters are stored on a Redis server and will be shared across the nodes. It is done usually for global speed limiting, and setting to `redis-cluster` uses a Redis cluster instead of a singl [...] -| redis_host | string | required when `policy` is `redis` | | | Address of the Redis server. Used when the `policy` attribute is set to `redis`. [...] -| redis_port | integer | False | 6379 | [1,...] | Port of the Redis server. Used when the `policy` attribute is set to `redis`. [...] -| redis_username | string | False | | | Username for Redis authentication if Redis ACL is used (for Redis version >= 6.0). If you use the legacy authentication method `requirepass` to configure Redis password, configure only the `redis_password`. Used when the `policy` is set to `redis`. [...] -| redis_password | string | False | | | Password for Redis authentication. Used when the `policy` is set to `redis` or `redis-cluster`. [...] -| redis_ssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis instance. Used when the `policy` attribute is set to `redis`. [...] -| redis_ssl_verify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis`. See [tcpsock:sslhandshake](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake). [...] -| redis_database | integer | False | 0 | redis_database >= 0 | Selected database of the Redis server (for single instance operation or when using Redis cloud with a single entrypoint). Used when the `policy` attribute is set to `redis`. [...] -| redis_timeout | integer | False | 1000 | [1,...] | Timeout in milliseconds for any command submitted to the Redis server. Used when the `policy` attribute is set to `redis` or `redis-cluster`. [...] -| redis_cluster_nodes | array | required when `policy` is `redis-cluster` | | | Addresses of Redis cluster nodes. Used when the `policy` attribute is set to `redis-cluster`. [...] -| redis_cluster_name | string | required when `policy` is `redis-cluster` | | | Name of the Redis cluster service nodes. Used when the `policy` attribute is set to `redis-cluster`. [...] -| redis_cluster_ssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis-cluster. Used when the `policy` attribute is set to `redis-cluster`. | -| redis_cluster_ssl_verify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis-cluster`. | ## Enable Plugin diff --git a/docs/zh/latest/plugins/limit-req.md b/docs/zh/latest/plugins/limit-req.md index dd6461d0e..6f844611d 100644 --- a/docs/zh/latest/plugins/limit-req.md +++ b/docs/zh/latest/plugins/limit-req.md @@ -43,19 +43,6 @@ description: limit-req 插件使用漏桶算法限制对用户服务的请求速 | rejected_msg | string | 否 | | 非空 | 当超过阈值的请求被拒绝时,返回的响应体。| | nodelay | boolean | 否 | false | | 当设置为 `true` 时,请求速率超过 `rate` 但没有超过(`rate` + `burst`)的请求不会加上延迟;当设置为 `false`,则会加上延迟。 | | allow_degradation | boolean | 否 | false | | 当设置为 `true` 时,如果限速插件功能临时不可用,将会自动允许请求继续。| -| policy | string | 否 | "local" | ["local", "redis", "redis-cluster"] | 用于检索和增加限制计数的策略。当设置为 `local` 时,计数器被以内存方式保存在节点本地;当设置为 `redis` 时,计数器保存在 Redis 服务节点上,从而可以跨节点共享结果,通常用它来完成全局限速;当设置为 `redis-cluster` 时,使用 Redis 集群而不是单个实例。| -| redis_host | string | 否 | | | 当使用 `redis` 限速策略时,Redis 服务节点的地址。**当 `policy` 属性设置为 `redis` 时必选。** | -| redis_port | integer | 否 | 6379 | [1,...] | 当使用 `redis` 限速策略时,Redis 服务节点的端口。 | -| redis_username | string | 否 | | | 若使用 Redis ACL 进行身份验证(适用于 Redis 版本 >=6.0),则需要提供 Redis 用户名。若使用 Redis legacy 方式 `requirepass` 进行身份验证,则只需将密码配置在 `redis_password`。当 `policy` 设置为 `redis` 时使用。 | -| redis_password | string | 否 | | | 当使用 `redis` 或者 `redis-cluster` 限速策略时,Redis 服务节点的密码。 | -| redis_ssl | boolean | 否 | false | | 当使用 `redis` 限速策略时,如果设置为 true,则使用 SSL 连接到 `redis` | -| redis_ssl_verify | boolean | 否 | false | | 当使用 `redis` 限速策略时,如果设置为 true,则验证服务器 SSL 证书的有效性,具体请参考 [tcpsock:sslhandshake](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake). | -| redis_database | integer | 否 | 0 | redis_database >= 0 | 当使用 `redis` 限速策略时,Redis 服务节点中使用的 `database`,并且只针对非 Redis 集群模式(单实例模式或者提供单入口的 Redis 公有云服务)生效。 | -| redis_timeout | integer | 否 | 1000 | [1,...] | 当 `policy` 设置为 `redis` 或 `redis-cluster` 时,Redis 服务节点的超时时间(以毫秒为单位)。 | -| redis_cluster_nodes | array | 否 | | | 当使用 `redis-cluster` 限速策略时,Redis 集群服务节点的地址列表(至少需要两个地址)。**当 `policy` 属性设置为 `redis-cluster` 时必选。** | -| redis_cluster_name | string | 否 | | | 当使用 `redis-cluster` 限速策略时,Redis 集群服务节点的名称。**当 `policy` 设置为 `redis-cluster` 时必选。** | -| redis_cluster_ssl | boolean | 否 | false | | 当使用 `redis-cluster` 限速策略时,如果设置为 true,则使用 SSL 连接到 `redis-cluster` | -| redis_cluster_ssl_verify | boolean | 否 | false | | 当使用 `redis-cluster` 限速策略时,如果设置为 true,则验证服务器 SSL 证书的有效性 | ## 启用插件 diff --git a/t/APISIX.pm b/t/APISIX.pm index 9a98176c3..73de93f34 100644 --- a/t/APISIX.pm +++ b/t/APISIX.pm @@ -559,7 +559,6 @@ _EOC_ lua_shared_dict balancer-ewma 1m; lua_shared_dict balancer-ewma-locks 1m; lua_shared_dict balancer-ewma-last-touched-at 1m; - lua_shared_dict plugin-limit-req-redis-cluster-slot-lock 1m; lua_shared_dict plugin-limit-count-redis-cluster-slot-lock 1m; lua_shared_dict plugin-limit-conn-redis-cluster-slot-lock 1m; lua_shared_dict tracing_buffer 10m; # plugin skywalking diff --git a/t/plugin/limit-req-redis-cluster.t b/t/plugin/limit-req-redis-cluster.t deleted file mode 100644 index 4c36c2200..000000000 --- a/t/plugin/limit-req-redis-cluster.t +++ /dev/null @@ -1,605 +0,0 @@ -# -# 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. -# -BEGIN { - if ($ENV{TEST_NGINX_CHECK_LEAK}) { - $SkipReason = "unavailable for the hup tests"; - - } else { - $ENV{TEST_NGINX_USE_HUP} = 1; - undef $ENV{TEST_NGINX_USE_STAP}; - } -} - -use t::APISIX 'no_plan'; - -repeat_each(1); -no_long_string(); -no_shuffle(); -no_root_location(); - -run_tests; - -__DATA__ - -=== TEST 1: sanity ---- config - location /t { - content_by_lua_block { - local plugin = require("apisix.plugins.limit-req") - local ok, err = plugin.check_schema({ - rate = 1, - burst = 0, - rejected_code = 503, - key = 'remote_addr', - policy = 'redis', - redis_host = '127.0.0.1' - }) - if not ok then - ngx.say(err) - end - - ngx.say("done") - } - } ---- request -GET /t ---- response_body -done - - - -=== TEST 2: add plugin with redis cluster with ssl ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:7000", - "127.0.0.1:7001", - "127.0.0.1:7002" - ], - "redis_cluster_ssl": true, - "redis_cluster_ssl_verify": false - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 3: not exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200] - - - -=== TEST 4: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200, 200, 200, 200, 200, 200, 503] - - - -=== TEST 5: update plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 6: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 503, 503, 503] - - - -=== TEST 7: wrong type ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": -1, - "burst": 0.1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.print(body) - } - } ---- request -GET /t ---- error_code: 400 ---- response_body -{"error_msg":"failed to check the configuration of plugin limit-req err: property \"rate\" validation failed: expected -1 to be greater than 0"} - - - -=== TEST 8: disable plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 9: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200] - - - -=== TEST 10: set route (key: server_addr) ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 2, - "rejected_code": 503, - "key": "server_addr", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 11: default rejected_code ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 2, - "key": "remote_addr", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 12: consumer binds the limit-req plugin and `key` is `consumer_name` ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers', - ngx.HTTP_PUT, - [[{ - "username": "new_consumer", - "plugins": { - "key-auth": { - "key": "auth-jack" - }, - "limit-req": { - "rate": 3, - "burst": 2, - "rejected_code": 403, - "key": "consumer_name", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - } - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 13: route add "key-auth" plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "key-auth": {} - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 14: not exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello"] ---- more_headers -apikey: auth-jack ---- error_code eval -[200, 200, 200] - - - -=== TEST 15: update the limit-req plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers', - ngx.HTTP_PUT, - [[{ - "username": "new_consumer", - "plugins": { - "key-auth": { - "key": "auth-jack" - }, - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 403, - "key": "consumer_name", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - } - }]] - ) - - ngx.status = code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 16: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- more_headers -apikey: auth-jack ---- error_code eval -[403, 403, 403, 403] - - - -=== TEST 17: key is consumer_name ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 2, - "burst": 1, - "key": "consumer_name", - "policy": "redis-cluster", - "redis_cluster_name": "test", - "redis_cluster_nodes": [ - "127.0.0.1:5000", - "127.0.0.1:5002" - ] - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 18: get "consumer_name" is empty ---- request -GET /hello ---- response_body -hello world ---- error_log -The value of the configured key is empty, use client IP instead - - - -=== TEST 19: delete consumer ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers/new_consumer', ngx.HTTP_DELETE) - - ngx.status = code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 20: delete route ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', ngx.HTTP_DELETE) - - ngx.status =code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 21: check_schema failed (the `rate` attribute is equal to 0) ---- config - location /t { - content_by_lua_block { - local plugin = require("apisix.plugins.limit-req") - local ok, err = plugin.check_schema({rate = 0, burst = 0, rejected_code = 503, key = 'remote_addr'}) - if not ok then - ngx.say(err) - end - - ngx.say("done") - } - } ---- request -GET /t ---- response_body eval -qr/property \"rate\" validation failed: expected 0 to be greater than 0/ diff --git a/t/plugin/limit-req-redis.t b/t/plugin/limit-req-redis.t deleted file mode 100644 index 84664b7a2..000000000 --- a/t/plugin/limit-req-redis.t +++ /dev/null @@ -1,653 +0,0 @@ -# -# 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. -# -BEGIN { - if ($ENV{TEST_NGINX_CHECK_LEAK}) { - $SkipReason = "unavailable for the hup tests"; - - } else { - $ENV{TEST_NGINX_USE_HUP} = 1; - undef $ENV{TEST_NGINX_USE_STAP}; - } -} - -use t::APISIX 'no_plan'; - -repeat_each(1); -no_long_string(); -no_shuffle(); -no_root_location(); - - -add_block_preprocessor(sub { - my ($block) = @_; - my $port = $ENV{TEST_NGINX_SERVER_PORT}; - - my $config = $block->config // <<_EOC_; - location /access_root_dir { - content_by_lua_block { - local httpc = require "resty.http" - local hc = httpc:new() - - local res, err = hc:request_uri('http://127.0.0.1:$port/limit_conn') - if res then - ngx.exit(res.status) - end - } - } -_EOC_ - - $block->set_value("config", $config); -}); - - -run_tests; - -__DATA__ - -=== TEST 1: sanity ---- config - location /t { - content_by_lua_block { - local plugin = require("apisix.plugins.limit-req") - local ok, err = plugin.check_schema({ - rate = 1, - burst = 0, - rejected_code = 503, - key = 'remote_addr', - policy = 'redis', - redis_host = '127.0.0.1' - }) - if not ok then - ngx.say(err) - end - - ngx.say("done") - } - } ---- request -GET /t ---- response_body -done - - - -=== TEST 2: add plugin with redis ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis", - "redis_host": "127.0.0.1" - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 3: not exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200] - - - -=== TEST 4: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200, 200, 200, 200, 200, 200, 503] - - - -=== TEST 5: update plugin with username password ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379, - "redis_username": "alice", - "redis_password": "somepassword" - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 6: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 503, 503, 503] - - - -=== TEST 7: update plugin with username, wrong password ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379, - "redis_username": "alice", - "redis_password": "someerrorpassword" - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 8: catch wrong pass ---- request -GET /hello ---- error_code: 500 ---- error_log -failed to limit req: WRONGPASS invalid username-password pair or user is disabled. - - - -=== TEST 9: invalid route: missing redis_host ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 503, - "key": "remote_addr", - "policy": "redis" - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.print(body) - } - } ---- request -GET /t ---- error_code: 400 ---- response_body -{"error_msg":"failed to check the configuration of plugin limit-req err: then clause did not match"} - - - -=== TEST 10: disable plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 11: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- error_code eval -[200, 200, 200, 200] - - - -=== TEST 12: set route (key: server_addr) ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 2, - "rejected_code": 503, - "key": "server_addr", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379 - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 13: default rejected_code ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 4, - "burst": 2, - "key": "remote_addr", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379 - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 14: consumer binds the limit-req plugin and `key` is `consumer_name` ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers', - ngx.HTTP_PUT, - [[{ - "username": "new_consumer", - "plugins": { - "key-auth": { - "key": "auth-jack" - }, - "limit-req": { - "rate": 3, - "burst": 2, - "rejected_code": 403, - "key": "consumer_name", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379 - } - } - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 15: route add "key-auth" plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "key-auth": {} - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 16: not exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello"] ---- more_headers -apikey: auth-jack ---- error_code eval -[200, 200, 200] - - - -=== TEST 17: update the limit-req plugin ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers', - ngx.HTTP_PUT, - [[{ - "username": "new_consumer", - "plugins": { - "key-auth": { - "key": "auth-jack" - }, - "limit-req": { - "rate": 0.1, - "burst": 0.1, - "rejected_code": 403, - "key": "consumer_name", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379 - } - } - }]] - ) - - ngx.status = code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 18: exceeding the burst ---- pipelined_requests eval -["GET /hello", "GET /hello", "GET /hello", "GET /hello"] ---- more_headers -apikey: auth-jack ---- error_code eval -[403, 403, 403, 403] - - - -=== TEST 19: key is consumer_name ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "plugins": { - "limit-req": { - "rate": 2, - "burst": 1, - "key": "consumer_name", - "policy": "redis", - "redis_host": "127.0.0.1", - "redis_port": 6379 - } - }, - "upstream": { - "nodes": { - "127.0.0.1:1980": 1 - }, - "type": "roundrobin" - }, - "desc": "upstream_node", - "uri": "/hello" - }]] - ) - - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 20: get "consumer_name" is empty ---- request -GET /hello ---- response_body -hello world ---- error_log -The value of the configured key is empty, use client IP instead - - - -=== TEST 21: delete consumer ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers/new_consumer', ngx.HTTP_DELETE) - - ngx.status = code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 22: delete route ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', ngx.HTTP_DELETE) - - ngx.status =code - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - - -=== TEST 23: check_schema failed (the `rate` attribute is equal to 0) ---- config - location /t { - content_by_lua_block { - local plugin = require("apisix.plugins.limit-req") - local ok, err = plugin.check_schema({rate = 0, burst = 0, rejected_code = 503, key = 'remote_addr'}) - if not ok then - ngx.say(err) - end - - ngx.say("done") - } - } ---- request -GET /t ---- response_body eval -qr/property \"rate\" validation failed: expected 0 to be greater than 0/
