|
1 |
|
2 local t_insert = table.insert; |
|
3 local jid_split = require "util.jid".split; |
|
4 local ipairs = ipairs; |
|
5 local st = require "util.stanza"; |
|
6 |
|
7 module "discohelper"; |
|
8 |
|
9 local function addDiscoItemsHandler(self, jid, func) |
|
10 if self.item_handlers[jid] then |
|
11 t_insert(self.item_handlers[jid], func); |
|
12 else |
|
13 self.item_handlers[jid] = {func}; |
|
14 end |
|
15 end |
|
16 |
|
17 local function addDiscoInfoHandler(self, jid, func) |
|
18 if self.info_handlers[jid] then |
|
19 t_insert(self.info_handlers[jid], func); |
|
20 else |
|
21 self.info_handlers[jid] = {func}; |
|
22 end |
|
23 end |
|
24 |
|
25 local function handle(self, stanza) |
|
26 if stanza.name == "iq" and stanza.tags[1].name == "query" then |
|
27 local query = stanza.tags[1]; |
|
28 local to = stanza.attr.to; |
|
29 local from = stanza.attr.from |
|
30 local node = query.attr.node or ""; |
|
31 local to_node, to_host = jid_split(to); |
|
32 |
|
33 local reply = st.reply(stanza):query(query.attr.xmlns); |
|
34 local handlers; |
|
35 if query.attr.xmlns == "http://jabber.org/protocol/disco#info" then -- select handler set |
|
36 handlers = self.info_handlers; |
|
37 elseif query.attr.xmlns == "http://jabber.org/protocol/disco#items" then |
|
38 handlers = self.item_handlers; |
|
39 end |
|
40 local handler = handlers[to]; -- get the handler |
|
41 if not handler then -- if not found then use default handler |
|
42 if to_node then |
|
43 handler = handlers["*defaultnode"]; |
|
44 else |
|
45 handler = handlers["*defaulthost"]; |
|
46 end |
|
47 end |
|
48 local found; -- to keep track of any handlers found |
|
49 if handler then |
|
50 for _, h in ipairs(handler) do |
|
51 if h(reply, to, from, node) then found = true; end |
|
52 end |
|
53 end |
|
54 if to_node then -- handlers which get called always |
|
55 handler = handlers["*node"]; |
|
56 else |
|
57 handler = handlers["*host"]; |
|
58 end |
|
59 if handler then -- call always called handler |
|
60 for _, h in ipairs(handler) do |
|
61 if h(reply, to, from, node) then found = true; end |
|
62 end |
|
63 end |
|
64 if found then return reply; end -- return the reply if there was one |
|
65 return st.error_reply(stanza, "cancel", "service-unavailable"); |
|
66 end |
|
67 end |
|
68 |
|
69 function new() |
|
70 return { |
|
71 item_handlers = {}; |
|
72 info_handlers = {}; |
|
73 addDiscoItemsHandler = addDiscoItemsHandler; |
|
74 addDiscoInfoHandler = addDiscoInfoHandler; |
|
75 handle = handle; |
|
76 }; |
|
77 end |
|
78 |
|
79 return _M; |