Software /
code /
prosody
Comparison
plugins/mod_presence.lua @ 3198:5a4e766a3577
mod_presence: Enable firing of pre-events for all outbound stanzas, and switching completely to core_post_stanza.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Tue, 08 Jun 2010 16:21:14 +0500 |
parent | 3196:d35b181a895a |
child | 3215:e55782f20679 |
comparison
equal
deleted
inserted
replaced
3197:f1db45e89317 | 3198:5a4e766a3577 |
---|---|
21 local NULL = {}; | 21 local NULL = {}; |
22 | 22 |
23 local rostermanager = require "core.rostermanager"; | 23 local rostermanager = require "core.rostermanager"; |
24 local sessionmanager = require "core.sessionmanager"; | 24 local sessionmanager = require "core.sessionmanager"; |
25 local offlinemanager = require "core.offlinemanager"; | 25 local offlinemanager = require "core.offlinemanager"; |
26 | |
27 local _core_route_stanza = core_route_stanza; | |
28 local core_route_stanza; | |
29 function core_route_stanza(origin, stanza) | |
30 if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" and stanza.attr.type ~= "error" then | |
31 local node, host = jid_split(stanza.attr.to); | |
32 host = hosts[host]; | |
33 if node and host and host.type == "local" then | |
34 handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to)); | |
35 return; | |
36 end | |
37 end | |
38 _core_route_stanza(origin, stanza); | |
39 end | |
40 | 26 |
41 local function select_top_resources(user) | 27 local function select_top_resources(user) |
42 local priority = 0; | 28 local priority = 0; |
43 local recipients = {}; | 29 local recipients = {}; |
44 for _, session in pairs(user.sessions) do -- find resource with greatest priority | 30 for _, session in pairs(user.sessions) do -- find resource with greatest priority |
80 local node, host = origin.username, origin.host; | 66 local node, host = origin.username, origin.host; |
81 local user = bare_sessions[node.."@"..host]; | 67 local user = bare_sessions[node.."@"..host]; |
82 for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources | 68 for _, res in pairs(user and user.sessions or NULL) do -- broadcast to all resources |
83 if res ~= origin and res.presence then -- to resource | 69 if res ~= origin and res.presence then -- to resource |
84 stanza.attr.to = res.full_jid; | 70 stanza.attr.to = res.full_jid; |
85 core_route_stanza(origin, stanza); | 71 core_post_stanza(origin, stanza, true); |
86 end | 72 end |
87 end | 73 end |
88 for jid, item in pairs(roster) do -- broadcast to all interested contacts | 74 for jid, item in pairs(roster) do -- broadcast to all interested contacts |
89 if item.subscription == "both" or item.subscription == "from" then | 75 if item.subscription == "both" or item.subscription == "from" then |
90 stanza.attr.to = jid; | 76 stanza.attr.to = jid; |
91 core_route_stanza(origin, stanza); | 77 core_post_stanza(origin, stanza, true); |
92 end | 78 end |
93 end | 79 end |
94 if stanza.attr.type == nil and not origin.presence then -- initial presence | 80 if stanza.attr.type == nil and not origin.presence then -- initial presence |
95 origin.presence = stanza; -- FIXME repeated later | 81 origin.presence = stanza; -- FIXME repeated later |
96 local probe = st.presence({from = origin.full_jid, type = "probe"}); | 82 local probe = st.presence({from = origin.full_jid, type = "probe"}); |
101 end | 87 end |
102 end | 88 end |
103 for _, res in pairs(user and user.sessions or NULL) do -- broadcast from all available resources | 89 for _, res in pairs(user and user.sessions or NULL) do -- broadcast from all available resources |
104 if res ~= origin and res.presence then | 90 if res ~= origin and res.presence then |
105 res.presence.attr.to = origin.full_jid; | 91 res.presence.attr.to = origin.full_jid; |
106 core_route_stanza(res, res.presence); | 92 core_post_stanza(res, res.presence, true); |
107 res.presence.attr.to = nil; | 93 res.presence.attr.to = nil; |
108 end | 94 end |
109 end | 95 end |
110 if roster.pending then -- resend incoming subscription requests | 96 if roster.pending then -- resend incoming subscription requests |
111 for jid in pairs(roster.pending) do | 97 for jid in pairs(roster.pending) do |
114 end | 100 end |
115 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); | 101 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); |
116 for jid, item in pairs(roster) do -- resend outgoing subscription requests | 102 for jid, item in pairs(roster) do -- resend outgoing subscription requests |
117 if item.ask then | 103 if item.ask then |
118 request.attr.to = jid; | 104 request.attr.to = jid; |
119 core_route_stanza(origin, request); | 105 core_post_stanza(origin, request, true); |
120 end | 106 end |
121 end | 107 end |
122 local offline = offlinemanager.load(node, host); | 108 local offline = offlinemanager.load(node, host); |
123 if offline then | 109 if offline then |
124 for _, msg in ipairs(offline) do | 110 for _, msg in ipairs(offline) do |
134 recalc_resource_map(user); | 120 recalc_resource_map(user); |
135 end | 121 end |
136 if origin.directed then | 122 if origin.directed then |
137 for jid in pairs(origin.directed) do | 123 for jid in pairs(origin.directed) do |
138 stanza.attr.to = jid; | 124 stanza.attr.to = jid; |
139 core_route_stanza(origin, stanza); | 125 core_post_stanza(origin, stanza, true); |
140 end | 126 end |
141 origin.directed = nil; | 127 origin.directed = nil; |
142 end | 128 end |
143 else | 129 else |
144 origin.presence = stanza; | 130 origin.presence = stanza; |
168 for k, session in pairs(u.sessions) do | 154 for k, session in pairs(u.sessions) do |
169 local pres = session.presence; | 155 local pres = session.presence; |
170 if pres then | 156 if pres then |
171 if stanza then pres = stanza; pres.attr.from = session.full_jid; end | 157 if stanza then pres = stanza; pres.attr.from = session.full_jid; end |
172 pres.attr.to = jid; | 158 pres.attr.to = jid; |
173 core_route_stanza(session, pres); | 159 core_post_stanza(session, pres, true); |
174 pres.attr.to = nil; | 160 pres.attr.to = nil; |
175 count = count + 1; | 161 count = count + 1; |
176 end | 162 end |
177 end | 163 end |
178 end | 164 end |
194 -- 1. route stanza | 180 -- 1. route stanza |
195 -- 2. roster push (subscription = none, ask = subscribe) | 181 -- 2. roster push (subscription = none, ask = subscribe) |
196 if rostermanager.set_contact_pending_out(node, host, to_bare) then | 182 if rostermanager.set_contact_pending_out(node, host, to_bare) then |
197 rostermanager.roster_push(node, host, to_bare); | 183 rostermanager.roster_push(node, host, to_bare); |
198 end -- else file error | 184 end -- else file error |
199 core_route_stanza(origin, stanza); | 185 core_post_stanza(origin, stanza); |
200 elseif stanza.attr.type == "unsubscribe" then | 186 elseif stanza.attr.type == "unsubscribe" then |
201 -- 1. route stanza | 187 -- 1. route stanza |
202 -- 2. roster push (subscription = none or from) | 188 -- 2. roster push (subscription = none or from) |
203 if rostermanager.unsubscribe(node, host, to_bare) then | 189 if rostermanager.unsubscribe(node, host, to_bare) then |
204 rostermanager.roster_push(node, host, to_bare); -- FIXME do roster push when roster has in fact not changed? | 190 rostermanager.roster_push(node, host, to_bare); -- FIXME do roster push when roster has in fact not changed? |
205 end -- else file error | 191 end -- else file error |
206 core_route_stanza(origin, stanza); | 192 core_post_stanza(origin, stanza); |
207 elseif stanza.attr.type == "subscribed" then | 193 elseif stanza.attr.type == "subscribed" then |
208 -- 1. route stanza | 194 -- 1. route stanza |
209 -- 2. roster_push () | 195 -- 2. roster_push () |
210 -- 3. send_presence_of_available_resources | 196 -- 3. send_presence_of_available_resources |
211 if rostermanager.subscribed(node, host, to_bare) then | 197 if rostermanager.subscribed(node, host, to_bare) then |
212 rostermanager.roster_push(node, host, to_bare); | 198 rostermanager.roster_push(node, host, to_bare); |
213 end | 199 end |
214 core_route_stanza(origin, stanza); | 200 core_post_stanza(origin, stanza); |
215 send_presence_of_available_resources(node, host, to_bare, origin); | 201 send_presence_of_available_resources(node, host, to_bare, origin); |
216 elseif stanza.attr.type == "unsubscribed" then | 202 elseif stanza.attr.type == "unsubscribed" then |
217 -- 1. route stanza | 203 -- 1. route stanza |
218 -- 2. roster push (subscription = none or to) | 204 -- 2. roster push (subscription = none or to) |
219 if rostermanager.unsubscribed(node, host, to_bare) then | 205 if rostermanager.unsubscribed(node, host, to_bare) then |
220 rostermanager.roster_push(node, host, to_bare); | 206 rostermanager.roster_push(node, host, to_bare); |
221 end | 207 end |
222 core_route_stanza(origin, stanza); | 208 core_post_stanza(origin, stanza); |
223 end | 209 end |
224 stanza.attr.from, stanza.attr.to = st_from, st_to; | 210 stanza.attr.from, stanza.attr.to = st_from, st_to; |
225 return true; | 211 return true; |
226 end | 212 end |
227 | 213 |
233 | 219 |
234 if stanza.attr.type == "probe" then | 220 if stanza.attr.type == "probe" then |
235 local result, err = rostermanager.is_contact_subscribed(node, host, from_bare); | 221 local result, err = rostermanager.is_contact_subscribed(node, host, from_bare); |
236 if result then | 222 if result then |
237 if 0 == send_presence_of_available_resources(node, host, st_from, origin) then | 223 if 0 == send_presence_of_available_resources(node, host, st_from, origin) then |
238 core_route_stanza(hosts[host], st.presence({from=to_bare, to=st_from, type="unavailable"})); -- TODO send last activity | 224 core_post_stanza(hosts[host], st.presence({from=to_bare, to=st_from, type="unavailable"}), true); -- TODO send last activity |
239 end | 225 end |
240 elseif not err then | 226 elseif not err then |
241 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"})); | 227 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unsubscribed"}), true); |
242 end | 228 end |
243 elseif stanza.attr.type == "subscribe" then | 229 elseif stanza.attr.type == "subscribe" then |
244 if rostermanager.is_contact_subscribed(node, host, from_bare) then | 230 if rostermanager.is_contact_subscribed(node, host, from_bare) then |
245 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"})); -- already subscribed | 231 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"}), true); -- already subscribed |
246 -- Sending presence is not clearly stated in the RFC, but it seems appropriate | 232 -- Sending presence is not clearly stated in the RFC, but it seems appropriate |
247 if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then | 233 if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then |
248 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- TODO send last activity | 234 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- TODO send last activity |
249 end | 235 end |
250 else | 236 else |
251 core_route_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"})); -- acknowledging receipt | 237 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- acknowledging receipt |
252 if not rostermanager.is_contact_pending_in(node, host, from_bare) then | 238 if not rostermanager.is_contact_pending_in(node, host, from_bare) then |
253 if rostermanager.set_contact_pending_in(node, host, from_bare) then | 239 if rostermanager.set_contact_pending_in(node, host, from_bare) then |
254 sessionmanager.send_to_available_resources(node, host, stanza); | 240 sessionmanager.send_to_available_resources(node, host, stanza); |
255 end -- TODO else return error, unable to save | 241 end -- TODO else return error, unable to save |
256 end | 242 end |
347 local origin, stanza = data.origin, data.stanza; | 333 local origin, stanza = data.origin, data.stanza; |
348 | 334 |
349 local from_bare = jid_bare(stanza.attr.from); | 335 local from_bare = jid_bare(stanza.attr.from); |
350 local t = stanza.attr.type; | 336 local t = stanza.attr.type; |
351 if t == "probe" then | 337 if t == "probe" then |
352 core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); | 338 core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
353 elseif t == "subscribe" then | 339 elseif t == "subscribe" then |
354 core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id, type = "subscribed" })); | 340 core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id, type = "subscribed" })); |
355 core_route_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); | 341 core_post_stanza(hosts[module.host], st.presence({ from = module.host, to = from_bare, id = stanza.attr.id })); |
356 end | 342 end |
357 return true; | 343 return true; |
358 end); | 344 end); |
359 | 345 |
360 module:hook("resource-unbind", function(event) | 346 module:hook("resource-unbind", function(event) |
369 local pres = st.presence{ type = "unavailable", from = session.full_jid }; | 355 local pres = st.presence{ type = "unavailable", from = session.full_jid }; |
370 if not(err) or err == "closed" then err = "connection closed"; end | 356 if not(err) or err == "closed" then err = "connection closed"; end |
371 pres:tag("status"):text("Disconnected: "..err):up(); | 357 pres:tag("status"):text("Disconnected: "..err):up(); |
372 for jid in pairs(session.directed) do | 358 for jid in pairs(session.directed) do |
373 pres.attr.to = jid; | 359 pres.attr.to = jid; |
374 core_route_stanza(session, pres); | 360 core_post_stanza(session, pres, true); |
375 end | 361 end |
376 session.directed = nil; | 362 session.directed = nil; |
377 end | 363 end |
378 end); | 364 end); |