Skip to content

Commit 77ad662

Browse files
authored
bugfix(radixtree_host_uri): match priority, host > uri. (#817)
* bugfix(radixtree_host_uri): match priority, host > uri. Fix #761.
1 parent 35416e9 commit 77ad662

File tree

4 files changed

+253
-81
lines changed

4 files changed

+253
-81
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,12 @@ endif
6565
check:
6666
.travis/openwhisk-utilities/scancode/scanCode.py --config .travis/ASF-Release.cfg ./
6767
luacheck -q lua
68-
./utils/lj-releng lua/*.lua lua/apisix/*.lua \
68+
./utils/lj-releng lua/*.lua \
69+
lua/apisix/*.lua \
6970
lua/apisix/admin/*.lua \
7071
lua/apisix/core/*.lua \
7172
lua/apisix/http/*.lua \
73+
lua/apisix/http/router/*.lua \
7274
lua/apisix/plugins/*.lua \
7375
lua/apisix/plugins/grpc-transcode/*.lua \
7476
lua/apisix/plugins/limit-count/*.lua > \

lua/apisix/http/router/radixtree_host_uri.lua

Lines changed: 45 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ local plugin = require("apisix.plugin")
2121
local ipairs = ipairs
2222
local type = type
2323
local error = error
24+
local tab_insert = table.insert
2425
local loadstring = loadstring
26+
local pairs = pairs
2527
local user_routes
2628
local cached_version
27-
local only_uri_routes = {}
29+
local host_router
2830
local only_uri_router
29-
local host_uri_routes = {}
30-
local host_uri_router
3131

3232

3333
local _M = {version = 0.1}
3434

3535

36-
local function add_host_uri_routes(path, host, route)
37-
core.log.info("add host+uri route, host: ", host, " path: ", path)
36+
local function push_host_router(route, host_routes, only_uri_routes)
37+
if type(route) ~= "table" then
38+
return
39+
end
3840

3941
local filter_fun, err
4042
if route.value.filter_func then
@@ -50,98 +52,62 @@ local function add_host_uri_routes(path, host, route)
5052
filter_fun = filter_fun()
5153
end
5254

53-
core.table.insert(host_uri_routes, {
54-
paths = {host .. path},
55+
local hosts = route.value.hosts or {route.value.host}
56+
57+
local radixtree_route = {
58+
paths = route.value.uris or route.value.uri,
5559
methods = route.value.methods,
56-
remote_addrs = route.value.remote_addrs or route.value.remote_addr,
60+
remote_addrs = route.value.remote_addrs
61+
or route.value.remote_addr,
5762
vars = route.value.vars,
5863
filter_fun = filter_fun,
5964
handler = function (api_ctx)
6065
api_ctx.matched_params = nil
6166
api_ctx.matched_route = route
62-
end,
63-
})
64-
end
65-
66-
67-
local function push_radixtree_host_router(route)
68-
if type(route) ~= "table" then
69-
return
70-
end
71-
72-
local hosts = route.value.hosts or {route.value.host}
73-
local hosts_wildcard = {}
74-
local uris = route.value.uris or {route.value.uri}
75-
76-
local added_count = 0
77-
for _, host in ipairs(hosts) do
78-
if host:sub(1, 1) == "*" then
79-
core.table.insert(hosts_wildcard, host)
80-
else
81-
for _, uri in ipairs(uris) do
82-
add_host_uri_routes(uri, host, route)
83-
end
84-
added_count = added_count + 1
8567
end
86-
end
68+
}
8769

88-
-- 4 cases:
89-
-- hosts = {}
90-
-- hosts = {"foo.com"}
91-
-- hosts = {"*.foo.com", "bar.com"}
92-
-- hosts = {"*.foo.com", "*.bar.com"}
93-
if added_count > 0 and added_count == #hosts then
70+
if #hosts == 0 then
71+
core.table.insert(only_uri_routes, radixtree_route)
9472
return
9573
end
9674

97-
if #hosts_wildcard == 0 then
98-
hosts_wildcard = nil
99-
end
100-
101-
local filter_fun, err
102-
if route.value.filter_func then
103-
filter_fun, err = loadstring(
104-
"return " .. route.value.filter_func,
105-
"router#" .. route.value.id)
106-
if not filter_fun then
107-
core.log.error("failed to load filter function: ", err,
108-
" route id: ", route.value.id)
109-
return
75+
for i, host in ipairs(hosts) do
76+
local host_rev = host:reverse()
77+
if not host_routes[host_rev] then
78+
host_routes[host_rev] = {radixtree_route}
79+
else
80+
tab_insert(host_routes[host_rev], radixtree_route)
11081
end
111-
112-
filter_fun = filter_fun()
11382
end
114-
115-
core.table.insert(only_uri_routes, {
116-
paths = uris,
117-
method = route.value.methods,
118-
hosts = hosts_wildcard,
119-
remote_addrs = route.value.remote_addrs or route.value.remote_addr,
120-
vars = route.value.vars,
121-
filter_fun = filter_fun,
122-
handler = function (api_ctx)
123-
api_ctx.matched_params = nil
124-
api_ctx.matched_route = route
125-
end,
126-
})
127-
128-
return
12983
end
13084

13185

13286
local function create_radixtree_router(routes)
133-
core.table.clear(host_uri_routes)
134-
core.table.clear(only_uri_routes)
135-
host_uri_router = nil
136-
only_uri_router = nil
87+
local host_routes = {}
88+
local only_uri_routes = {}
89+
host_router = nil
13790

13891
for _, route in ipairs(routes or {}) do
139-
push_radixtree_host_router(route)
92+
push_host_router(route, host_routes, only_uri_routes)
14093
end
14194

142-
-- create router: host_uri_router
143-
if #host_uri_routes > 0 then
144-
host_uri_router = router.new(host_uri_routes)
95+
-- create router: host_router
96+
local host_router_routes = {}
97+
for host_rev, routes in pairs(host_routes) do
98+
local sub_router = router.new(routes)
99+
100+
core.table.insert(host_router_routes, {
101+
paths = host_rev,
102+
filter_fun = function(vars, opts, ...)
103+
return sub_router:dispatch(vars.uri, opts, ...)
104+
end,
105+
handler = function (api_ctx)
106+
end
107+
})
108+
end
109+
if #host_router_routes > 0 then
110+
host_router = router.new(host_router_routes)
145111
end
146112

147113
-- create router: only_uri_router
@@ -176,9 +142,9 @@ function _M.match(api_ctx)
176142
match_opts.vars = api_ctx.var
177143
match_opts.host = api_ctx.var.host
178144

179-
if host_uri_router then
180-
local host_uri = api_ctx.var.host .. api_ctx.var.uri
181-
local ok = host_uri_router:dispatch(host_uri, match_opts, api_ctx)
145+
if host_router then
146+
local host_uri = api_ctx.var.host
147+
local ok = host_router:dispatch(host_uri:reverse(), match_opts, api_ctx)
182148
if ok then
183149
return true
184150
end

lua/apisix/schema_def.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ local upstream_schema = {
253253
description = "the key of chash for dynamic load balancing",
254254
type = "string",
255255
pattern = [[^((uri|server_name|server_addr|request_uri|remote_port]]
256-
.. [[|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$]],
256+
.. [[|remote_addr|query_string|host|hostname)]]
257+
.. [[|arg_[0-9a-zA-z_-]+)$]],
257258
},
258259
desc = {type = "string", maxLength = 256},
259260
id = id_schema

0 commit comments

Comments
 (0)