Mercurial > prosody-hg
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; |
