Mercurial > prosody-hg
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 |
| parents | 692b3c6c5bd2 |
| children | 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? |
