mod_rest/mod_rest.lua
changeset 4945 e7b9bc629ecc
parent 4926 c83b009b5bc5
child 4946 83a54f4af94c
--- 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());