Software /
code /
prosody
Changeset
438:193f9dd64f17
Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 27 Nov 2008 03:12:12 +0000 |
parents | 437:c1a720db2157 |
children | 439:6608ad3a72f3 441:4089b62b510c |
files | core/modulemanager.lua core/stanza_router.lua main.lua plugins/mod_dialback.lua plugins/mod_disco.lua plugins/mod_legacyauth.lua plugins/mod_ping.lua plugins/mod_private.lua plugins/mod_register.lua plugins/mod_roster.lua plugins/mod_saslauth.lua plugins/mod_selftests.lua plugins/mod_time.lua plugins/mod_tls.lua plugins/mod_uptime.lua plugins/mod_vcard.lua plugins/mod_version.lua |
diffstat | 17 files changed, 144 insertions(+), 97 deletions(-) [+] |
line wrap: on
line diff
--- a/core/modulemanager.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/core/modulemanager.lua Thu Nov 27 03:12:12 2008 +0000 @@ -1,5 +1,7 @@ -local log = require "util.logger".init("modulemanager") + +local logger = require "util.logger"; +local log = logger.init("modulemanager") local loadfile, pcall = loadfile, pcall; local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; @@ -14,80 +16,59 @@ module "modulemanager" +local api = {}; -- Module API container + +local modulemap = {}; + local handler_info = {}; -local handlers = {}; - +local stanza_handlers = {}; + local modulehelpers = setmetatable({}, { __index = _G }); -local function _add_iq_handler(module, origin_type, xmlns, handler) - handlers[origin_type] = handlers[origin_type] or {}; - handlers[origin_type].iq = handlers[origin_type].iq or {}; - if not handlers[origin_type].iq[xmlns] then - handlers[origin_type].iq[xmlns]= handler; - handler_info[handler] = module; - log("debug", "mod_%s now handles tag 'iq' with query namespace '%s'", module.name, xmlns); - else - log("warning", "mod_%s wants to handle tag 'iq' with query namespace '%s' but mod_%s already handles that", module.name, xmlns, handler_info[handlers[origin_type].iq[xmlns]].module.name); - end -end -function modulehelpers.add_iq_handler(origin_type, xmlns, handler) - if not (origin_type and handler and xmlns) then return false; end - if type(origin_type) == "table" then - for _, origin_type in ipairs(origin_type) do - _add_iq_handler(getfenv(2).module, origin_type, xmlns, handler); - end - return; - end - _add_iq_handler(getfenv(2).module, origin_type, xmlns, handler); -end - -local function _add_handler(module, origin_type, tag, xmlns, handler) - handlers[origin_type] = handlers[origin_type] or {}; - if not handlers[origin_type][tag] then - handlers[origin_type][tag] = handlers[origin_type][tag] or {}; - handlers[origin_type][tag][xmlns]= handler; - handler_info[handler] = module; - log("debug", "mod_%s now handles tag '%s'", module.name, tag); - elseif handler_info[handlers[origin_type][tag]] then - log("warning", "mod_%s wants to handle tag '%s' but mod_%s already handles that", module.name, tag, handler_info[handlers[origin_type][tag]].module.name); - end -end - -function modulehelpers.add_handler(origin_type, tag, xmlns, handler) - if not (origin_type and tag and xmlns and handler) then return false; end - if type(origin_type) == "table" then - for _, origin_type in ipairs(origin_type) do - _add_handler(getfenv(2).module, origin_type, tag, xmlns, handler); - end - return; - end - _add_handler(getfenv(2).module, origin_type, tag, xmlns, handler); -end - -function load(name) - local mod, err = loadfile("plugins/mod_"..name..".lua"); +function load(host, module_name, config) + local mod, err = loadfile("plugins/mod_"..module_name..".lua"); if not mod then - log("error", "Unable to load module '%s': %s", name or "nil", err or "nil"); + log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); return nil, err; end - local pluginenv = setmetatable({ module = { name = name } }, { __index = modulehelpers }); + if not modulemap[host] then + modulemap[host] = {}; + stanza_handlers[host] = {}; + elseif modulemap[host][module_name] then + log("warn", "%s is already loaded for %s, so not loading again", module_name, host); + return nil, "module-already-loaded"; + end + + local _log = logger.init(host..":"..module_name); + local api_instance = setmetatable({ name = module_name, host = host, config = config, _log = _log, log = function (self, ...) return _log(...); end }, { __index = api }); + + local pluginenv = setmetatable({ module = api_instance }, { __index = _G }); setfenv(mod, pluginenv); + local success, ret = pcall(mod); if not success then log("error", "Error initialising module '%s': %s", name or "nil", ret or "nil"); return nil, ret; end + + modulemap[host][module_name] = mod; + return true; end -function handle_stanza(origin, stanza) +function handle_stanza(host, origin, stanza) local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; + local handlers = stanza_handlers[host]; + if not handlers then + log("warn", "No handlers for %s", host); + return false; + end + if name == "iq" and xmlns == "jabber:client" and handlers[origin_type] then - log("debug", "Stanza is an <iq/>"); local child = stanza.tags[1]; if child then local xmlns = child.attr.xmlns or xmlns; @@ -112,14 +93,54 @@ return false; -- we didn't handle it end +----- API functions exposed to modules ----------- +-- Must all be in api.* + +-- Returns the name of the current module +function api:get_name() + return self.name; +end + +-- Returns the host that the current module is serving +function api:get_host() + return self.host; +end + + +local function _add_iq_handler(module, origin_type, xmlns, handler) + local handlers = stanza_handlers[module.host]; + handlers[origin_type] = handlers[origin_type] or {}; + handlers[origin_type].iq = handlers[origin_type].iq or {}; + if not handlers[origin_type].iq[xmlns] then + handlers[origin_type].iq[xmlns]= handler; + handler_info[handler] = module; + module:log("debug", "I now handle tag 'iq' [%s] with payload namespace '%s'", origin_type, xmlns); + else + module:log("warn", "I wanted to handle tag 'iq' [%s] with payload namespace '%s' but mod_%s already handles that", origin_type, xmlns, handler_info[handlers[origin_type].iq[xmlns]].name); + end +end + +function api:add_iq_handler(origin_type, xmlns, handler) + if not (origin_type and handler and xmlns) then return false; end + if type(origin_type) == "table" then + for _, origin_type in ipairs(origin_type) do + _add_iq_handler(self, origin_type, xmlns, handler); + end + return; + end + _add_iq_handler(self, origin_type, xmlns, handler); +end + + do local event_handlers = {}; - function modulehelpers.add_event_hook(name, handler) + function api:add_event_hook(name, handler) if not event_handlers[name] then event_handlers[name] = {}; end t_insert(event_handlers[name] , handler); + self:log("debug", "Subscribed to %s", name); end function fire_event(name, ...) @@ -132,4 +153,31 @@ end end + +local function _add_handler(module, origin_type, tag, xmlns, handler) + local handlers = stanza_handlers[module.host]; + handlers[origin_type] = handlers[origin_type] or {}; + if not handlers[origin_type][tag] then + handlers[origin_type][tag] = handlers[origin_type][tag] or {}; + handlers[origin_type][tag][xmlns]= handler; + handler_info[handler] = module; + module:log("debug", "I now handle tag '%s' [%s] with xmlns '%s'", tag, origin_type, xmlns); + elseif handler_info[handlers[origin_type][tag]] then + log("warning", "I wanted to handle tag '%s' [%s] but mod_%s already handles that", tag, origin_type, handler_info[handlers[origin_type][tag]].module.name); + end +end + +function api:add_handler(origin_type, tag, xmlns, handler) + if not (origin_type and tag and xmlns and handler) then return false; end + if type(origin_type) == "table" then + for _, origin_type in ipairs(origin_type) do + _add_handler(self, origin_type, tag, xmlns, handler); + end + return; + end + _add_handler(self, origin_type, tag, xmlns, handler); +end + +-------------------------------------------------------------------- + return _M;
--- a/core/stanza_router.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/core/stanza_router.lua Thu Nov 27 03:12:12 2008 +0000 @@ -1,9 +1,3 @@ - --- The code in this file should be self-explanatory, though the logic is horrible --- for more info on that, see doc/stanza_routing.txt, which attempts to condense --- the rules from the RFCs (mainly 3921) - -require "core.servermanager" local log = require "util.logger".init("stanzarouter") @@ -82,7 +76,7 @@ elseif hosts[to] and hosts[to].type == "local" then -- directed at a local server core_handle_stanza(origin, stanza); elseif stanza.attr.xmlns and stanza.attr.xmlns ~= "jabber:client" and stanza.attr.xmlns ~= "jabber:server" then - modules_handle_stanza(origin, stanza); + modules_handle_stanza(host or origin.host or origin.to_host, origin, stanza); elseif hosts[to_bare] and hosts[to_bare].type == "component" then -- hack to allow components to handle node@server component_handle_stanza(origin, stanza); elseif hosts[to] and hosts[to].type == "component" then -- hack to allow components to handle node@server/resource and server/resource @@ -105,7 +99,7 @@ -- that is, they are handled by this server function core_handle_stanza(origin, stanza) -- Handlers - if modules_handle_stanza(origin, stanza) then return; end + if modules_handle_stanza(stanza.attr.to or origin.host, origin, stanza) then return; end if origin.type == "c2s" or origin.type == "c2s_unauthed" then local session = origin;
--- a/main.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/main.lua Thu Nov 27 03:12:12 2008 +0000 @@ -63,10 +63,15 @@ ------------------------------------------------------------------------ -- Initialise modules -local modules_enabled = config.get("*", "core", "modules_enabled"); -if modules_enabled then - for _, module in pairs(modules_enabled) do - modulemanager.load(module); + +for host in pairs(hosts) do + if host ~= "*" then + local modules_enabled = config.get(host, "core", "modules_enabled"); + if modules_enabled then + for _, module in pairs(modules_enabled) do + modulemanager.load(host, module); + end + end end end
--- a/plugins/mod_dialback.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_dialback.lua Thu Nov 27 03:12:12 2008 +0000 @@ -8,7 +8,7 @@ local xmlns_dialback = "jabber:server:dialback"; -add_handler({"s2sin_unauthed", "s2sin"}, "verify", xmlns_dialback, +module:add_handler({"s2sin_unauthed", "s2sin"}, "verify", xmlns_dialback, function (origin, stanza) -- We are being asked to verify the key, to ensure it was generated by us log("debug", "verifying dialback key..."); @@ -26,7 +26,7 @@ origin.sends2s(format("<db:verify from='%s' to='%s' id='%s' type='%s'>%s</db:verify>", attr.to, attr.from, attr.id, type, stanza[1])); end); -add_handler("s2sin_unauthed", "result", xmlns_dialback, +module:add_handler("s2sin_unauthed", "result", xmlns_dialback, function (origin, stanza) -- he wants to be identified through dialback -- We need to check the key with the Authoritative server @@ -42,7 +42,7 @@ hosts[origin.to_host].s2sout[origin.from_host].dialback_verifying = origin; end); -add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback, +module:add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback, function (origin, stanza) if origin.dialback_verifying then local valid; @@ -64,7 +64,7 @@ end end); -add_handler({ "s2sout_unauthed", "s2sout" }, "result", xmlns_dialback, +module:add_handler({ "s2sout_unauthed", "s2sout" }, "result", xmlns_dialback, function (origin, stanza) if stanza.attr.type == "valid" then s2s_make_authenticated(origin);
--- a/plugins/mod_disco.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_disco.lua Thu Nov 27 03:12:12 2008 +0000 @@ -4,9 +4,9 @@ require "core.discomanager".set("disco", "http://jabber.org/protocol/disco#info"); require "core.discomanager".set("disco", "http://jabber.org/protocol/disco#items"); -add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#info", function (session, stanza) +module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#info", function (session, stanza) session.send(discomanager_handle(stanza)); end); -add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#items", function (session, stanza) +module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#items", function (session, stanza) session.send(discomanager_handle(stanza)); end);
--- a/plugins/mod_legacyauth.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_legacyauth.lua Thu Nov 27 03:12:12 2008 +0000 @@ -4,7 +4,7 @@ require "core.discomanager".set("legacyauth", "jabber:iq:auth"); -add_iq_handler("c2s_unauthed", "jabber:iq:auth", +module:add_iq_handler("c2s_unauthed", "jabber:iq:auth", function (session, stanza) local username = stanza.tags[1]:child_with_name("username"); local password = stanza.tags[1]:child_with_name("password"); @@ -43,4 +43,4 @@ end end - end); \ No newline at end of file + end);
--- a/plugins/mod_ping.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_ping.lua Thu Nov 27 03:12:12 2008 +0000 @@ -3,7 +3,7 @@ require "core.discomanager".set("ping", "urn:xmpp:ping"); -add_iq_handler({"c2s", "s2sin"}, "urn:xmpp:ping", +module:add_iq_handler({"c2s", "s2sin"}, "urn:xmpp:ping", function(session, stanza) if stanza.attr.type == "get" then session.send(st.reply(stanza));
--- a/plugins/mod_private.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_private.lua Thu Nov 27 03:12:12 2008 +0000 @@ -6,7 +6,7 @@ require "core.discomanager".set("private", "jabber:iq:private"); -add_iq_handler("c2s", "jabber:iq:private", +module:add_iq_handler("c2s", "jabber:iq:private", function (session, stanza) local type = stanza.attr.type; local query = stanza.tags[1];
--- a/plugins/mod_register.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_register.lua Thu Nov 27 03:12:12 2008 +0000 @@ -6,7 +6,7 @@ require "core.discomanager".set("register", "jabber:iq:register"); -add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) +module:add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) if stanza.tags[1].name == "query" then local query = stanza.tags[1]; if stanza.attr.type == "get" then @@ -73,7 +73,7 @@ end; end); -add_iq_handler("c2s_unauthed", "jabber:iq:register", function (session, stanza) +module:add_iq_handler("c2s_unauthed", "jabber:iq:register", function (session, stanza) if stanza.tags[1].name == "query" then local query = stanza.tags[1]; if stanza.attr.type == "get" then
--- a/plugins/mod_roster.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_roster.lua Thu Nov 27 03:12:12 2008 +0000 @@ -11,7 +11,7 @@ require "core.discomanager".set("roster", "jabber:iq:roster"); -add_iq_handler("c2s", "jabber:iq:roster", +module:add_iq_handler("c2s", "jabber:iq:roster", function (session, stanza) if stanza.tags[1].name == "query" then if stanza.attr.type == "get" then @@ -103,4 +103,4 @@ return true; end end - end); \ No newline at end of file + end);
--- a/plugins/mod_saslauth.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_saslauth.lua Thu Nov 27 03:12:12 2008 +0000 @@ -79,14 +79,14 @@ session.send(s); end -add_handler("c2s_unauthed", "auth", xmlns_sasl, sasl_handler); -add_handler("c2s_unauthed", "abort", xmlns_sasl, sasl_handler); -add_handler("c2s_unauthed", "response", xmlns_sasl, sasl_handler); +module:add_handler("c2s_unauthed", "auth", xmlns_sasl, sasl_handler); +module:add_handler("c2s_unauthed", "abort", xmlns_sasl, sasl_handler); +module:add_handler("c2s_unauthed", "response", xmlns_sasl, sasl_handler); local mechanisms_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-sasl' }; local bind_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-bind' }; local xmpp_session_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-session' }; -add_event_hook("stream-features", +module:add_event_hook("stream-features", function (session, features) if not session.username then features:tag("mechanisms", mechanisms_attr); @@ -100,7 +100,7 @@ end end); -add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", +module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", function (session, stanza) log("debug", "Client tried to bind to a resource"); local resource; @@ -123,7 +123,7 @@ end end); -add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-session", +module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-session", function (session, stanza) log("debug", "Client tried to bind to a resource"); session.send(st.reply(stanza));
--- a/plugins/mod_selftests.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_selftests.lua Thu Nov 27 03:12:12 2008 +0000 @@ -36,7 +36,7 @@ local our_origin = hosts[host]; - add_event_hook("server-started", + module:add_event_hook("server-started", function () local id = st.new_id(); local ping_attr = { xmlns = 'urn:xmpp:ping' };
--- a/plugins/mod_time.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_time.lua Thu Nov 27 03:12:12 2008 +0000 @@ -7,7 +7,7 @@ require "core.discomanager".set("time", "urn:xmpp:time"); -add_iq_handler({"c2s", "s2sin"}, "urn:xmpp:time", +module:add_iq_handler({"c2s", "s2sin"}, "urn:xmpp:time", function(session, stanza) if stanza.attr.type == "get" then session.send(st.reply(stanza):tag("time", {xmlns="urn:xmpp:time"}) @@ -20,7 +20,7 @@ require "core.discomanager".set("time", "jabber:iq:time"); -add_iq_handler({"c2s", "s2sin"}, "jabber:iq:time", +module:add_iq_handler({"c2s", "s2sin"}, "jabber:iq:time", function(session, stanza) if stanza.attr.type == "get" then session.send(st.reply(stanza):tag("query", {xmlns="jabber:iq:time"})
--- a/plugins/mod_tls.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_tls.lua Thu Nov 27 03:12:12 2008 +0000 @@ -9,7 +9,7 @@ local xmlns_starttls ='urn:ietf:params:xml:ns:xmpp-tls'; -add_handler("c2s_unauthed", "starttls", xmlns_starttls, +module:add_handler("c2s_unauthed", "starttls", xmlns_starttls, function (session, stanza) if session.conn.starttls then session.send(st.stanza("proceed", { xmlns = xmlns_starttls })); @@ -25,7 +25,7 @@ end); local starttls_attr = { xmlns = xmlns_starttls }; -add_event_hook("stream-features", +module:add_event_hook("stream-features", function (session, features) if session.conn.starttls then features:tag("starttls", starttls_attr):up();
--- a/plugins/mod_uptime.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_uptime.lua Thu Nov 27 03:12:12 2008 +0000 @@ -8,7 +8,7 @@ require "core.discomanager".set("uptime", "jabber:iq:last"); -add_iq_handler({"c2s", "s2sin"}, "jabber:iq:last", +module:add_iq_handler({"c2s", "s2sin"}, "jabber:iq:last", function (origin, stanza) if stanza.tags[1].name == "query" then if stanza.attr.type == "get" then
--- a/plugins/mod_vcard.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_vcard.lua Thu Nov 27 03:12:12 2008 +0000 @@ -10,7 +10,7 @@ require "core.discomanager".set("vcard", "vcard-temp"); -add_iq_handler({"c2s", "s2sin"}, "vcard-temp", +module:add_iq_handler({"c2s", "s2sin"}, "vcard-temp", function (session, stanza) if stanza.tags[1].name == "vCard" then local to = stanza.attr.to; @@ -46,7 +46,7 @@ end); local feature_vcard_attr = { var='vcard-temp' }; -add_event_hook("stream-features", +module:add_event_hook("stream-features", function (session, features) if session.type == "c2s" then features:tag("feature", feature_vcard_attr):up();
--- a/plugins/mod_version.lua Thu Nov 27 03:06:29 2008 +0000 +++ b/plugins/mod_version.lua Thu Nov 27 03:12:12 2008 +0000 @@ -16,5 +16,5 @@ end end -add_iq_handler("c2s", xmlns_version, handle_version_request); -add_iq_handler("s2sin", xmlns_version, handle_version_request); +module:add_iq_handler("c2s", xmlns_version, handle_version_request); +module:add_iq_handler("s2sin", xmlns_version, handle_version_request);