Skip to content

Commit 9d1663d

Browse files
authored
feature: passed all of the arguments to filter_fun when matching. (#28)
1 parent 67403d3 commit 9d1663d

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Synopsis
3939
{"arg_name", "==", "json"},
4040
{"arg_weight", ">", 10},
4141
},
42-
filter_fun = function(vars)
42+
filter_fun = function(vars, opts)
4343
return vars["arg_name"] == "json"
4444
end,
4545

@@ -78,7 +78,7 @@ The attributes of each element may contain these:
7878
|remote_addrs|option |A list of client remote address(IPv4 and IPv6), and we can use CIDR format, eg `192.168.1.0/24`.|{"127.0.0.1", "192.0.0.0/8", "::1", "fe80::/32"}|
7979
|methods |option |A list of method name. Here is full valid method list: "GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS", "CONNECT" and "TRACE".|{"GET", "POST"}|
8080
|vars |option |A list of `{var, operator, val}`. For example: {{var, operator, val}, {var, operator, val}, ...}, `{"arg_name", "==", "json"}` means the value of argument `name` expect to `json`. Here is the full [Operator List](#operator-list).|{{"arg_name", "==", "json"}, {"arg_age", ">", 18}}|
81-
|filter_fun |option |User defined filter function, We can use it to achieve matching logic for special scenes. `radixtree` will only pass one parameter which named `vars` when matching route.|function(vars) return vars["arg_name"] == "json" end|
81+
|filter_fun |option |User defined filter function, We can use it to achieve matching logic for special scenes. `radixtree` will pass `vars` and other arguments when matching route.|function(vars) return vars["arg_name"] == "json" end|
8282
|metadata |option |Will return this field if using `rx:match` to match route.||
8383
|handler |option |Will call this function using `rx:dispatch` to match route.||
8484

lib/resty/radixtree.lua

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ local function match_host(route_host_is_wildcard, route_host, request_host)
373373
return true
374374
end
375375

376+
376377
local function match_uri(route_uri_is_wildcard, route_uri, request_uri)
377378
if type(request_uri) ~= "string" or #route_uri > #request_uri then
378379
return false
@@ -390,6 +391,7 @@ local function match_uri(route_uri_is_wildcard, route_uri, request_uri)
390391
return true
391392
end
392393

394+
393395
local compare_funcs = {
394396
["=="] = function (l_v, r_v)
395397
if type(r_v) == "number" then
@@ -431,7 +433,7 @@ local function compare_val(l_v, op, r_v)
431433
end
432434

433435

434-
local function match_route_opts(route, opts)
436+
local function match_route_opts(route, opts, ...)
435437
local method = opts.method
436438
if route.method ~= 0 then
437439
if not method or type(METHODS[method]) ~= "number" or
@@ -517,7 +519,7 @@ local function match_route_opts(route, opts)
517519
end
518520

519521
if route.filter_fun then
520-
if not route.filter_fun(opts.vars or ngx_var) then
522+
if not route.filter_fun(opts.vars or ngx_var, opts, ...) then
521523
return false
522524
end
523525
end
@@ -526,31 +528,30 @@ local function match_route_opts(route, opts)
526528
end
527529

528530

529-
local function _match_from_routes(routes, path, opts)
531+
local function _match_from_routes(routes, path, opts, ...)
530532
for _, route in ipairs(routes) do
531533
if route.path_op == "=" then
532534
if route.path == path then
533-
if match_route_opts(route, opts) then
535+
if match_route_opts(route, opts, ...) then
534536
return route
535537
end
536538
end
537539

538540
else
539-
if match_route_opts(route, opts) then
541+
if match_route_opts(route, opts, ...) then
540542
return route
541543
end
542544
end
543545
end
544-
545546
return nil
546547
end
547548

548549

549-
local function match_route(self, path, opts)
550+
local function match_route(self, path, opts, ...)
550551
local routes = self.hash_path[path]
551552
if routes then
552553
for _, route in ipairs(routes) do
553-
if match_route_opts(route, opts) then
554+
if match_route_opts(route, opts, ...) then
554555
return route
555556
end
556557
end
@@ -569,7 +570,7 @@ local function match_route(self, path, opts)
569570

570571
routes = self.match_data[idx]
571572
if routes then
572-
local route = _match_from_routes(routes, path, opts)
573+
local route = _match_from_routes(routes, path, opts, ...)
573574
if route then
574575
return route
575576
end
@@ -579,7 +580,6 @@ local function match_route(self, path, opts)
579580
return nil
580581
end
581582

582-
583583
function _M.match(self, path, opts)
584584
if type(path) ~= "string" then
585585
error("invalid argument path", 2)
@@ -602,7 +602,7 @@ function _M.dispatch(self, path, opts, ...)
602602
error("invalid argument path", 2)
603603
end
604604

605-
local route, err = match_route(self, path, opts or empty_table)
605+
local route, err = match_route(self, path, opts or empty_table, ...)
606606
if not route then
607607
if err then
608608
return nil, err

t/filter-fun.t

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,75 @@ start to filter
6868
--- response_body
6969
nil
7070
nil
71+
72+
73+
74+
=== TEST 3: match(path, opts)
75+
--- config
76+
location /t {
77+
content_by_lua_block {
78+
local opts = {vars = ngx.var}
79+
local radix = require("resty.radixtree")
80+
local rx = radix.new({
81+
{
82+
paths = "/aa",
83+
metadata = "metadata /aa",
84+
filter_fun = function(vars, opt, ...)
85+
ngx.log(ngx.WARN, "start to filter, opt: ", opts == opt)
86+
return vars['arg_k'] == 'v'
87+
end
88+
}
89+
})
90+
91+
ngx.say(rx:match("/aa", opts))
92+
ngx.say(rx:match("/aa", {}))
93+
}
94+
}
95+
--- request
96+
GET /t?k=v
97+
--- no_error_log
98+
[error]
99+
--- error_log
100+
start to filter, opt: true
101+
start to filter, opt: false
102+
--- response_body
103+
metadata /aa
104+
metadata /aa
105+
106+
107+
108+
=== TEST 4: dispatch(path, opt, ...)
109+
--- config
110+
location /t {
111+
content_by_lua_block {
112+
local opts = {vars = ngx.var}
113+
local radix = require("resty.radixtree")
114+
local rx = radix.new({
115+
{
116+
paths = "/aa",
117+
filter_fun = function(vars, opt, ...)
118+
ngx.log(ngx.WARN, "start to filter, opt: ", opt == opts)
119+
return vars['arg_k'] == 'v'
120+
end,
121+
handler = function (...)
122+
ngx.say("handler /aa")
123+
end,
124+
}
125+
})
126+
127+
ngx.say(rx:dispatch("/aa", opts))
128+
ngx.say(rx:dispatch("/aa", {}))
129+
}
130+
}
131+
--- request
132+
GET /t?k=v
133+
--- no_error_log
134+
[error]
135+
--- error_log
136+
start to filter, opt: true
137+
start to filter, opt: false
138+
--- response_body
139+
handler /aa
140+
true
141+
handler /aa
142+
true

0 commit comments

Comments
 (0)