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 |
