diff --git a/router.lua b/router.lua index e5ec0f1..3a7d827 100644 --- a/router.lua +++ b/router.lua @@ -30,6 +30,7 @@ local router = { } local COLON_BYTE = string.byte(':', 1) +local WILDCARD_BYTE = string.byte('*', 1) local function match_one_path(node, path, f) for token in path:gmatch("[^/.]+") do @@ -60,6 +61,10 @@ local function resolve(path, node, params) if f then return f, bindings end params[param_name] = param_value -- reset the params table. + elseif child_token:byte(1) == WILDCARD_BYTE then -- it's a * + local param_name = child_token:sub(2) + params[param_name] = current_token .. path + return node[child_token]["LEAF"], params end end diff --git a/spec/router_spec.lua b/spec/router_spec.lua index cbf3a46..3eba504 100644 --- a/spec/router_spec.lua +++ b/spec/router_spec.lua @@ -234,6 +234,35 @@ describe("Router", function() end) -- :execute end) -- default params + describe('Wildcard routes', function() + before_each(function () + r:match({ + GET = { + ["/a/b/*args"] = write_dummy, + }, + POST = { + } + }) + end) + + it("match a single segment", function() + local ok, err = r:execute("GET", "/a/b/c") + assert.is_true(ok) + assert.same(dummy.params.args, "c") + end) + + it("match multiple segments", function() + local ok, err = r:execute("GET", "/a/b/c/d/e/f") + assert.is_true(ok) + assert.same(dummy.params.args, "c/d/e/f") + end) + + it("don't match if the segment is empty", function() + local ok, err = r:execute("GET", "/a/b") + assert.is_nil(ok) + end) + end) + describe("shortcuts", function() for method in ("get post put patch delete trace connect options head"):gmatch("%S+") do local verb = method:upper()