Software /
code /
prosody
Comparison
plugins/mod_bosh.lua @ 7651:55f11a6806bc
mod_bosh: Correctly handle requests arriving out of order (thanks Jitsi folk!)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 02 Sep 2016 21:57:22 +0100 |
parent | 7387:addd041342bd |
child | 7652:7cc3d6c764ce |
comparison
equal
deleted
inserted
replaced
7648:d91ef1e6afc2 | 7651:55f11a6806bc |
---|---|
347 end | 347 end |
348 | 348 |
349 if session.rid then | 349 if session.rid then |
350 local rid = tonumber(attr.rid); | 350 local rid = tonumber(attr.rid); |
351 local diff = rid - session.rid; | 351 local diff = rid - session.rid; |
352 if diff > 1 then | 352 -- Diff should be 1 for a healthy request |
353 session.log("warn", "rid too large (means a request was lost). Last rid: %d New rid: %s", session.rid, attr.rid); | 353 if diff ~= 1 then |
354 elseif diff <= 0 then | 354 context.sid = sid; |
355 -- Repeated, ignore | |
356 session.log("debug", "rid repeated, ignoring: %s (diff %d)", session.rid, diff); | |
357 context.notopen = nil; | 355 context.notopen = nil; |
356 if diff == 2 then | |
357 -- Hold request, but don't process it (ouch!) | |
358 session.log("debug", "rid skipped: %d, deferring this request", rid-1) | |
359 context.defer = true; | |
360 session.bosh_deferred = { context = context, sid = sid, rid = rid, terminate = attr.type == "terminate" }; | |
361 return; | |
362 end | |
358 context.ignore = true; | 363 context.ignore = true; |
359 context.sid = sid; | 364 if diff == 0 then |
360 t_insert(session.requests, response); | 365 -- Re-send previous response, ignore stanzas in this request |
366 session.log("debug", "rid repeated, ignoring: %s (diff %d)", session.rid, diff); | |
367 response:send(session.bosh_last_response); | |
368 return; | |
369 end | |
370 -- Session broken, destroy it | |
371 session.log("debug", "rid out of range: %d (diff %d)", rid, diff); | |
372 response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); | |
361 return; | 373 return; |
362 end | 374 end |
363 session.rid = rid; | 375 session.rid = rid; |
364 end | 376 end |
365 | 377 |
389 local session = sessions[context.sid]; | 401 local session = sessions[context.sid]; |
390 if session then | 402 if session then |
391 if stanza.attr.xmlns == xmlns_bosh then | 403 if stanza.attr.xmlns == xmlns_bosh then |
392 stanza.attr.xmlns = nil; | 404 stanza.attr.xmlns = nil; |
393 end | 405 end |
394 stanza = session.filter("stanzas/in", stanza); | 406 if context.defer and session.bosh_deferred then |
395 if stanza then | 407 log("debug", "Deferring this stanza"); |
396 return xpcall(function () return core_process_stanza(session, stanza) end, handleerr); | 408 t_insert(session.bosh_deferred, stanza); |
409 else | |
410 stanza = session.filter("stanzas/in", stanza); | |
411 if stanza then | |
412 return xpcall(function () return core_process_stanza(session, stanza) end, handleerr); | |
413 end | |
397 end | 414 end |
398 end | 415 end |
399 end | 416 end |
400 | 417 |
401 function stream_callbacks.streamclosed(context) | 418 function stream_callbacks.streamclosed(context) |
402 local session = sessions[context.sid]; | 419 local session = sessions[context.sid]; |
403 if session then | 420 if session then |
421 if not context.defer and session.bosh_deferred then | |
422 -- Handle deferred stanzas now | |
423 local deferred_stanzas = session.bosh_deferred; | |
424 local context = deferred_stanzas.context; | |
425 session.bosh_deferred = nil; | |
426 log("debug", "Handling deferred stanzas from rid %d", deferred_stanzas.rid); | |
427 session.rid = deferred_stanzas.rid; | |
428 t_insert(session.requests, context.response); | |
429 for _, stanza in ipairs(deferred_stanzas) do | |
430 stream_callbacks.handlestanza(context, stanza); | |
431 end | |
432 if deferred_stanzas.terminate then | |
433 session.bosh_terminate = true; | |
434 end | |
435 end | |
404 session.bosh_processing = false; | 436 session.bosh_processing = false; |
405 if #session.send_buffer > 0 then | 437 if #session.send_buffer > 0 then |
406 session.send(""); | 438 session.send(""); |
407 end | 439 end |
408 end | 440 end |