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));