# HG changeset patch # User tmolitor # Date 1502746265 -7200 # Node ID fff185e7ab7378f6648a8883904bf10ab00fab3f # Parent b5fae17e4403ccd61f7b2f59cf258ff461bd569a mod_cloud_notify: Implement the "stripped stanzas" proposal. See https://mail.jabber.org/pipermail/standards/2017-July/033089.html diff -r b5fae17e4403 -r fff185e7ab73 mod_cloud_notify/mod_cloud_notify.lua --- a/mod_cloud_notify/mod_cloud_notify.lua Sat Aug 12 20:45:11 2017 +0200 +++ b/mod_cloud_notify/mod_cloud_notify.lua Mon Aug 14 23:31:05 2017 +0200 @@ -4,6 +4,7 @@ -- -- This file is MIT/X11 licensed. +local t_insert = table.insert; local st = require"util.stanza"; local jid = require"util.jid"; local dataform = require"util.dataforms".new; @@ -110,7 +111,7 @@ if hashes.sha256(push_identifier, true) == stanza.attr.id then if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and push_errors[push_identifier] > 0 then push_errors[push_identifier] = 0; - module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s", push_identifier, tostring(push_errors[push_identifier])); + module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s again", push_identifier, tostring(push_errors[push_identifier])); end end end @@ -132,6 +133,8 @@ local push_jid = enable.attr.jid; -- SHOULD contain a 'node' attribute local push_node = enable.attr.node; + -- CAN contain a 'include_payload' attribute + local include_payload = enable.attr.include_payload; if not push_jid then origin.log("debug", "Push notification enable request missing the 'jid' field"); origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing jid")); @@ -146,6 +149,7 @@ local push_service = { jid = push_jid; node = push_node; + include_payload = include_payload; count = 0; options = publish_options and st.preserialize(publish_options); }; @@ -197,6 +201,23 @@ end module:hook("iq-set/self/"..xmlns_push..":disable", push_disable); +-- clone a stanza and strip it +local function strip_stanza(stanza) + local tags = {}; + local new = { name = stanza.name, attr = { xmlns = stanza.attr.xmlns, type = stanza.attr.type }, tags = tags }; + for i=1,#stanza do + local child = stanza[i]; + if type(child) == "table" then -- don't add raw text nodes + if child.name then + child = strip_stanza(child); + t_insert(tags, child); + end + t_insert(new, child); + end + end + return setmetatable(new, st.stanza_mt); +end + local push_form = dataform { { name = "FORM_TYPE"; type = "hidden"; value = "urn:xmpp:push:summary"; }; { name = "message-count"; type = "text-single"; }; @@ -242,6 +263,16 @@ form_data["last-message-body"] = stanza:get_child_text("body"); end push_publish:add_child(push_form:form(form_data)); + if stanza and push_info.include_payload == "stripped" then + push_publish:tag("payload", { type = "stripped" }) + :add_child(strip_stanza(stanza)); + push_publish:up(); -- / payload + end + if stanza and push_info.include_payload == "full" then + push_publish:tag("payload", { type = "full" }) + :add_child(st.clone(stanza)); + push_publish:up(); -- / payload + end push_publish:up(); -- / notification push_publish:up(); -- / publish push_publish:up(); -- / pubsub @@ -250,6 +281,7 @@ end -- send out push module:log("debug", "Sending push notification for %s@%s to %s (%s)", node, module.host, push_info.jid, tostring(push_info.node)); + -- module:log("debug", "PUSH STANZA: %s", tostring(push_publish)); -- handle push errors for this node if push_errors[push_identifier] == nil then push_errors[push_identifier] = 0; @@ -274,6 +306,7 @@ -- publish on offline message module:hook("message/offline/handle", function(event) local node, user_push_services = get_push_settings(event.stanza, event.origin); + module:log("debug", "Invoking cloud handle_notify_request() for offline stanza"); handle_notify_request(event.stanza, node, user_push_services); end, 1); @@ -309,7 +342,7 @@ -- process unacked stanzas process_smacks_queue(queue, session); -- process future unacked (hibernated) stanzas - filters.add_filter(session, "stanzas/out", process_smacks_stanza); + filters.add_filter(session, "stanzas/out", process_smacks_stanza, -990); end -- smacks hibernation is ended @@ -384,21 +417,6 @@ -- can be used by other modules to ping one or more (or all) push endpoints module:hook("cloud-notify-ping", send_ping); --- TODO: this has to be done on first connect not on offline broadcast, else the counter will be incorrect --- TODO: it seems this is already done, so this could be safely removed, couldn't it? --- module:hook("message/offline/broadcast", function(event) --- local origin = event.origin; --- local user_push_services = push_store:get(origin.username); --- if not #user_push_services then return end --- --- for _, push_info in pairs(user_push_services) do --- if push_info then --- push_info.count = 0; --- end --- end --- push_store:set(origin.username, user_push_services); --- end, 1); - module:log("info", "Module loaded"); function module.unload() if module.unhook then