Skip to content

Commit

Permalink
fix(router) regex path matching not considered with exact path match
Browse files Browse the repository at this point in the history
  • Loading branch information
bungle committed Jan 9, 2019
1 parent 5c24e50 commit f8c5987
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 13 deletions.
30 changes: 17 additions & 13 deletions kong/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,8 @@ do

[MATCH_RULES.URI] = function(route_t, ctx)
do
local uri_t = route_t.uris[ctx.hits.uri or ctx.req_uri]
local uri_t = route_t.uris[ctx.req_uri] or
route_t.uris[ctx.hits.uri]

if uri_t then
if uri_t.is_regex then
Expand Down Expand Up @@ -709,7 +710,8 @@ do
end,

[MATCH_RULES.URI] = function(category, ctx)
return category.routes_by_uris[ctx.hits.uri or ctx.req_uri]
return category.routes_by_uris[ctx.req_uri] or
category.routes_by_uris[ctx.hits.uri]
end,

[MATCH_RULES.METHOD] = function(category, ctx)
Expand Down Expand Up @@ -1007,31 +1009,33 @@ function _M.new(routes)

-- uri match

if plain_indexes.uris[req_uri] then
req_category = bor(req_category, MATCH_RULES.URI)

else
do
local prefix_match
for i = 1, #prefix_uris do
if find(req_uri, prefix_uris[i].value, nil, true) == 1 then
hits.uri = prefix_uris[i].value
req_category = bor(req_category, MATCH_RULES.URI)
prefix_match = find(req_uri, prefix_uris[i].value, nil, true) == 1
if prefix_match then
hits.uri = prefix_uris[i].value
break
end
end

local regex_match, _, err
for i = 1, #regex_uris do
local from, _, err = re_find(req_uri, regex_uris[i].regex, "ajo")
regex_match, _, err = re_find(req_uri, regex_uris[i].regex, "ajo")
if err then
log(ERR, "could not evaluate URI regex: ", err)
return
end

if from then
hits.uri = regex_uris[i].value
req_category = bor(req_category, MATCH_RULES.URI)
if regex_match then
hits.uri = regex_uris[i].value
break
end
end

if prefix_match or regex_match or plain_indexes.uris[req_uri] then
req_category = bor(req_category, MATCH_RULES.URI)
end
end

-- method match
Expand Down
113 changes: 113 additions & 0 deletions spec/02-integration/05-proxy/02-router_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,119 @@ for _, strategy in helpers.each_strategy() do
end)
end)

describe("path prefixes and regexes", function()
local routes

lazy_setup(function()
routes = insert_routes {
{
strip_path = true,
paths = { "/root/fix" },
},
{
strip_path = true,
paths = { "/root/(fixture)" },
},
{
strip_path = true,
paths = { "/root2/fixture" },
},
{
strip_path = true,
paths = { "/root2/fix" },
},
{
strip_path = true,
paths = { "/root2/(fixture)" },
}

}
end)

lazy_teardown(function()
remove_routes(routes)
end)

it("prioritizes regexes over prefixes", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/root/fixture",
headers = {
["kong-debug"] = 1,
}
})

assert.res_status(200, res)

assert.equal(routes[2].id, res.headers["kong-route-id"])
assert.equal(routes[2].service.id, res.headers["kong-service-id"])
assert.equal(routes[2].service.name, res.headers["kong-service-name"])
end)

it("prioritizes exact match over regexes and prefixes", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/root2/fixture",
headers = {
["kong-debug"] = 1,
}
})

assert.res_status(200, res)

assert.equal(routes[3].id, res.headers["kong-route-id"])
assert.equal(routes[3].service.id, res.headers["kong-service-id"])
assert.equal(routes[3].service.name, res.headers["kong-service-name"])
end)

end)

describe("[paths]", function()
local routes

lazy_setup(function()
routes = insert_routes {
{
strip_path = true,
hosts = { "route.com" },
paths = { "/pat" },
},
{
strip_path = true,
hosts = { "route.com" },
paths = { "/path" },
methods = { "POST" },
},
{
strip_path = true,
hosts = { "route.com" },
paths = { "/(path)" },
},
}
end)

lazy_teardown(function()
remove_routes(routes)
end)

it("matches regex path even when there is exact and prefix match", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/path",
headers = {
["Host"] = "route.com",
["kong-debug"] = 1,
}
})

assert.res_status(200, res)

assert.equal(routes[3].id, res.headers["kong-route-id"])
assert.equal(routes[3].service.id, res.headers["kong-service-id"])
assert.equal(routes[3].service.name, res.headers["kong-service-name"])
end)
end)

describe("slash handing", function()
local checks = {
-- upstream url paths request path expected path strip uri
Expand Down

0 comments on commit f8c5987

Please sign in to comment.