Software /
code /
prosody
Comparison
plugins/mod_bosh.lua @ 5776:bd0ff8ae98a8
Remove all trailing whitespace
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Fri, 09 Aug 2013 17:48:21 +0200 |
parent | 5748:cef2a1122b43 |
child | 6528:f0687c313cf1 |
comparison
equal
deleted
inserted
replaced
5775:a6c2b8933507 | 5776:bd0ff8ae98a8 |
---|---|
76 if r == request then | 76 if r == request then |
77 t_remove(requests, i); | 77 t_remove(requests, i); |
78 break; | 78 break; |
79 end | 79 end |
80 end | 80 end |
81 | 81 |
82 -- If this session now has no requests open, mark it as inactive | 82 -- If this session now has no requests open, mark it as inactive |
83 local max_inactive = session.bosh_max_inactive; | 83 local max_inactive = session.bosh_max_inactive; |
84 if max_inactive and #requests == 0 then | 84 if max_inactive and #requests == 0 then |
85 inactive_sessions[session] = os_time() + max_inactive; | 85 inactive_sessions[session] = os_time() + max_inactive; |
86 (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive); | 86 (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive); |
119 headers.content_type = "text/xml; charset=utf-8"; | 119 headers.content_type = "text/xml; charset=utf-8"; |
120 | 120 |
121 if cross_domain and event.request.headers.origin then | 121 if cross_domain and event.request.headers.origin then |
122 set_cross_domain_headers(response); | 122 set_cross_domain_headers(response); |
123 end | 123 end |
124 | 124 |
125 -- stream:feed() calls the stream_callbacks, so all stanzas in | 125 -- stream:feed() calls the stream_callbacks, so all stanzas in |
126 -- the body are processed in this next line before it returns. | 126 -- the body are processed in this next line before it returns. |
127 -- In particular, the streamopened() stream callback is where | 127 -- In particular, the streamopened() stream callback is where |
128 -- much of the session logic happens, because it's where we first | 128 -- much of the session logic happens, because it's where we first |
129 -- get to see the 'sid' of this request. | 129 -- get to see the 'sid' of this request. |
130 if not stream:feed(body) then | 130 if not stream:feed(body) then |
131 module:log("warn", "Error parsing BOSH payload") | 131 module:log("warn", "Error parsing BOSH payload") |
132 return 400; | 132 return 400; |
133 end | 133 end |
134 | 134 |
135 -- Stanzas (if any) in the request have now been processed, and | 135 -- Stanzas (if any) in the request have now been processed, and |
136 -- we take care of the high-level BOSH logic here, including | 136 -- we take care of the high-level BOSH logic here, including |
137 -- giving a response or putting the request "on hold". | 137 -- giving a response or putting the request "on hold". |
138 local session = sessions[context.sid]; | 138 local session = sessions[context.sid]; |
139 if session then | 139 if session then |
162 log("debug", "Session has data in the send buffer, will send now.."); | 162 log("debug", "Session has data in the send buffer, will send now.."); |
163 local resp = t_concat(session.send_buffer); | 163 local resp = t_concat(session.send_buffer); |
164 session.send_buffer = {}; | 164 session.send_buffer = {}; |
165 session.send(resp); | 165 session.send(resp); |
166 end | 166 end |
167 | 167 |
168 if not response.finished then | 168 if not response.finished then |
169 -- We're keeping this request open, to respond later | 169 -- We're keeping this request open, to respond later |
170 log("debug", "Have nothing to say, so leaving request unanswered for now"); | 170 log("debug", "Have nothing to say, so leaving request unanswered for now"); |
171 if session.bosh_wait then | 171 if session.bosh_wait then |
172 waiting_requests[response] = os_time() + session.bosh_wait; | 172 waiting_requests[response] = os_time() + session.bosh_wait; |
173 end | 173 end |
174 end | 174 end |
175 | 175 |
176 if session.bosh_terminate then | 176 if session.bosh_terminate then |
177 session.log("debug", "Closing session with %d requests open", #session.requests); | 177 session.log("debug", "Closing session with %d requests open", #session.requests); |
178 session:close(); | 178 session:close(); |
179 return nil; | 179 return nil; |
180 else | 180 else |
190 | 190 |
191 local stream_xmlns_attr = { xmlns = "urn:ietf:params:xml:ns:xmpp-streams" }; | 191 local stream_xmlns_attr = { xmlns = "urn:ietf:params:xml:ns:xmpp-streams" }; |
192 | 192 |
193 local function bosh_close_stream(session, reason) | 193 local function bosh_close_stream(session, reason) |
194 (session.log or log)("info", "BOSH client disconnected"); | 194 (session.log or log)("info", "BOSH client disconnected"); |
195 | 195 |
196 local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", | 196 local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", |
197 ["xmlns:stream"] = xmlns_streams }); | 197 ["xmlns:stream"] = xmlns_streams }); |
198 | 198 |
199 | 199 |
200 if reason then | 200 if reason then |
201 close_reply.attr.condition = "remote-stream-error"; | 201 close_reply.attr.condition = "remote-stream-error"; |
202 if type(reason) == "string" then -- assume stream error | 202 if type(reason) == "string" then -- assume stream error |
203 close_reply:tag("stream:error") | 203 close_reply:tag("stream:error") |
234 local sid = attr.sid; | 234 local sid = attr.sid; |
235 log("debug", "BOSH body open (sid: %s)", sid or "<none>"); | 235 log("debug", "BOSH body open (sid: %s)", sid or "<none>"); |
236 if not sid then | 236 if not sid then |
237 -- New session request | 237 -- New session request |
238 context.notopen = nil; -- Signals that we accept this opening tag | 238 context.notopen = nil; -- Signals that we accept this opening tag |
239 | 239 |
240 -- TODO: Sanity checks here (rid, to, known host, etc.) | 240 -- TODO: Sanity checks here (rid, to, known host, etc.) |
241 if not hosts[attr.to] then | 241 if not hosts[attr.to] then |
242 -- Unknown host | 242 -- Unknown host |
243 log("debug", "BOSH client tried to connect to unknown host: %s", tostring(attr.to)); | 243 log("debug", "BOSH client tried to connect to unknown host: %s", tostring(attr.to)); |
244 local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", | 244 local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", |
245 ["xmlns:stream"] = xmlns_streams, condition = "host-unknown" }); | 245 ["xmlns:stream"] = xmlns_streams, condition = "host-unknown" }); |
246 response:send(tostring(close_reply)); | 246 response:send(tostring(close_reply)); |
247 return; | 247 return; |
248 end | 248 end |
249 | 249 |
250 -- New session | 250 -- New session |
251 sid = new_uuid(); | 251 sid = new_uuid(); |
252 local session = { | 252 local session = { |
253 type = "c2s_unauthed", conn = {}, sid = sid, rid = tonumber(attr.rid)-1, host = attr.to, | 253 type = "c2s_unauthed", conn = {}, sid = sid, rid = tonumber(attr.rid)-1, host = attr.to, |
254 bosh_version = attr.ver, bosh_wait = math_min(attr.wait, bosh_max_wait), streamid = sid, | 254 bosh_version = attr.ver, bosh_wait = math_min(attr.wait, bosh_max_wait), streamid = sid, |
257 close = bosh_close_stream, dispatch_stanza = core_process_stanza, notopen = true, | 257 close = bosh_close_stream, dispatch_stanza = core_process_stanza, notopen = true, |
258 log = logger.init("bosh"..sid), secure = consider_bosh_secure or request.secure, | 258 log = logger.init("bosh"..sid), secure = consider_bosh_secure or request.secure, |
259 ip = get_ip_from_request(request); | 259 ip = get_ip_from_request(request); |
260 }; | 260 }; |
261 sessions[sid] = session; | 261 sessions[sid] = session; |
262 | 262 |
263 local filter = initialize_filters(session); | 263 local filter = initialize_filters(session); |
264 | 264 |
265 session.log("debug", "BOSH session created for request from %s", session.ip); | 265 session.log("debug", "BOSH session created for request from %s", session.ip); |
266 log("info", "New BOSH session, assigned it sid '%s'", sid); | 266 log("info", "New BOSH session, assigned it sid '%s'", sid); |
267 | 267 |
268 -- Send creation response | 268 -- Send creation response |
269 local creating_session = true; | 269 local creating_session = true; |
306 end | 306 end |
307 return true; | 307 return true; |
308 end | 308 end |
309 request.sid = sid; | 309 request.sid = sid; |
310 end | 310 end |
311 | 311 |
312 local session = sessions[sid]; | 312 local session = sessions[sid]; |
313 if not session then | 313 if not session then |
314 -- Unknown sid | 314 -- Unknown sid |
315 log("info", "Client tried to use sid '%s' which we don't know about", sid); | 315 log("info", "Client tried to use sid '%s' which we don't know about", sid); |
316 response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); | 316 response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); |
317 context.notopen = nil; | 317 context.notopen = nil; |
318 return; | 318 return; |
319 end | 319 end |
320 | 320 |
321 if session.rid then | 321 if session.rid then |
322 local rid = tonumber(attr.rid); | 322 local rid = tonumber(attr.rid); |
323 local diff = rid - session.rid; | 323 local diff = rid - session.rid; |
324 if diff > 1 then | 324 if diff > 1 then |
325 session.log("warn", "rid too large (means a request was lost). Last rid: %d New rid: %s", session.rid, attr.rid); | 325 session.log("warn", "rid too large (means a request was lost). Last rid: %d New rid: %s", session.rid, attr.rid); |
332 t_insert(session.requests, response); | 332 t_insert(session.requests, response); |
333 return; | 333 return; |
334 end | 334 end |
335 session.rid = rid; | 335 session.rid = rid; |
336 end | 336 end |
337 | 337 |
338 if attr.type == "terminate" then | 338 if attr.type == "terminate" then |
339 -- Client wants to end this session, which we'll do | 339 -- Client wants to end this session, which we'll do |
340 -- after processing any stanzas in this request | 340 -- after processing any stanzas in this request |
341 session.bosh_terminate = true; | 341 session.bosh_terminate = true; |
342 end | 342 end |
386 local response = context.response; | 386 local response = context.response; |
387 response.status_code = 400; | 387 response.status_code = 400; |
388 response:send(); | 388 response:send(); |
389 return; | 389 return; |
390 end | 390 end |
391 | 391 |
392 local session = sessions[context.sid]; | 392 local session = sessions[context.sid]; |
393 if error == "stream-error" then -- Remote stream error, we close normally | 393 if error == "stream-error" then -- Remote stream error, we close normally |
394 session:close(); | 394 session:close(); |
395 else | 395 else |
396 session:close({ condition = "bad-format", text = "Error processing stream" }); | 396 session:close({ condition = "bad-format", text = "Error processing stream" }); |
410 if request.conn then | 410 if request.conn then |
411 sessions[request.context.sid].send(""); | 411 sessions[request.context.sid].send(""); |
412 end | 412 end |
413 end | 413 end |
414 end | 414 end |
415 | 415 |
416 now = now - 3; | 416 now = now - 3; |
417 local n_dead_sessions = 0; | 417 local n_dead_sessions = 0; |
418 for session, close_after in pairs(inactive_sessions) do | 418 for session, close_after in pairs(inactive_sessions) do |
419 if close_after < now then | 419 if close_after < now then |
420 (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now); | 420 (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now); |