Software /
code /
prosody
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? |