This is an automated email from the ASF dual-hosted git repository.
nic-6443 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 51fad8a89 fix(traffic-label): cache the compiled match expressions
outside the plugin config (#13901)
51fad8a89 is described below
commit 51fad8a897d538a68b8283d1e9a428363889df0a
Author: Nic <[email protected]>
AuthorDate: Tue Sep 1 14:31:01 2026 +0800
fix(traffic-label): cache the compiled match expressions outside the plugin
config (#13901)
---
apisix/plugins/traffic-label.lua | 25 +++++++++-------
t/plugin/traffic-label2.t | 63 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 10 deletions(-)
diff --git a/apisix/plugins/traffic-label.lua b/apisix/plugins/traffic-label.lua
index 65eb71e53..e57169b38 100644
--- a/apisix/plugins/traffic-label.lua
+++ b/apisix/plugins/traffic-label.lua
@@ -21,6 +21,7 @@ local expr = require("resty.expr.v1")
local roundrobin = require("resty.roundrobin")
local ipairs = ipairs
local pairs = pairs
+local setmetatable = setmetatable
local lrucache = core.lrucache.new({
ttl = 0, count = 512
@@ -192,19 +193,23 @@ end
function _M.access(conf, ctx)
local match_result
- if not conf.rules_arr then
- conf.rules_arr = {}
-
- for _, rule in ipairs(conf.rules) do
+ for _, rule in ipairs(conf.rules) do
+ if not rule._expr then
-- if no rule.match, use {} to match all request
- local expr, _ = expr.new(rule.match or {})
- core.table.insert_tail(conf.rules_arr, expr)
+ local rule_expr, err = expr.new(rule.match or {})
+ if not rule_expr then
+ core.log.error("failed to create the 'match' expression: ",
err)
+ return
+ end
+
+ -- Hide the compiled expression in a metatable so that it stays
out of
+ -- the configuration: the "ipmatch" operator compiles into an
ipmatcher,
+ -- whose lookup tables are keyed by integers, and a configuration
holding
+ -- one can no longer be JSON encoded.
+ setmetatable(rule, {__index = {_expr = rule_expr}})
end
- end
- for i, rule in ipairs(conf.rules) do
- local expr = conf.rules_arr[i]
- match_result = expr:eval(ctx.var)
+ match_result = rule._expr:eval(ctx.var)
if match_result then
local action = next_action(rule.actions)
diff --git a/t/plugin/traffic-label2.t b/t/plugin/traffic-label2.t
index 70271f20d..422af3b57 100644
--- a/t/plugin/traffic-label2.t
+++ b/t/plugin/traffic-label2.t
@@ -551,3 +551,66 @@ qr/property \\"rules\\" is required/
--- error_code: 400
--- response_body eval
qr/expect array to have at least 1 items/
+
+
+
+=== TEST 19: set route with an ipmatch match expression
+--- 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": {
+ "traffic-label": {
+ "rules": [
+ {
+ "match": [
+ [
+ "http_x_forwarded_for",
+ "ipmatch",
+ ["10.7.22.0/24"]
+ ]
+ ],
+ "actions": [
+ {
+ "set_headers": {
+ "X-server-id": 100
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/echo"
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 20: the route config stays serialisable once the expression is
compiled
+--- pipelined_requests eval
+["GET /echo", "GET /echo"]
+--- more_headers
+X-Forwarded-For: 10.7.22.1
+--- error_code eval
+[200, 200]
+--- no_error_log
+[error]
+excessively sparse array