Software /
code /
prosody-modules
Comparison
mod_rest/mod_rest.lua @ 4941:e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Makes MAM queries to remote hosts works.
As the comment says, MAM results from users' local archives or local
MUCs are returned via origin.send() which is provided in the event and
thus already worked. Results from remote hosts go via normal stanza
routing and events, which need this extra handling to catch.
This pattern of iq-set, message+, iq-result is generally limited to MAM.
Closest similar thing might be MUC join, but to really handle that you
would need the webhook callback mechanism.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 16 May 2022 19:47:09 +0200 |
parent | 4922:c83b009b5bc5 |
child | 4942:83a54f4af94c |
comparison
equal
deleted
inserted
replaced
4940:7406039021d8 | 4941:e7b9bc629ecc |
---|---|
65 username = id.medium():lower(); | 65 username = id.medium():lower(); |
66 host = module.host; | 66 host = module.host; |
67 } | 67 } |
68 end | 68 end |
69 end | 69 end |
70 | |
71 local function event_suffix(jid_to) | |
72 local node, _, resource = jid.split(jid_to); | |
73 if node then | |
74 if resource then | |
75 return '/full'; | |
76 else | |
77 return '/bare'; | |
78 end | |
79 else | |
80 return '/host'; | |
81 end | |
82 end | |
83 | |
70 | 84 |
71 -- TODO This ought to be handled some way other than duplicating this | 85 -- TODO This ought to be handled some way other than duplicating this |
72 -- core.stanza_router code here. | 86 -- core.stanza_router code here. |
73 local function compat_preevents(origin, stanza) --> boolean : handled | 87 local function compat_preevents(origin, stanza) --> boolean : handled |
74 local to = stanza.attr.to; | 88 local to = stanza.attr.to; |
354 return post_errors.new("iq_type"); | 368 return post_errors.new("iq_type"); |
355 elseif #payload.tags ~= 1 then | 369 elseif #payload.tags ~= 1 then |
356 return post_errors.new("iq_tags"); | 370 return post_errors.new("iq_tags"); |
357 end | 371 end |
358 | 372 |
359 return module:send_iq(payload, origin):next( | 373 -- special handling of multiple responses to MAM queries primarily from |
374 -- remote hosts, local go directly to origin.send() | |
375 local archive_event_name = "message"..event_suffix(from); | |
376 local archive_handler; | |
377 local archive_query = payload:get_child("query", "urn:xmpp:mam:2"); | |
378 if archive_query then | |
379 archive_handler = function(result_event) | |
380 if result_event.stanza:find("{urn:xmpp:mam:2}result/@queryid") == archive_query.attr.queryid then | |
381 origin.send(result_event.stanza); | |
382 return true; | |
383 end | |
384 end | |
385 module:hook(archive_event_name, archive_handler, 1); | |
386 end | |
387 | |
388 local p = module:send_iq(payload, origin):next( | |
360 function (result) | 389 function (result) |
361 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); | 390 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); |
362 response.headers.content_type = send_type; | 391 response.headers.content_type = send_type; |
363 if responses[2] then | 392 if responses[2] then |
364 return encode(send_type, responses); | 393 return encode(send_type, responses); |
375 return encode(send_type, error.context.stanza); | 404 return encode(send_type, error.context.stanza); |
376 else | 405 else |
377 return error; | 406 return error; |
378 end | 407 end |
379 end); | 408 end); |
409 | |
410 if archive_handler then | |
411 p:finally(function () | |
412 module:unhook(archive_event_name, archive_handler); | |
413 end) | |
414 end | |
415 | |
416 return p; | |
380 else | 417 else |
381 function origin.send(stanza) | 418 function origin.send(stanza) |
382 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); | 419 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
383 response.headers.content_type = send_type; | 420 response.headers.content_type = send_type; |
384 response:send(encode(send_type, stanza)); | 421 response:send(encode(send_type, stanza)); |