Mercurial > prosody-modules
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 |