Mercurial > prosody-modules
comparison mod_smacks/mod_smacks.lua @ 3935:c49fea05772e
mod_smacks: handle mam-enabled session internally
This obsoletes mod_smacks_offline and supersedes mod_smacks_noerror with mod_smacks_nooffline_noerror
author | tmolitor <thilo@eightysoft.de> |
---|---|
date | Sun, 08 Mar 2020 19:49:47 +0100 |
parents | b5d367798570 |
children | e93e58b33bf6 |
comparison
equal
deleted
inserted
replaced
3928:7e7ac4af6e0c | 3935:c49fea05772e |
---|---|
43 local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10); | 43 local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10); |
44 local core_process_stanza = prosody.core_process_stanza; | 44 local core_process_stanza = prosody.core_process_stanza; |
45 local sessionmanager = require"core.sessionmanager"; | 45 local sessionmanager = require"core.sessionmanager"; |
46 | 46 |
47 assert(max_hibernated_sessions > 0, "smacks_max_hibernated_sessions must be greater than 0"); | 47 assert(max_hibernated_sessions > 0, "smacks_max_hibernated_sessions must be greater than 0"); |
48 assert(max_old_sessions > 0, "smacks_old_sessions must be greater than 0"); | 48 assert(max_old_sessions > 0, "smacks_max_old_sessions must be greater than 0"); |
49 | 49 |
50 local c2s_sessions = module:shared("/*/c2s/sessions"); | 50 local c2s_sessions = module:shared("/*/c2s/sessions"); |
51 | 51 |
52 local function init_session_cache(max_entries, evict_callback) | 52 local function init_session_cache(max_entries, evict_callback) |
53 -- old prosody version < 0.10 (no limiting at all!) | 53 -- old prosody version < 0.10 (no limiting at all!) |
108 if stopped then return; end | 108 if stopped then return; end |
109 return callback(t); | 109 return callback(t); |
110 end); | 110 end); |
111 if timer and timer.stop then return timer; end -- new prosody api includes stop() function | 111 if timer and timer.stop then return timer; end -- new prosody api includes stop() function |
112 return { | 112 return { |
113 stop = function () stopped = true end; | 113 stop = function(self) stopped = true end; |
114 timer; | 114 timer; |
115 }; | 115 }; |
116 end | 116 end |
117 | 117 |
118 local function delayed_ack_function(session) | 118 local function delayed_ack_function(session) |
391 --TODO: Optimise... incoming stanzas should be handled by a per-session | 391 --TODO: Optimise... incoming stanzas should be handled by a per-session |
392 -- function that has a counter as an upvalue (no table indexing for increments, | 392 -- function that has a counter as an upvalue (no table indexing for increments, |
393 -- and won't slow non-198 sessions). We can also then remove the .handled flag | 393 -- and won't slow non-198 sessions). We can also then remove the .handled flag |
394 -- on stanzas | 394 -- on stanzas |
395 | 395 |
396 function handle_unacked_stanzas(session) | 396 local function handle_unacked_stanzas(session) |
397 local queue = session.outgoing_stanza_queue; | 397 local queue = session.outgoing_stanza_queue; |
398 local error_attr = { type = "cancel" }; | 398 local error_attr = { type = "cancel" }; |
399 if #queue > 0 then | 399 if #queue > 0 then |
400 session.outgoing_stanza_queue = {}; | 400 session.outgoing_stanza_queue = {}; |
401 for i=1,#queue do | 401 for i=1,#queue do |
409 end | 409 end |
410 end | 410 end |
411 end | 411 end |
412 end | 412 end |
413 end | 413 end |
414 | |
415 -- don't send delivery errors for messages which will be delivered by mam later on | |
416 module:hook("delivery/failure", function(event) | |
417 local session, stanza = event.session, event.stanza; | |
418 -- Only deal with authenticated (c2s) sessions | |
419 if session.username then | |
420 if stanza.name == "message" and stanza.attr.xmlns == nil and | |
421 ( stanza.attr.type == "chat" or ( stanza.attr.type or "normal" ) == "normal" ) then | |
422 -- do nothing here for normal messages and don't send out "message delivery errors", | |
423 -- because messages are already in MAM at this point (no need to frighten users) | |
424 if session.mam_requested and stanza._was_archived then | |
425 return true; -- stanza handled, don't send an error | |
426 end | |
427 -- store message in offline store, if this client does not use mam *and* was the last client online | |
428 local sessions = prosody.hosts[module.host].sessions[session.username] and | |
429 prosody.hosts[module.host].sessions[session.username].sessions or nil; | |
430 if sessions and next(sessions) == session.resource and next(sessions, session.resource) == nil then | |
431 module:fire_event("message/offline/handle", { origin = session, stanza = stanza } ); | |
432 return true; -- stanza handled, don't send an error | |
433 end | |
434 end | |
435 end | |
436 end); | |
437 | |
438 -- mark stanzas as archived --> this will allow us to send back errors for stanzas not archived | |
439 -- because the user configured the server to do so ("no-archive"-setting for one special contact for example) | |
440 module:hook("archive-message-added", function(event) | |
441 local session, stanza, for_user, stanza_id = event.origin, event.stanza, event.for_user, event.id; | |
442 if session then session.log("debug", "Marking stanza as archived, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end | |
443 if not session then module:log("debug", "Marking stanza as archived in unknown session, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end | |
444 stanza._was_archived = true; | |
445 end); | |
414 | 446 |
415 module:hook("pre-resource-unbind", function (event) | 447 module:hook("pre-resource-unbind", function (event) |
416 local session, err = event.session, event.error; | 448 local session, err = event.session, event.error; |
417 if session.smacks then | 449 if session.smacks then |
418 if not session.resumption_token then | 450 if not session.resumption_token then |
529 original_session.log("debug", "mod_smacks closing an old connection for this session"); | 561 original_session.log("debug", "mod_smacks closing an old connection for this session"); |
530 local conn = original_session.conn; | 562 local conn = original_session.conn; |
531 c2s_sessions[conn] = nil; | 563 c2s_sessions[conn] = nil; |
532 conn:close(); | 564 conn:close(); |
533 end | 565 end |
566 local migrated_session_log = session.log; | |
534 original_session.ip = session.ip; | 567 original_session.ip = session.ip; |
535 original_session.conn = session.conn; | 568 original_session.conn = session.conn; |
536 original_session.send = session.send; | 569 original_session.send = session.send; |
537 original_session.close = session.close; | 570 original_session.close = session.close; |
538 original_session.filter = session.filter; | 571 original_session.filter = session.filter; |
563 local queue = original_session.outgoing_stanza_queue; | 596 local queue = original_session.outgoing_stanza_queue; |
564 session.log("debug", "resending all unacked stanzas that are still queued after resume, #queue = %d", #queue); | 597 session.log("debug", "resending all unacked stanzas that are still queued after resume, #queue = %d", #queue); |
565 for i=1,#queue do | 598 for i=1,#queue do |
566 session.send(queue[i]); | 599 session.send(queue[i]); |
567 end | 600 end |
568 session.log("debug", "all stanzas resent, now disabling send() in this session, #queue = %d", #queue); | 601 session.log("debug", "all stanzas resent, now disabling send() in this migrated session, #queue = %d", #queue); |
569 function session.send(stanza) | 602 function session.send(stanza) |
570 session.log("warn", "Tried to send stanza on old session migrated by smacks resume (maybe there is a bug?): %s", tostring(stanza)); | 603 migrated_session_log("error", "Tried to send stanza on old session migrated by smacks resume (maybe there is a bug?): %s", tostring(stanza)); |
571 return false; | 604 return false; |
572 end | 605 end |
573 module:fire_event("smacks-hibernation-end", {origin = session, resumed = original_session, queue = queue}); | 606 module:fire_event("smacks-hibernation-end", {origin = session, resumed = original_session, queue = queue}); |
574 request_ack_if_needed(original_session, true, "handle_resume"); | 607 request_ack_if_needed(original_session, true, "handle_resume"); |
575 else | 608 else |