Skip to content

Commit

Permalink
fix(router) avoid HTTP method to supersede non-plain URI
Browse files Browse the repository at this point in the history
Assuming 2 APIs:
* one with `methods = GET`
* the other with `uris = /httpbin`

And the following request:

    GET /httpbin/foo HTTP/1.1
    Host:

The router would match API 1 and discard the URI matching. However, URI
matching should have a higher priority than HTTP method matching. This
happens because the prefix-URI matching happens *after* plain URI and
plain HTTP method matching.

This patch makes sure that the URI-prefix matching happens before the
"last-resort" HTTP method matching.
  • Loading branch information
thibaultcha committed Feb 11, 2017
1 parent a97d229 commit 4ebaa6e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 42 deletions.
62 changes: 20 additions & 42 deletions kong/core/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,9 @@ local function categorize_api_t(api_t, categories, uris_prefixes, wildcard_hosts
})
end

for _, uri_prefix_regex in ipairs(api_t.uris_prefixes_regexes) do
for i, uri_prefix_regex in ipairs(api_t.uris_prefixes_regexes) do
insert(uris_prefixes, {
uri = api_t.api.uris[i],
regex = uri_prefix_regex.regex,
api_t = api_t,
})
Expand Down Expand Up @@ -298,33 +299,13 @@ do
end,

[MATCH_RULES.URI] = function(api_t, _, uri)
-- plain

if api_t.uris[uri] then
if api_t.strip_uri then
api_t.strip_uri_regex = api_t.uris[uri].strip_regex
end

return true
end

-- prefix

for i = 1, #api_t.uris_prefixes_regexes do
local from, _, err = re_find(uri, api_t.uris_prefixes_regexes[i].regex, "jo")
if err then
log(ERR, "could not search for URI prefix: ", err)
return
end

if from then
if api_t.strip_uri then
api_t.strip_uri_regex = api_t.uris_prefixes_regexes[i].strip_regex
end

return true
end
end
end,

[MATCH_RULES.METHOD] = function(api_t, method)
Expand Down Expand Up @@ -522,10 +503,27 @@ function _M.new(apis)
req_category = bor(req_category, MATCH_RULES.HOST)
end


if indexes.plain_uris[uri] then
req_category = bor(req_category, MATCH_RULES.URI)

else
for i = 1, #uris_prefixes do
local from, _, err = re_find(uri, uris_prefixes[i].regex, "jo")
if err then
log(ERR, "could not search for URI prefix: ", err)
return
end

if from then
uri = uris_prefixes[i].uri
req_category = bor(req_category, MATCH_RULES.URI)
break
end
end
end


if indexes.methods[method] then
req_category = bor(req_category, MATCH_RULES.METHOD)
end
Expand Down Expand Up @@ -556,29 +554,9 @@ function _M.new(apis)
end


-- URI prefix checking
-- no API seemed to belong to any of those recorded in our
-- fast-indexed category lookups, we now want to test for
-- wildcard hosts and prefix URIs


for i = 1, #uris_prefixes do
local from, _, err = re_find(uri, uris_prefixes[i].regex, "jo")
if err then
log(ERR, "could not search for URI prefix: ", err)
return
end

-- our URI matches this API's URI as a prefix
-- let's test all of its other conditions
if from and match_api(uris_prefixes[i].api_t, method, uri, host) then
cache:set(cache_key, uris_prefixes[i].api_t)
return uris_prefixes[i].api_t
end
end


-- wildcard host checking
-- wildcard hosts


for i = 1, #wildcard_hosts do
Expand Down
22 changes: 22 additions & 0 deletions spec/01-unit/12-router_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,28 @@ describe("Router", function()
assert.truthy(api_t)
assert.same(use_case[1], api_t.api)
end)

it("HTTP method does not supersede non-plain URI", function()
local use_case = {
{
name = "api-1",
methods = { "GET" },
},
{
name = "api-2",
uris = { "/httpbin" },
}
}

local router = assert(Router.new(use_case))
local api_t = router.select("GET", "/httpbin", {})
assert.truthy(api_t)
assert.same(use_case[2], api_t.api)

api_t = router.select("GET", "/httpbin/status/200", {})
assert.truthy(api_t)
assert.same(use_case[2], api_t.api)
end)
end)

describe("multiple APIs of same category with conflicting values", function()
Expand Down

0 comments on commit 4ebaa6e

Please sign in to comment.