359 |
359 |
360 function api:send(stanza, origin) |
360 function api:send(stanza, origin) |
361 return core_post_stanza(origin or hosts[self.host], stanza); |
361 return core_post_stanza(origin or hosts[self.host], stanza); |
362 end |
362 end |
363 |
363 |
|
364 function api:send_iq(stanza, origin, timeout) |
|
365 local iq_cache = self._iq_cache; |
|
366 if not iq_cache then |
|
367 iq_cache = require "util.cache".new(256, function (_, iq) |
|
368 iq.reject("evicted"); |
|
369 self:unhook(iq.result_event, iq.result_handler); |
|
370 self:unhook(iq.error_event, iq.error_handler); |
|
371 end); |
|
372 self._iq_cache = iq_cache; |
|
373 end |
|
374 return require "util.promise".new(function (resolve, reject) |
|
375 local event_type; |
|
376 if stanza.attr.from == self.host then |
|
377 event_type = "host"; |
|
378 else -- assume bare since we can't hook full jids |
|
379 event_type = "bare"; |
|
380 end |
|
381 local result_event = "iq-result/"..event_type.."/"..stanza.attr.id; |
|
382 local error_event = "iq-error/"..event_type.."/"..stanza.attr.id; |
|
383 local cache_key = event_type.."/"..stanza.attr.id; |
|
384 |
|
385 local function result_handler(event) |
|
386 if event.stanza.attr.from == stanza.attr.to then |
|
387 resolve(event); |
|
388 return true; |
|
389 end |
|
390 end |
|
391 |
|
392 local function error_handler(event) |
|
393 if event.stanza.attr.from == stanza.attr.to then |
|
394 reject(event); |
|
395 return true; |
|
396 end |
|
397 end |
|
398 |
|
399 if iq_cache:get(cache_key) then |
|
400 error("choose another iq stanza id attribute") |
|
401 end |
|
402 |
|
403 self:hook(result_event, result_handler); |
|
404 self:hook(error_event, error_handler); |
|
405 |
|
406 local timeout_handle = self:add_timer(timeout or 120, function () |
|
407 reject("timeout"); |
|
408 self:unhook(result_event, result_handler); |
|
409 self:unhook(error_event, error_handler); |
|
410 iq_cache:set(cache_key, nil); |
|
411 end); |
|
412 |
|
413 local ok = iq_cache:set(cache_key, { |
|
414 reject = reject, resolve = resolve, |
|
415 timeout_handle = timeout_handle, |
|
416 result_event = result_event, error_event = error_event, |
|
417 result_handler = result_handler, error_handler = error_handler; |
|
418 }); |
|
419 |
|
420 if not ok then |
|
421 reject("cache insertion failure"); |
|
422 return; |
|
423 end |
|
424 |
|
425 self:send(stanza, origin); |
|
426 end); |
|
427 end |
|
428 |
364 function api:broadcast(jids, stanza, iter) |
429 function api:broadcast(jids, stanza, iter) |
365 for jid in (iter or it.values)(jids) do |
430 for jid in (iter or it.values)(jids) do |
366 local new_stanza = st.clone(stanza); |
431 local new_stanza = st.clone(stanza); |
367 new_stanza.attr.to = jid; |
432 new_stanza.attr.to = jid; |
368 self:send(new_stanza); |
433 self:send(new_stanza); |