Comparison

plugins/mod_disco.lua @ 3343:c70c6d5bf270

mod_disco: Support for putting the server's caps hash in stream:features to allow the client to cache disco#info for the server instead of requesting it at each login.
author Matthew Wild <mwild1@gmail.com>
date Fri, 09 Jul 2010 13:20:00 +0100
parent 2925:692b3c6c5bd2
child 3347:99f56bed5228
comparison
equal deleted inserted replaced
3342:20e99763a08a 3343:c70c6d5bf270
9 local componentmanager_get_children = require "core.componentmanager".get_children; 9 local componentmanager_get_children = require "core.componentmanager".get_children;
10 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; 10 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
11 local jid_split = require "util.jid".split; 11 local jid_split = require "util.jid".split;
12 local jid_bare = require "util.jid".bare; 12 local jid_bare = require "util.jid".bare;
13 local st = require "util.stanza" 13 local st = require "util.stanza"
14 local calculate_hash = require "util.caps".calculate_hash;
14 15
15 local disco_items = module:get_option("disco_items") or {}; 16 local disco_items = module:get_option("disco_items") or {};
16 do -- validate disco_items 17 do -- validate disco_items
17 for _, item in ipairs(disco_items) do 18 for _, item in ipairs(disco_items) do
18 local err; 19 local err;
33 34
34 module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router 35 module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router
35 module:add_feature("http://jabber.org/protocol/disco#info"); 36 module:add_feature("http://jabber.org/protocol/disco#info");
36 module:add_feature("http://jabber.org/protocol/disco#items"); 37 module:add_feature("http://jabber.org/protocol/disco#items");
37 38
39 -- Handle disco requests to the server
40
41 local function build_server_disco_info(stanza)
42 local done = {};
43 for _,identity in ipairs(module:get_host_items("identity")) do
44 local identity_s = identity.category.."\0"..identity.type;
45 if not done[identity_s] then
46 stanza:tag("identity", identity):up();
47 done[identity_s] = true;
48 end
49 end
50 for _,feature in ipairs(module:get_host_items("feature")) do
51 if not done[feature] then
52 stanza:tag("feature", {var=feature}):up();
53 done[feature] = true;
54 end
55 end
56 end
38 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event) 57 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
39 local origin, stanza = event.origin, event.stanza; 58 local origin, stanza = event.origin, event.stanza;
40 if stanza.attr.type ~= "get" then return; end 59 if stanza.attr.type ~= "get" then return; end
41 local node = stanza.tags[1].attr.node; 60 local node = stanza.tags[1].attr.node;
42 if node and node ~= "" then return; end -- TODO fire event? 61 if node and node ~= "" then return; end -- TODO fire event?
43
44 local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info"); 62 local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info");
45 local done = {}; 63 build_server_disco_info(reply);
46 for _,identity in ipairs(module:get_host_items("identity")) do
47 local identity_s = identity.category.."\0"..identity.type;
48 if not done[identity_s] then
49 reply:tag("identity", identity):up();
50 done[identity_s] = true;
51 end
52 end
53 for _,feature in ipairs(module:get_host_items("feature")) do
54 if not done[feature] then
55 reply:tag("feature", {var=feature}):up();
56 done[feature] = true;
57 end
58 end
59 origin.send(reply); 64 origin.send(reply);
60 return true; 65 return true;
61 end); 66 end);
62 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) 67 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event)
63 local origin, stanza = event.origin, event.stanza; 68 local origin, stanza = event.origin, event.stanza;
73 reply:tag("item", {jid=item[1], name=item[2]}):up(); 78 reply:tag("item", {jid=item[1], name=item[2]}):up();
74 end 79 end
75 origin.send(reply); 80 origin.send(reply);
76 return true; 81 return true;
77 end); 82 end);
83
84 -- Server caps hash calculation
85 local caps_hash_feature;
86
87 local function recalculate_server_caps()
88 local caps_hash = calculate_hash(st.stanza());
89 caps_hash_feature = st.stanza("c", {
90 xmlns = "http://jabber.org/protocol/caps";
91 hash = "sha-1";
92 node = "http://prosody.im";
93 ver = caps_hash;
94 });
95 end
96 recalculate_server_caps();
97
98 module:hook("item-added/identity", recalculate_server_caps);
99 module:hook("item-added/feature", recalculate_server_caps);
100
101 module:hook("stream-features", function (event)
102 if caps_hash_feature then
103 event.features:add_child(caps_hash_feature);
104 end
105 end);
106
107 -- Handle disco requests to user accounts
78 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event) 108 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event)
79 local origin, stanza = event.origin, event.stanza; 109 local origin, stanza = event.origin, event.stanza;
80 if stanza.attr.type ~= "get" then return; end 110 if stanza.attr.type ~= "get" then return; end
81 local node = stanza.tags[1].attr.node; 111 local node = stanza.tags[1].attr.node;
82 if node and node ~= "" then return; end -- TODO fire event? 112 if node and node ~= "" then return; end -- TODO fire event?