# HG changeset patch # User Guus der Kinderen # Date 1704365975 -3600 # Node ID c3eeeb96840309bc9c8619edd0af5d827cd8214a # Parent f55e65315ba0bc772ba13297a482ad2c92575af8 mod_pubsub_serverinfo: Detect existence of pub/sub node Instead of blindly trying to create the pub/sub node to publish items to, a service discovery query is performed to check if node creation is required. Added various bits of warn and debug logging, to give a user better feedback if and why something is failing. diff -r f55e65315ba0 -r c3eeeb968403 mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua --- a/mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua Wed Jan 03 23:05:14 2024 +0100 +++ b/mod_pubsub_serverinfo/mod_pubsub_serverinfo.lua Thu Jan 04 11:59:35 2024 +0100 @@ -11,8 +11,15 @@ local opt_in_reports function module.load() - -- Will error out with a 'conflict' if the node already exists. TODO: create the node only when it's missing. - create_node():next() + discover_node():next( + function(exists) + if not exists then create_node() end + end + ):catch( + function(error) + module:log("warn", "Error prevented discovery or creation of pub/sub node at %s: %s", service, error) + end + ) module:add_feature("urn:xmpp:serverinfo:0"); @@ -29,7 +36,35 @@ delete_node(); -- Should this block, to delay unload() until the node is deleted? end --- Returns a promise +-- Returns a promise of a boolean +function discover_node() + local request = st.iq({ type = "get", to = service, from = actor, id = new_id() }) + :tag("query", { xmlns = "http://jabber.org/protocol/disco#items" }) + + module:log("debug", "Sending request to discover existence of pub/sub node '%s' at %s", node, service) + return module:send_iq(request):next( + function(response) + if response.stanza == nil or response.stanza.attr.type ~= "result" then + module:log("warn", "Unexpected response to service discovery items request at %s: %s", service, response.stanza) + return false + end + + local query = response.stanza:get_child("query", "http://jabber.org/protocol/disco#items") + if query ~= nil then + for item in query:childtags("item") do + if item.attr.jid == service and item.attr.node == node then + module:log("debug", "pub/sub node '%s' at %s does exists.", node, service) + return true + end + end + end + module:log("debug", "pub/sub node '%s' at %s does not exist.", node, service) + return false; + end + ); +end + +-- Returns a promise of a boolean function create_node() local request = st.iq({ type = "set", to = service, from = actor, id = new_id() }) :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) @@ -44,16 +79,39 @@ :up() :tag("field", { var = "pubsub#persist_items" }) :text_tag("value", "0") - return module:send_iq(request); + + module:log("debug", "Sending request to create pub/sub node '%s' at %s", node, service) + return module:send_iq(request):next( + function(response) + if response.stanza == nil or response.stanza.attr.type ~= "result" then + module:log("warn", "Unexpected response to pub/sub node '%s' creation request at %s: %s", node, service, response.stanza) + return false + else + module:log("debug", "Successfully created pub/sub node '%s' at %s", node, service) + return true + end + end + ) end --- Returns a promise +-- Returns a promise of a boolean function delete_node() local request = st.iq({ type = "set", to = service, from = actor, id = new_id() }) :tag("pubsub", { xmlns = "http://jabber.org/protocol/pubsub" }) :tag("delete", { node = node }); - return module:send_iq(request); + module:log("debug", "Sending request to delete pub/sub node '%s' at %s", node, service) + return module:send_iq(request):next( + function(response) + if response.stanza == nil or response.stanza.attr.type ~= "result" then + module:log("warn", "Unexpected response to pub/sub node '%s' deletion request at %s: %s", node, service, response.stanza) + return false + else + module:log("debug", "Successfully deleted pub/sub node '%s' at %s", node, service) + return true + end + end + ) end function publish_serverinfo() @@ -112,7 +170,20 @@ request:up():up() - module:send_iq(request):next() + module:send_iq(request):next( + function(response) + if response.stanza == nil or response.stanza.attr.type ~= "result" then + module:log("warn", "Unexpected response to item publication at pub/sub node '%s' on %s: %s", node, service, response.stanza) + return false + else + module:log("debug", "Successfully published item on pub/sub node '%s' at %s", node, service) + return true + end + end, + function(error) + module:log("warn", "Error prevented publication of item on pub/sub node at %s: %s", service, error) + end + ) return publication_interval; end