Mercurial > prosody-hg
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 |
| parents | d35b181a895a |
| children | 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); |
