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);