From a58d36efa48d266e45e039b9bde4ff4ec2753d04 Mon Sep 17 00:00:00 2001 From: monkeyDluffy6017 Date: Thu, 23 Nov 2023 20:18:55 +0800 Subject: [PATCH] fix(limit-count): all consumers should share the same counter --- apisix/plugin.lua | 6 ++ apisix/plugins/limit-count/init.lua | 4 +- t/plugin/limit-count3.t | 126 ++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) diff --git a/apisix/plugin.lua b/apisix/plugin.lua index fa1d814b290a..b5da3f2163d5 100644 --- a/apisix/plugin.lua +++ b/apisix/plugin.lua @@ -738,6 +738,12 @@ function _M.merge_consumer_route(route_conf, consumer_conf, consumer_group_conf, local new_conf = merged_route(flag, api_ctx.conf_version, merge_consumer_route, route_conf, consumer_conf, consumer_group_conf) + -- some plugins like limit-count don't care if consumer changes + -- all consumers should share the same counter + api_ctx.conf_type_without_consumer = api_ctx.conf_type + api_ctx.conf_version_without_consumer = api_ctx.conf_version + api_ctx.conf_id_without_consumer = api_ctx.conf_id + api_ctx.conf_type = api_ctx.conf_type .. "&consumer" api_ctx.conf_version = api_ctx.conf_version .. "&" .. api_ctx.consumer_ver diff --git a/apisix/plugins/limit-count/init.lua b/apisix/plugins/limit-count/init.lua index 069ab6739ee5..a280592b90f5 100644 --- a/apisix/plugins/limit-count/init.lua +++ b/apisix/plugins/limit-count/init.lua @@ -230,7 +230,9 @@ local function gen_limit_key(conf, ctx, key) -- Here we use plugin-level conf version to prevent the counter from being resetting -- because of the change elsewhere. -- A route which reuses a previous route's ID will inherits its counter. - local new_key = ctx.conf_type .. ctx.conf_id .. ':' .. apisix_plugin.conf_version(conf) + local conf_type = ctx.conf_type_without_consumer or ctx.conf_type + local conf_id = ctx.conf_id_without_consumer or ctx.conf_id + local new_key = conf_type .. conf_id .. ':' .. apisix_plugin.conf_version(conf) .. ':' .. key if conf._vid then -- conf has _vid means it's from workflow plugin, add _vid to the key diff --git a/t/plugin/limit-count3.t b/t/plugin/limit-count3.t index 0c5490616ad2..1f5476fc47ad 100644 --- a/t/plugin/limit-count3.t +++ b/t/plugin/limit-count3.t @@ -285,3 +285,129 @@ passed } --- response_body [200,200] + + + +=== TEST 9: add consumer jack1 +--- 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": "jack1", + "plugins": { + "basic-auth": { + "username": "jack2019", + "password": "123456" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 10: add consumer jack2 +--- 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": "jack2", + "plugins": { + "basic-auth": { + "username": "jack2020", + "password": "123456" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 11: set route with consumers +--- 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, + [[{ + "uri": "/hello", + "plugins": { + "basic-auth": {}, + "consumer-restriction":{ + "whitelist":[ + "jack1", + "jack2" + ], + "rejected_code": 403, + "type":"consumer_name" + }, + "limit-count": { + "count": 1, + "time_window": 60, + "rejected_code": 429 + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 12: hit jack1, pass +--- request +GET /hello +--- more_headers +Authorization: Basic amFjazIwMTk6MTIzNDU2 +--- response_body +hello world + + + +=== TEST 13: hit jack2, reject, the two consumers share the same counter +--- request +GET /hello +--- more_headers +Authorization: Basic amFjazIwMjA6MTIzNDU2 +--- error_code: 429