diff --git a/apisix/plugins/limit-conn/init.lua b/apisix/plugins/limit-conn/init.lua index 0d45bd29074d..b0cbafe815b4 100644 --- a/apisix/plugins/limit-conn/init.lua +++ b/apisix/plugins/limit-conn/init.lua @@ -191,6 +191,11 @@ local function run_limit_conn(conf, rule, ctx) end key = key .. ctx.conf_type .. ctx.conf_version + if conf._vid then + -- conf has _vid means it's from workflow plugin, add _vid to the key + -- so that the counter is unique per action. + key = key .. ':' .. conf._vid + end core.log.info("limit key: ", key) local delay, err = lim:incoming(key, true) diff --git a/t/plugin/workflow3.t b/t/plugin/workflow3.t index 70a0aca712c2..e993381af02a 100644 --- a/t/plugin/workflow3.t +++ b/t/plugin/workflow3.t @@ -59,6 +59,36 @@ add_block_preprocessor(sub { end } } + + + location /access_root_dir2 { + 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_conn2') + if res then + ngx.exit(res.status) + end + } + } + + location /test_concurrency2 { + content_by_lua_block { + local reqs = {} + for i = 1, 10 do + if i % 2 == 0 then + reqs[i] = { "/access_root_dir" } + else + reqs[i] = { "/access_root_dir2" } + end + end + local resps = { ngx.location.capture_multi(reqs) } + for i, resp in ipairs(resps) do + ngx.say(resp.status) + end + } + } _EOC_ $block->set_value("config", $config); @@ -145,7 +175,97 @@ GET /test_concurrency -=== TEST 3: set up workflow with limit-conn in global rule, and a route with cors +=== TEST 3: two limit-conn configurations +--- config + location /t { + content_by_lua_block { + local json = require("toolkit.json") + local t = require("lib.test_admin").test + local data = { + uri = "/*", + plugins = { + workflow = { + rules = { + { + case = { + {"uri", "==", "/limit_conn"} + }, + actions = { + { + "limit-conn", + { + conn = 2, + burst = 1, + default_conn_delay = 0.1, + rejected_code = 503, + key = "remote_addr" + } + } + } + }, + { + case = { + {"uri", "==", "/limit_conn2"} + }, + actions = { + { + "limit-conn", + { + conn = 2, + burst = 1, + default_conn_delay = 0.1, + rejected_code = 503, + key = "remote_addr" + } + } + } + } + } + } + }, + upstream = { + nodes = { + ["127.0.0.1:1980"] = 1 + }, + type = "roundrobin" + } + } + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + json.encode(data) + ) + + if code >= 300 then + ngx.status = code + end + + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 4: exceeding the burst +--- request +GET /test_concurrency2 +--- timeout: 10s +--- response_body +404 +200 +404 +200 +404 +200 +503 +503 +503 +503 + + + +=== TEST 5: set up workflow with limit-conn in global rule, and a route with cors --- config location /t { content_by_lua_block { @@ -213,7 +333,7 @@ passed -=== TEST 4: OPTIONS preflight finished by cors in rewrite phase, workflow log phase should not fail +=== TEST 6: OPTIONS preflight finished by cors in rewrite phase, workflow log phase should not fail --- request OPTIONS /hello --- more_headers @@ -225,7 +345,7 @@ _workflow_cache -=== TEST 5: clean up +=== TEST 7: clean up --- config location /t { content_by_lua_block {