Mercurial > prosody-hg
comparison plugins/mod_disco.lua @ 3347:99f56bed5228
mod_disco: Cache disco#info reply and caps hash for host, return correct caps hash, and respond to disco#info to the caps hash node.
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Sun, 11 Jul 2010 21:21:38 +0500 |
| parents | c70c6d5bf270 |
| children | 3b84a84f472a |
comparison
equal
deleted
inserted
replaced
| 3346:c9294e190bb6 | 3347:99f56bed5228 |
|---|---|
| 34 | 34 |
| 35 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 |
| 36 module:add_feature("http://jabber.org/protocol/disco#info"); | 36 module:add_feature("http://jabber.org/protocol/disco#info"); |
| 37 module:add_feature("http://jabber.org/protocol/disco#items"); | 37 module:add_feature("http://jabber.org/protocol/disco#items"); |
| 38 | 38 |
| 39 -- Handle disco requests to the server | 39 -- Generate and cache disco result and caps hash |
| 40 | 40 local _cached_server_disco_info, _cached_server_caps_feature, _cached_server_caps_hash; |
| 41 local function build_server_disco_info(stanza) | 41 local function build_server_disco_info() |
| 42 local query = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info" }); | |
| 42 local done = {}; | 43 local done = {}; |
| 43 for _,identity in ipairs(module:get_host_items("identity")) do | 44 for _,identity in ipairs(module:get_host_items("identity")) do |
| 44 local identity_s = identity.category.."\0"..identity.type; | 45 local identity_s = identity.category.."\0"..identity.type; |
| 45 if not done[identity_s] then | 46 if not done[identity_s] then |
| 46 stanza:tag("identity", identity):up(); | 47 query:tag("identity", identity):up(); |
| 47 done[identity_s] = true; | 48 done[identity_s] = true; |
| 48 end | 49 end |
| 49 end | 50 end |
| 50 for _,feature in ipairs(module:get_host_items("feature")) do | 51 for _,feature in ipairs(module:get_host_items("feature")) do |
| 51 if not done[feature] then | 52 if not done[feature] then |
| 52 stanza:tag("feature", {var=feature}):up(); | 53 query:tag("feature", {var=feature}):up(); |
| 53 done[feature] = true; | 54 done[feature] = true; |
| 54 end | 55 end |
| 55 end | 56 end |
| 57 _cached_server_disco_info = query; | |
| 58 _cached_server_caps_hash = calculate_hash(query); | |
| 59 _cached_server_caps_feature = st.stanza("c", { | |
| 60 xmlns = "http://jabber.org/protocol/caps"; | |
| 61 hash = "sha-1"; | |
| 62 node = "http://prosody.im"; | |
| 63 ver = _cached_server_caps_hash; | |
| 64 }); | |
| 56 end | 65 end |
| 66 local function clear_disco_cache() | |
| 67 _cached_server_disco_info, _cached_server_caps_feature, _cached_server_caps_hash = nil, nil, nil; | |
| 68 end | |
| 69 local function get_server_disco_info() | |
| 70 if not _cached_server_disco_info then build_server_disco_info(); end | |
| 71 return _cached_server_disco_info; | |
| 72 end | |
| 73 local function get_server_caps_feature() | |
| 74 if not _cached_server_caps_feature then build_server_disco_info(); end | |
| 75 return _cached_server_caps_feature; | |
| 76 end | |
| 77 local function get_server_caps_hash() | |
| 78 if not _cached_server_caps_hash then build_server_disco_info(); end | |
| 79 return _cached_server_caps_hash; | |
| 80 end | |
| 81 | |
| 82 module:hook("item-added/identity", clear_disco_cache); | |
| 83 module:hook("item-added/feature", clear_disco_cache); | |
| 84 | |
| 85 -- Handle disco requests to the server | |
| 57 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event) | 86 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event) |
| 58 local origin, stanza = event.origin, event.stanza; | 87 local origin, stanza = event.origin, event.stanza; |
| 59 if stanza.attr.type ~= "get" then return; end | 88 if stanza.attr.type ~= "get" then return; end |
| 60 local node = stanza.tags[1].attr.node; | 89 local node = stanza.tags[1].attr.node; |
| 61 if node and node ~= "" then return; end -- TODO fire event? | 90 if node and node ~= "" and node ~= get_server_caps_hash() then return; end -- TODO fire event? |
| 62 local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info"); | 91 local reply = st.reply(stanza):add_child(get_server_disco_info()); |
| 63 build_server_disco_info(reply); | |
| 64 origin.send(reply); | 92 origin.send(reply); |
| 65 return true; | 93 return true; |
| 66 end); | 94 end); |
| 67 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) | 95 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) |
| 68 local origin, stanza = event.origin, event.stanza; | 96 local origin, stanza = event.origin, event.stanza; |
| 79 end | 107 end |
| 80 origin.send(reply); | 108 origin.send(reply); |
| 81 return true; | 109 return true; |
| 82 end); | 110 end); |
| 83 | 111 |
| 84 -- Server caps hash calculation | 112 -- Handle caps stream feature |
| 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) | 113 module:hook("stream-features", function (event) |
| 102 if caps_hash_feature then | 114 event.features:add_child(get_server_caps_feature()); |
| 103 event.features:add_child(caps_hash_feature); | |
| 104 end | |
| 105 end); | 115 end); |
| 106 | 116 |
| 107 -- Handle disco requests to user accounts | 117 -- Handle disco requests to user accounts |
| 108 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event) | 118 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event) |
| 109 local origin, stanza = event.origin, event.stanza; | 119 local origin, stanza = event.origin, event.stanza; |
