Mercurial > prosody-modules
comparison mod_pubsub_subscription/mod_pubsub_subscription.lua @ 6110:9db1529c06c2
Merge upstream
| author | tmolitor <thilo@eightysoft.de> |
|---|---|
| date | Sun, 05 Jan 2025 17:50:02 +0100 |
| parents | 6dca425eea15 |
| children | 1c0e9486ba23 |
comparison
equal
deleted
inserted
replaced
| 6109:4cb1cad2badd | 6110:9db1529c06c2 |
|---|---|
| 1 local id = require "util.id"; | |
| 1 local st = require "util.stanza"; | 2 local st = require "util.stanza"; |
| 2 local uuid = require "util.uuid"; | 3 local uuid = require "util.uuid"; |
| 3 local mt = require "util.multitable"; | 4 local mt = require "util.multitable"; |
| 4 local cache = require "util.cache"; | 5 local cache = require "util.cache"; |
| 5 | 6 |
| 35 already_subscibed = true; | 36 already_subscibed = true; |
| 36 break | 37 break |
| 37 end | 38 end |
| 38 | 39 |
| 39 item._id = uuid.generate(); | 40 item._id = uuid.generate(); |
| 40 local iq_id = uuid.generate(); | 41 local iq_id = "pubsub-sub-"..id.short(); |
| 41 pending_subscription:set(iq_id, item._id); | 42 pending_subscription:set(iq_id, item._id); |
| 42 active_subscriptions:set(item.service, item.node, item.from, item._id, item); | 43 active_subscriptions:set(item.service, item.node, item.from, item._id, item); |
| 43 | 44 |
| 44 if not already_subscibed then | 45 if not already_subscibed then |
| 45 module:send(st.iq({ type = "set", id = iq_id, from = item.from, to = item.service }) | 46 module:send(st.iq({ type = "set", id = iq_id, from = item.from, to = item.service }) |
| 49 end | 50 end |
| 50 | 51 |
| 51 for _, event_name in ipairs(valid_events) do | 52 for _, event_name in ipairs(valid_events) do |
| 52 module:hook("pubsub-event/host/"..event_name, function (event) | 53 module:hook("pubsub-event/host/"..event_name, function (event) |
| 53 for _, _, _, _, _, cb in active_subscriptions:iter(event.service, event.node, event.stanza.attr.to, nil, "on_"..event_name) do | 54 for _, _, _, _, _, cb in active_subscriptions:iter(event.service, event.node, event.stanza.attr.to, nil, "on_"..event_name) do |
| 55 event.handled = true; | |
| 54 pcall(cb, event); | 56 pcall(cb, event); |
| 55 end | 57 end |
| 56 end); | 58 end); |
| 57 | 59 |
| 58 module:hook("pubsub-event/bare/"..event_name, function (event) | 60 module:hook("pubsub-event/bare/"..event_name, function (event) |
| 59 for _, _, _, _, _, cb in active_subscriptions:iter(event.service, event.node, event.stanza.attr.to, nil, "on_"..event_name) do | 61 for _, _, _, _, _, cb in active_subscriptions:iter(event.service, event.node, event.stanza.attr.to, nil, "on_"..event_name) do |
| 62 event.handled = true; | |
| 60 pcall(cb, event); | 63 pcall(cb, event); |
| 61 end | 64 end |
| 62 end); | 65 end); |
| 63 end | 66 end |
| 64 | 67 |
| 65 function handle_iq(context, event) | 68 function handle_iq(context, event) |
| 66 local stanza = event.stanza; | 69 local stanza = event.stanza; |
| 67 local service = stanza.attr.from; | 70 local service = stanza.attr.from; |
| 68 | 71 |
| 69 if not stanza.attr.id then return end -- shouldn't be possible | 72 if not stanza.attr.id then return end -- shouldn't be possible |
| 73 if not stanza.attr.id:match("^pubsub%-sub%-") then return end | |
| 70 | 74 |
| 71 local subscribed_node = pending_subscription:get(stanza.attr.id); | 75 local subscribed_node = pending_subscription:get(stanza.attr.id); |
| 72 pending_subscription:set(stanza.attr.id, nil); | 76 pending_subscription:set(stanza.attr.id, nil); |
| 73 local unsubscribed_node = pending_unsubscription:get(stanza.attr.id); | 77 local unsubscribed_node = pending_unsubscription:get(stanza.attr.id); |
| 74 pending_unsubscription:set(stanza.attr.id, nil); | 78 pending_unsubscription:set(stanza.attr.id, nil); |
| 116 local item = item_event.item; | 120 local item = item_event.item; |
| 117 active_subscriptions:set(item.service, item.node, item.from, item._id, nil); | 121 active_subscriptions:set(item.service, item.node, item.from, item._id, nil); |
| 118 local node_subs = active_subscriptions:get(item.service, item.node, item.from); | 122 local node_subs = active_subscriptions:get(item.service, item.node, item.from); |
| 119 if node_subs and next(node_subs) then return end | 123 if node_subs and next(node_subs) then return end |
| 120 | 124 |
| 121 local iq_id = uuid.generate(); | 125 local iq_id = "pubsub-sub-"..id.short(); |
| 122 pending_unsubscription:set(iq_id, item._id); | 126 pending_unsubscription:set(iq_id, item._id); |
| 123 | 127 |
| 124 module:send(st.iq({ type = "set", id = iq_id, from = item.from, to = item.service }) | 128 module:send(st.iq({ type = "set", id = iq_id, from = item.from, to = item.service }) |
| 125 :tag("pubsub", { xmlns = xmlns_pubsub }) | 129 :tag("pubsub", { xmlns = xmlns_pubsub }) |
| 126 :tag("unsubscribe", { jid = item.from, node = item.node })) | 130 :tag("unsubscribe", { jid = item.from, node = item.node })) |
| 128 | 132 |
| 129 module:handle_items("pubsub-subscription", subscription_added, subscription_removed, true); | 133 module:handle_items("pubsub-subscription", subscription_added, subscription_removed, true); |
| 130 | 134 |
| 131 function handle_message(context, event) | 135 function handle_message(context, event) |
| 132 local origin, stanza = event.origin, event.stanza; | 136 local origin, stanza = event.origin, event.stanza; |
| 133 local ret = nil; | 137 local handled = nil; |
| 134 local service = stanza.attr.from; | 138 local service = stanza.attr.from; |
| 135 module:log("debug", "Got message/%s: %s", context, stanza:top_tag()); | 139 module:log("debug", "Got message/%s: %s", context, stanza:top_tag()); |
| 136 for event_container in stanza:childtags("event", xmlns_pubsub_event) do | 140 for event_container in stanza:childtags("event", xmlns_pubsub_event) do |
| 137 for pubsub_event in event_container:childtags() do | 141 for pubsub_event in event_container:childtags() do |
| 138 module:log("debug", "Got pubsub event %s", pubsub_event:top_tag()); | 142 module:log("debug", "Got pubsub event %s", pubsub_event:top_tag()); |
| 139 local node = pubsub_event.attr.node; | 143 local node = pubsub_event.attr.node; |
| 140 module:fire_event("pubsub-event/" .. context .. "/"..pubsub_event.name, { | 144 local event_data = { |
| 141 stanza = stanza; | 145 stanza = stanza; |
| 142 origin = origin; | 146 origin = origin; |
| 143 event = pubsub_event; | 147 event = pubsub_event; |
| 144 service = service; | 148 service = service; |
| 145 node = node; | 149 node = node; |
| 146 }); | 150 handled = false; |
| 147 ret = true; | 151 }; |
| 152 module:fire_event("pubsub-event/" .. context .. "/"..pubsub_event.name, event_data); | |
| 153 if not handled and event_data.handled then | |
| 154 handled = true; | |
| 155 end | |
| 148 end | 156 end |
| 149 end | 157 end |
| 150 return ret; | 158 -- If not addressed to the host, let it fall through to normal handling |
| 159 -- (it may be on its way to a local client), otherwise, we'll mark the | |
| 160 -- event as handled to suppress an error response if we handled it. | |
| 161 if context == "host" and handled then | |
| 162 return true; | |
| 163 end | |
| 151 end | 164 end |
| 152 | 165 |
| 153 module:hook("message/host", function(event) | 166 module:hook("message/host", function(event) |
| 154 return handle_message("host", event); | 167 return handle_message("host", event); |
| 155 end); | 168 end); |
