# HG changeset patch # User Kim Alvefur # Date 1652723229 -7200 # Node ID e7b9bc629eccad820fbd1ebe35406de7b24c07a3 # Parent 7406039021d848b3681dba5b6f220f26e42e854c 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. diff -r 7406039021d8 -r e7b9bc629ecc mod_rest/mod_rest.lua --- a/mod_rest/mod_rest.lua Sat May 14 15:52:23 2022 +0200 +++ b/mod_rest/mod_rest.lua Mon May 16 19:47:09 2022 +0200 @@ -68,6 +68,20 @@ end end +local function event_suffix(jid_to) + local node, _, resource = jid.split(jid_to); + if node then + if resource then + return '/full'; + else + return '/bare'; + end + else + return '/host'; + end +end + + -- TODO This ought to be handled some way other than duplicating this -- core.stanza_router code here. local function compat_preevents(origin, stanza) --> boolean : handled @@ -356,7 +370,22 @@ return post_errors.new("iq_tags"); end - return module:send_iq(payload, origin):next( + -- special handling of multiple responses to MAM queries primarily from + -- remote hosts, local go directly to origin.send() + local archive_event_name = "message"..event_suffix(from); + local archive_handler; + local archive_query = payload:get_child("query", "urn:xmpp:mam:2"); + if archive_query then + archive_handler = function(result_event) + if result_event.stanza:find("{urn:xmpp:mam:2}result/@queryid") == archive_query.attr.queryid then + origin.send(result_event.stanza); + return true; + end + end + module:hook(archive_event_name, archive_handler, 1); + end + + local p = module:send_iq(payload, origin):next( function (result) module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); response.headers.content_type = send_type; @@ -377,6 +406,14 @@ return error; end end); + + if archive_handler then + p:finally(function () + module:unhook(archive_event_name, archive_handler); + end) + end + + return p; else function origin.send(stanza) module:log("debug", "Sending[rest]: %s", stanza:top_tag());