@@ -26,6 +26,7 @@ local lrucache = require("resty.lrucache")
2626local bit = require (" bit" )
2727local ngx = ngx
2828local table = table
29+ local clear_tab = base .clear_tab
2930local new_tab = base .new_tab
3031local tonumber = tonumber
3132local ipairs = ipairs
@@ -39,7 +40,9 @@ local io = io
3940local package = package
4041local getmetatable = getmetatable
4142local setmetatable = setmetatable
43+ local select = select
4244local type = type
45+ local unpack = unpack
4346local error = error
4447local newproxy = newproxy
4548local cur_level = ngx .config .subsystem == " http" and
@@ -536,7 +539,7 @@ local function compare_val(l_v, op, r_v, opts)
536539end
537540
538541
539- local function match_route_opts (route , opts , ... )
542+ local function match_route_opts (route , opts , args )
540543 local method = opts .method
541544 local opts_matched_exists = (opts .matched ~= nil )
542545 if route .method ~= 0 then
@@ -569,7 +572,8 @@ local function match_route_opts(route, opts, ...)
569572 local hosts = route .hosts
570573 local host = opts .host
571574 if host then
572- for i = 1 , # hosts , 2 do
575+ local len = # hosts
576+ for i = 1 , len , 2 do
573577 if match_host (hosts [i ], hosts [i + 1 ], host ) then
574578 if opts_matched_exists then
575579 if hosts [i ] then
@@ -607,7 +611,18 @@ local function match_route_opts(route, opts, ...)
607611 end
608612
609613 if route .filter_fun then
610- if not route .filter_fun (opts .vars or ngx_var , opts , ... ) then
614+ local fn = route .filter_fun
615+ local ok
616+ if args then
617+ -- now we can safely clear the self.args
618+ local args_len = args [0 ]
619+ args [0 ] = nil
620+ ok = fn (opts .vars or ngx_var , opts , unpack (args , 1 , args_len ))
621+ else
622+ ok = fn (opts .vars or ngx_var , opts )
623+ end
624+
625+ if not ok then
611626 return false
612627 end
613628 end
@@ -616,7 +631,7 @@ local function match_route_opts(route, opts, ...)
616631end
617632
618633
619- local function _match_from_routes (routes , path , opts , ... )
634+ local function _match_from_routes (routes , path , opts , args )
620635 if opts == empty_table then
621636 local route = routes [1 ]
622637 if not route or route .method == 0 then
@@ -628,7 +643,7 @@ local function _match_from_routes(routes, path, opts, ...)
628643 for _ , route in ipairs (routes ) do
629644 if route .path_op == " =" then
630645 if route .path == path then
631- if match_route_opts (route , opts , ... ) then
646+ if match_route_opts (route , opts , args ) then
632647 if opts_matched_exists then
633648 opts .matched ._path = path
634649 end
@@ -638,7 +653,7 @@ local function _match_from_routes(routes, path, opts, ...)
638653 goto continue
639654 end
640655
641- if match_route_opts (route , opts , ... ) then
656+ if match_route_opts (route , opts , args ) then
642657 -- log_info("matched route: ", require("cjson").encode(route))
643658 -- log_info("matched path: ", path)
644659 if compare_param (path , route , opts ) then
@@ -656,7 +671,7 @@ local function _match_from_routes(routes, path, opts, ...)
656671end
657672
658673
659- local function match_route (self , path , opts , ... )
674+ local function match_route (self , path , opts , args )
660675 if opts .matched then
661676 clear_tab (opts .matched )
662677 end
@@ -665,7 +680,7 @@ local function match_route(self, path, opts, ...)
665680 if routes then
666681 local opts_matched_exists = (opts .matched ~= nil )
667682 for _ , route in ipairs (routes ) do
668- if match_route_opts (route , opts , ... ) then
683+ if match_route_opts (route , opts , args ) then
669684 if opts_matched_exists then
670685 opts .matched ._path = path
671686 end
@@ -687,7 +702,7 @@ local function match_route(self, path, opts, ...)
687702
688703 routes = self .match_data [idx ]
689704 if routes then
690- local route = _match_from_routes (routes , path , opts , ... )
705+ local route = _match_from_routes (routes , path , opts , args )
691706 if route then
692707 return route
693708 end
@@ -715,7 +730,25 @@ function _M.dispatch(self, path, opts, ...)
715730 error (" invalid argument path" , 2 )
716731 end
717732
718- local route , err = match_route (self , path , opts or empty_table , ... )
733+ local args
734+ local len = select (' #' , ... )
735+ if len > 0 then
736+ if not self .args then
737+ self .args = {... }
738+ else
739+ clear_tab (self .args )
740+ for i = 1 , len do
741+ self .args [i ] = select (i , ... )
742+ end
743+ end
744+
745+ -- To keep the self.args in safe,
746+ -- we can't yield until filter_fun is called
747+ args = self .args
748+ args [0 ] = len
749+ end
750+
751+ local route , err = match_route (self , path , opts or empty_table , args )
719752 if not route then
720753 if err then
721754 return nil , err
0 commit comments