comparison plugins/mod_cloud_notify.lua @ 14134:041c7ff18f76 13.0

mod_cloud_notify: Fix leaking iq response handlers by using send_iq()
author Matthew Wild <mwild1@gmail.com>
date Thu, 16 Apr 2026 18:55:53 +0100
parents 1aa7efabeacb
children f149652cb5ff
comparison
equal deleted inserted replaced
14133:4087c5b600b1 14134:041c7ff18f76
72 72
73 73
74 -- Forward declarations, as both functions need to reference each other 74 -- Forward declarations, as both functions need to reference each other
75 local handle_push_success, handle_push_error; 75 local handle_push_success, handle_push_error;
76 76
77 function handle_push_error(event) 77 function handle_push_error(stanza)
78 local stanza = event.stanza;
79 local error_type, condition, error_text = stanza:get_error(); 78 local error_type, condition, error_text = stanza:get_error();
80 local node = id2node[stanza.attr.id]; 79 local node = id2node[stanza.attr.id];
81 local identifier = id2identifier[stanza.attr.id]; 80 local identifier = id2identifier[stanza.attr.id];
82 if node == nil then 81 if node == nil then
83 module:log("warn", "Received push error with unrecognised id: %s", stanza.attr.id); 82 module:log("warn", "Received push error with unrecognised id: %s", stanza.attr.id);
115 end 114 end
116 -- save changed global config 115 -- save changed global config
117 changed = true; 116 changed = true;
118 user_push_services[push_identifier] = nil 117 user_push_services[push_identifier] = nil
119 push_errors[push_identifier] = nil; 118 push_errors[push_identifier] = nil;
120 -- unhook iq handlers for this identifier (if possible)
121 module:unhook("iq-error/host/"..stanza.attr.id, handle_push_error);
122 module:unhook("iq-result/host/"..stanza.attr.id, handle_push_success);
123 id2node[stanza.attr.id] = nil;
124 id2identifier[stanza.attr.id] = nil;
125 end 119 end
126 elseif user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type == "wait" then 120 elseif user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and error_type == "wait" then
127 module:log("debug", "Got error <%s:%s:%s> for identifier '%s': " 121 module:log("debug", "Got error <%s:%s:%s> for identifier '%s': "
128 .."NOT increasing error count for this identifier", error_type, condition, error_text or "", push_identifier); 122 .."NOT increasing error count for this identifier", error_type, condition, error_text or "", push_identifier);
129 else 123 else
139 module:log("warn", "Unable to find matching registration for push error <%s:%s:%s> from %s", error_type, condition, error_text or "", from); 133 module:log("warn", "Unable to find matching registration for push error <%s:%s:%s> from %s", error_type, condition, error_text or "", from);
140 end 134 end
141 return true; 135 return true;
142 end 136 end
143 137
144 function handle_push_success(event) 138 function handle_push_success(stanza)
145 local stanza = event.stanza;
146 local node = id2node[stanza.attr.id]; 139 local node = id2node[stanza.attr.id];
147 local identifier = id2identifier[stanza.attr.id]; 140 local identifier = id2identifier[stanza.attr.id];
148 if node == nil then return false; end -- unknown stanza? Ignore for now! 141 if node == nil then return false; end -- unknown stanza? Ignore for now!
149 local from = stanza.attr.from; 142 local from = stanza.attr.from;
150 local user_push_services = push_store:get(node); 143 local user_push_services = push_store:get(node);
151 144
152 for push_identifier, _ in pairs(user_push_services) do 145 for push_identifier, _ in pairs(user_push_services) do
153 if push_identifier == identifier then 146 if push_identifier == identifier then
154 if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and push_errors[push_identifier] > 0 then 147 if user_push_services[push_identifier] and user_push_services[push_identifier].jid == from and push_errors[push_identifier] > 0 then
155 push_errors[push_identifier] = 0; 148 push_errors[push_identifier] = 0;
156 -- unhook iq handlers for this identifier (if possible)
157 module:unhook("iq-error/host/"..stanza.attr.id, handle_push_error);
158 module:unhook("iq-result/host/"..stanza.attr.id, handle_push_success);
159 id2node[stanza.attr.id] = nil;
160 id2identifier[stanza.attr.id] = nil;
161 module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s again", 149 module:log("debug", "Push succeeded, error count for identifier '%s' is now at %s again",
162 push_identifier, tostring(push_errors[push_identifier]) 150 push_identifier, tostring(push_errors[push_identifier])
163 ); 151 );
164 end 152 end
165 end 153 end
255 origin.hibernating_watchdog = watchdog.new(origin.original_smacks_timeout, origin.original_smacks_callback); 243 origin.hibernating_watchdog = watchdog.new(origin.original_smacks_timeout, origin.original_smacks_callback);
256 end 244 end
257 end 245 end
258 user_push_services[key] = nil; 246 user_push_services[key] = nil;
259 push_errors[key] = nil; 247 push_errors[key] = nil;
260 for stanza_id, identifier in pairs(id2identifier) do
261 if identifier == key then
262 module:unhook("iq-error/host/"..stanza_id, handle_push_error);
263 module:unhook("iq-result/host/"..stanza_id, handle_push_success);
264 id2node[stanza_id] = nil;
265 id2identifier[stanza_id] = nil;
266 end
267 end
268 end 248 end
269 end 249 end
270 local ok = push_store:flush_to_disk(origin.username); 250 local ok = push_store:flush_to_disk(origin.username);
271 if not ok then 251 if not ok then
272 origin.send(st.error_reply(stanza, "wait", "internal-server-error")); 252 origin.send(st.error_reply(stanza, "wait", "internal-server-error"));
411 else 391 else
412 -- handle push errors for this node 392 -- handle push errors for this node
413 if push_errors[push_identifier] == nil then 393 if push_errors[push_identifier] == nil then
414 push_errors[push_identifier] = 0; 394 push_errors[push_identifier] = 0;
415 end 395 end
416 module:hook("iq-error/host/"..stanza_id, handle_push_error);
417 module:hook("iq-result/host/"..stanza_id, handle_push_success);
418 id2node[stanza_id] = node; 396 id2node[stanza_id] = node;
419 id2identifier[stanza_id] = push_identifier; 397 id2identifier[stanza_id] = push_identifier;
420 module:send(push_publish); 398 module:send_iq(push_publish):next(handle_push_success, handle_push_error):finally(function ()
399 -- unhook iq handlers for this identifier (if possible)
400 id2node[stanza.attr.id] = nil;
401 id2identifier[stanza.attr.id] = nil;
402 end);
421 pushes = pushes + 1; 403 pushes = pushes + 1;
422 end 404 end
423 end 405 end
424 end 406 end
425 return pushes; 407 return pushes;