diff --git a/CHANGELOG.md b/CHANGELOG.md index ed00285..a8b94d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - `roles.httpd` role to configure one or more HTTP servers (#196) +- `httpd:delete(name)` method to delete named routes (#197) ## [1.5.0] - 2023-03-29 diff --git a/README.md b/README.md index 7e74fb3..a575d1e 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,13 @@ httpd:route({ path = '/objects', method = 'GET' }, handle3) ... ``` +To delete a named route, use `delete()` method of the `httpd` object: + +```lua +httpd:route({ path = '/path/to', name = 'route' }, 'controller#action') +httpd:delete('route') +``` + The first argument for `route()` is a Lua table with one or more keys: * `file` - a template file name (can be relative to. diff --git a/http/server.lua b/http/server.lua index 286be38..facee94 100644 --- a/http/server.lua +++ b/http/server.lua @@ -1260,6 +1260,23 @@ local function add_route(self, opts, sub) return self end +local function delete_route(self, name) + local route = self.iroutes[name] + if route == nil then + return + end + + self.iroutes[name] = nil + table.remove(self.routes, route) + + -- Update iroutes numeration. + for n, r in ipairs(self.routes) do + if r.name then + self.iroutes[r.name] = n + end + end +end + local function url_for_httpd(httpd, name, args, query) local idx = httpd.iroutes[ name ] @@ -1357,6 +1374,7 @@ local exports = { -- methods route = add_route, + delete = delete_route, match = match_route, helper = set_helper, hook = set_hook, diff --git a/test/integration/http_server_delete_test.lua b/test/integration/http_server_delete_test.lua new file mode 100644 index 0000000..04d2923 --- /dev/null +++ b/test/integration/http_server_delete_test.lua @@ -0,0 +1,37 @@ +local t = require('luatest') +local http_client = require('http.client') + +local helpers = require('test.helpers') + +local g = t.group() + +g.before_each(function() + g.httpd = helpers.cfgserv({ + display_errors = true, + }) + g.httpd:start() +end) + +g.after_each(function() + helpers.teardown(g.httpd) +end) + +g.test_delete = function() + local httpd = g.httpd + httpd:route({ + path = '/content_type', + name = 'content_type', + }, function() + return { + status = 200, + } + end) + + local r = http_client.get(helpers.base_uri .. '/content_type') + t.assert_equals(r.status, 200) + + httpd:delete('content_type') + + r = http_client.get(helpers.base_uri .. '/content_type') + t.assert_equals(r.status, 404) +end