comparison mod_carbons/mod_carbons.lua @ 833:30d49c26d219

mod_carbons: Optimize and clarify (thanks waqas)
author Kim Alvefur <zash@zash.se>
date Tue, 18 Sep 2012 21:05:41 +0200
parents 9087431d35f6
children 07cc1efde2f8
comparison
equal deleted inserted replaced
832:9087431d35f6 833:30d49c26d219
3 -- 3 --
4 -- This file is MIT/X11 licensed. 4 -- This file is MIT/X11 licensed.
5 5
6 local st = require "util.stanza"; 6 local st = require "util.stanza";
7 local jid_bare = require "util.jid".bare; 7 local jid_bare = require "util.jid".bare;
8 local jid_split = require "util.jid".split;
9 local xmlns_carbons = "urn:xmpp:carbons:1"; 8 local xmlns_carbons = "urn:xmpp:carbons:1";
10 local xmlns_forward = "urn:xmpp:forward:0"; 9 local xmlns_forward = "urn:xmpp:forward:0";
11 local host_sessions = hosts[module.host].sessions; 10 local host_sessions = hosts[module.host].sessions;
11 local full_sessions, bare_sessions = full_sessions, bare_sessions;
12 12
13 local function toggle_carbons(event) 13 local function toggle_carbons(event)
14 local origin, stanza = event.origin, event.stanza; 14 local origin, stanza = event.origin, event.stanza;
15 if stanza.attr.type == "set" then 15 if stanza.attr.type == "set" then
16 local state = stanza.tags[1].name; 16 local state = stanza.tags[1].name;
25 25
26 local function message_handler(event, c2s) 26 local function message_handler(event, c2s)
27 local origin, stanza = event.origin, event.stanza; 27 local origin, stanza = event.origin, event.stanza;
28 local orig_type = stanza.attr.type; 28 local orig_type = stanza.attr.type;
29 local orig_to = stanza.attr.to; 29 local orig_to = stanza.attr.to;
30 local orig_from = stanza.attr.from;
31 30
32 if not (orig_type == nil 31 if not (orig_type == nil
33 or orig_type == "normal" 32 or orig_type == "normal"
34 or orig_type == "chat") then 33 or orig_type == "chat") then
35 return -- No carbons for messages of type error or headline 34 return -- No carbons for messages of type error or headline
36 end 35 end
37 36
38 local bare_jid, user_sessions; 37 -- Stanza sent by a local client
39 local no_carbon_to = {}; 38 local bare_jid = origin.username .. "@" .. origin.host;
40 module:log("debug", "Message from %s to %s", tostring(orig_from), tostring(orig_to)); 39 local target_session = origin;
41 if c2s then -- Stanza sent by a local client 40 local top_priority = false;
42 bare_jid = (origin.username.."@"..origin.host) 41 local user_sessions = host_sessions[origin.username];
43 user_sessions = host_sessions[origin.username]; 42
44 else -- Stanza about to be delivered to a local client 43 -- Stanza about to be delivered to a local client
45 local username, hostname, resource = jid_split(orig_to); 44 if not c2s then
46 bare_jid = jid_bare(orig_to); 45 bare_jid = jid_bare(orig_to);
47 user_sessions = host_sessions[username]; 46 target_session = full_sessions[orig_to]
48 if resource then 47 user_sessions = bare_sessions[bare_jid];
49 module:log("debug", "Message was to resource %s, it will not get carbon", resource); 48 if not target_session and user_sessions then
50 no_carbon_to[resource] = true; 49 -- The top resources will already receive this message per normal routing rules,
51 elseif user_sessions then 50 -- so we are going to skip them in order to avoid sending duplicated messages.
52 local top_resources = user_sessions.top_resources; 51 local top_resources = user_sessions.top_resources;
53 if top_resources then 52 top_priority = top_resources and top_resources[1].priority
54 -- These will already receive this message per normal routing rules,
55 -- so we skip them to avoid duplicated messages.
56 for i=1,#top_resources do
57 local resource = top_resources[i].resource;
58 module:log("debug", "Not sending carbons to top resource %s", resource);
59 no_carbon_to[resource] = true;
60 end
61 end
62 end 53 end
63 end 54 end
64 55
65 if not user_sessions then 56 if not user_sessions then
66 module:log("debug", "Skip carbons for offline user"); 57 module:log("debug", "Skip carbons for offline user");
82 local carbon = st.message{ from = bare_jid, type = orig_type, } 73 local carbon = st.message{ from = bare_jid, type = orig_type, }
83 :tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up() 74 :tag(c2s and "sent" or "received", { xmlns = xmlns_carbons }):up()
84 :tag("forwarded", { xmlns = xmlns_forward }) 75 :tag("forwarded", { xmlns = xmlns_forward })
85 :add_child(copy):reset(); 76 :add_child(copy):reset();
86 77
87 -- And finally, send the carbon to the sessions that should have it.
88 user_sessions = user_sessions and user_sessions.sessions; 78 user_sessions = user_sessions and user_sessions.sessions;
89 for resource, session in pairs(user_sessions) do 79 for _, session in pairs(user_sessions) do
90 local full_jid = bare_jid .. "/" .. resource; 80 -- Carbons are sent to resources that have enabled it
91 if session.want_carbons and ((c2s and session ~= origin) or (not c2s and not no_carbon_to[resource])) then 81 if session.want_carbons
92 carbon.attr.to = full_jid; 82 -- but not the resource that sent the message, or the one that it's directed to
93 module:log("debug", "Sending carbon to %s", full_jid); 83 and session ~= target_session
84 -- and isn't among the top resources that would receive the message per standard routing rules
85 and (not c2s or session.priority ~= top_priority) then
86 carbon.attr.to = session.full_jid;
87 module:log("debug", "Sending carbon to %s", session.full_jid);
94 session.send(carbon); 88 session.send(carbon);
95 end 89 end
96 end 90 end
97 end 91 end
98 92