local tostring = tostring;
local codes = require "net.http.codes";
local _G = _G;
+local legacy_httpserver = require "net.httpserver";
local _M = {};
local listener = {};
+local function is_wildcard_event(event)
+ return event:sub(-2, -1) == "/*";
+end
+local function is_wildcard_match(wildcard_event, event)
+ return wildcard_event:sub(1, -2) == event:sub(1, #wildcard_event-1);
+end
+
+local event_map = events._event_map;
+setmetatable(events._handlers, {
+ __index = function (handlers, curr_event)
+ if is_wildcard_event(curr_event) then return; end -- Wildcard events cannot be fired
+ -- Find all handlers that could match this event, sort them
+ -- and then put the array into handlers[event]
+ local matching_handlers_set = {};
+ local handlers_array = {};
+ for event, handlers_set in pairs(event_map) do
+ if event == curr_event or
+ is_wildcard_event(event) and is_wildcard_match(event, curr_event) then
+ for handler, priority in pairs(handlers_set) do
+ matching_handlers_set[handler] = { (select(2, event:gsub("/", "%1"))), priority };
+ table.insert(handlers_array, handler);
+ end
+ end
+ end
+ if #handlers_array == 0 then return; end
+ table.sort(handlers_array, function(b, a)
+ local a_score, b_score = matching_handlers_set[a], matching_handlers_set[b];
+ for i = 1, #a_score do
+ if a ~= b then -- If equal, compare next score value
+ return a_score[i] < b_score[i];
+ end
+ end
+ return false;
+ end);
+ handlers[curr_event] = handlers_array;
+ return handlers_array;
+ end;
+ __newindex = function (handlers, curr_event, handlers_array)
+ if handlers_array == nil
+ and is_wildcard_event(curr_event) then
+ -- Invalidate all matching
+ for event in pairs(handlers) do
+ if is_wildcard_match(curr_event, event) then
+ handlers[event] = nil;
+ end
+ end
+ end
+ end;
+});
+
local handle_request;
local _1, _2, _3;
local function _handle_request() return handle_request(_1, _2, _3); end
--log("debug", "Event: %s", event);
if events.fire_event(event, payload) ~= nil then return; end
-- TODO try adding/stripping / at the end, but this needs to work via an HTTP redirect
+ if events.fire_event("*", payload) ~= nil then return; end
end
-- if handler not called, fallback to legacy httpserver handlers
function _M.legacy_handler(request, response)
log("debug", "Invoking legacy handler");
local base = request.path:match("^/([^/?]+)");
- local legacy_server = _G.httpserver and _G.httpserver.new.http_servers[5280];
+ local legacy_server = legacy_httpserver and legacy_httpserver.new.http_servers[5280];
local handler = legacy_server and legacy_server.handlers[base];
- if not handler then handler = _G.httpserver and _G.httpserver.set_default_handler.default_handler; end
+ if not handler then handler = legacy_httpserver and legacy_httpserver.set_default_handler.default_handler; end
if handler then
-- add legacy properties to request object
request.url = { path = request.path };