+ for _,extension in ipairs(module:get_host_items("extension")) do
+ if not done[extension] then
+ query:add_child(extension);
+ done[extension] = true;
+ end
+ end
+ _cached_server_disco_info = query;
+ _cached_server_caps_hash = calculate_hash(query);
+ _cached_server_caps_feature = st.stanza("c", {
+ xmlns = "http://jabber.org/protocol/caps";
+ hash = "sha-1";
+ node = "http://prosody.im";
+ ver = _cached_server_caps_hash;
+ });
+end
+local function clear_disco_cache()
+ _cached_server_disco_info, _cached_server_caps_feature, _cached_server_caps_hash = nil, nil, nil;
+end
+local function get_server_disco_info()
+ if not _cached_server_disco_info then build_server_disco_info(); end
+ return _cached_server_disco_info;
+end
+local function get_server_caps_feature()
+ if not _cached_server_caps_feature then build_server_disco_info(); end
+ return _cached_server_caps_feature;
+end
+local function get_server_caps_hash()
+ if not _cached_server_caps_hash then build_server_disco_info(); end
+ return _cached_server_caps_hash;
+end
+
+module:hook("item-added/identity", clear_disco_cache);
+module:hook("item-added/feature", clear_disco_cache);
+module:hook("item-added/extension", clear_disco_cache);
+module:hook("item-removed/identity", clear_disco_cache);
+module:hook("item-removed/feature", clear_disco_cache);
+module:hook("item-removed/extension", clear_disco_cache);
+
+-- Handle disco requests to the server
+module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
+ local origin, stanza = event.origin, event.stanza;
+ if stanza.attr.type ~= "get" then return; end
+ local node = stanza.tags[1].attr.node;
+ if node and node ~= "" and node ~= "http://prosody.im#"..get_server_caps_hash() then return; end -- TODO fire event?
+ local reply_query = get_server_disco_info();
+ reply_query.node = node;
+ local reply = st.reply(stanza):add_child(reply_query);