Software /
code /
prosody
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 |
parent | 3343:c70c6d5bf270 |
child | 3348: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; |