# HG changeset patch # User Kim Alvefur # Date 1373662481 -7200 # Node ID 1dc07833355eeec02c723bba3a25f7f731e4fa88 # Parent bdbf76730f499d7ce5cf262a9217492bd8effae9 mod_mam: Use more specific hook diff -r bdbf76730f49 -r 1dc07833355e mod_mam/mod_mam.lua --- a/mod_mam/mod_mam.lua Fri Jul 12 22:46:15 2013 +0200 +++ b/mod_mam/mod_mam.lua Fri Jul 12 22:54:41 2013 +0200 @@ -94,134 +94,132 @@ end); -- Handle archive queries -module:hook("iq/self/"..xmlns_mam..":query", function(event) +module:hook("iq-get/self/"..xmlns_mam..":query", function(event) local origin, stanza = event.origin, event.stanza; local query = stanza.tags[1]; - if stanza.attr.type == "get" then - local qid = query.attr.queryid; + local qid = query.attr.queryid; + + -- Search query parameters + local qwith = query:get_child_text("with"); + local qstart = query:get_child_text("start"); + local qend = query:get_child_text("end"); + local qset = rsm.get(query); + module:log("debug", "Archive query, id %s with %s from %s until %s)", + tostring(qid), qwith or "anyone", qstart or "the dawn of time", qend or "now"); - -- Search query parameters - local qwith = query:get_child_text("with"); - local qstart = query:get_child_text("start"); - local qend = query:get_child_text("end"); - local qset = rsm.get(query); - module:log("debug", "Archive query, id %s with %s from %s until %s)", - tostring(qid), qwith or "anyone", qstart or "the dawn of time", qend or "now"); + if qstart or qend then -- Validate timestamps + local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend)) + if (qstart and not vstart) or (qend and not vend) then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid timestamp")) + return true + end + qstart, qend = vstart, vend; + end - if qstart or qend then -- Validate timestamps - local vstart, vend = (qstart and timestamp_parse(qstart)), (qend and timestamp_parse(qend)) - if (qstart and not vstart) or (qend and not vend) then - origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid timestamp")) - return true - end - qstart, qend = vstart, vend; + local qres; + if qwith then -- Validate the 'with' jid + local pwith = qwith and jid_prep(qwith); + if pwith and not qwith then -- it failed prepping + origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid JID")) + return true end + local _, _, resource = jid_split(qwith); + qwith = jid_bare(pwith); + qres = resource; + end - local qres; - if qwith then -- Validate the 'with' jid - local pwith = qwith and jid_prep(qwith); - if pwith and not qwith then -- it failed prepping - origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid JID")) - return true - end - local _, _, resource = jid_split(qwith); - qwith = jid_bare(pwith); - qres = resource; + -- Load all the data! + local data, err = dm_list_load(origin.username, origin.host, archive_store); + if not data then + if (not err) then + module:log("debug", "The archive was empty."); + origin.send(st.reply(stanza)); + else + origin.send(st.error_reply(stanza, "cancel", "internal-server-error", "Error loading archive: "..tostring(err))); end + return true + end - -- Load all the data! - local data, err = dm_list_load(origin.username, origin.host, archive_store); - if not data then - if (not err) then - module:log("debug", "The archive was empty."); - origin.send(st.reply(stanza)); - else - origin.send(st.error_reply(stanza, "cancel", "internal-server-error", "Error loading archive: "..tostring(err))); + -- RSM stuff + local qmax = m_min(qset and qset.max or default_max_items, max_max_items); + local qset_matches = not (qset and qset.after); + local first, last, index; + local n = 0; + local start = qset and qset.index or 1; + local results = {}; + -- An empty means: give the last n items. So we loop backwards. + local reverse = qset and qset.before or false; + + module:log("debug", "Loaded %d items, about to filter", #data); + for i=(reverse and #data or start),(reverse and start or #data),(reverse and -1 or 1) do + local item = data[i]; + local when, with, resource = item.when, item.with, item.resource; + local id = item.id; + --module:log("debug", "id is %s", id); + + -- RSM pre-send-checking + if qset then + if qset.before == id then + module:log("debug", "End of matching range found"); + qset_matches = false; + break; end - return true end - -- RSM stuff - local qmax = m_min(qset and qset.max or default_max_items, max_max_items); - local qset_matches = not (qset and qset.after); - local first, last, index; - local n = 0; - local start = qset and qset.index or 1; - local results = {}; - -- An empty means: give the last n items. So we loop backwards. - local reverse = qset and qset.before or false; - - module:log("debug", "Loaded %d items, about to filter", #data); - for i=(reverse and #data or start),(reverse and start or #data),(reverse and -1 or 1) do - local item = data[i]; - local when, with, resource = item.when, item.with, item.resource; - local id = item.id; - --module:log("debug", "id is %s", id); - - -- RSM pre-send-checking - if qset then - if qset.before == id then - module:log("debug", "End of matching range found"); - qset_matches = false; - break; - end + --module:log("debug", "message with %s at %s", with, when or "???"); + -- Apply query filter + if (not qwith or ((qwith == with) and (not qres or qres == resource))) + and (not qstart or when >= qstart) + and (not qend or when <= qend) + and (not qset or qset_matches) then + local fwd_st = st.message{ to = origin.full_jid } + :tag("result", { xmlns = xmlns_mam, queryid = qid, id = id }) + :tag("forwarded", { xmlns = xmlns_forward }) + :tag("delay", { xmlns = xmlns_delay, stamp = timestamp(when) }):up(); + local orig_stanza = st.deserialize(item.stanza); + orig_stanza.attr.xmlns = "jabber:client"; + fwd_st:add_child(orig_stanza); + if reverse then + t_insert(results, 1, fwd_st); + else + results[#results + 1] = fwd_st; end + if not first then + index = i; + first = id; + end + last = id; + n = n + 1; + elseif (qend and when > qend) then + module:log("debug", "We have passed into messages more recent than requested"); + break -- We have passed into messages more recent than requested + end - --module:log("debug", "message with %s at %s", with, when or "???"); - -- Apply query filter - if (not qwith or ((qwith == with) and (not qres or qres == resource))) - and (not qstart or when >= qstart) - and (not qend or when <= qend) - and (not qset or qset_matches) then - local fwd_st = st.message{ to = origin.full_jid } - :tag("result", { xmlns = xmlns_mam, queryid = qid, id = id }) - :tag("forwarded", { xmlns = xmlns_forward }) - :tag("delay", { xmlns = xmlns_delay, stamp = timestamp(when) }):up(); - local orig_stanza = st.deserialize(item.stanza); - orig_stanza.attr.xmlns = "jabber:client"; - fwd_st:add_child(orig_stanza); - if reverse then - t_insert(results, 1, fwd_st); - else - results[#results + 1] = fwd_st; - end - if not first then - index = i; - first = id; - end - last = id; - n = n + 1; - elseif (qend and when > qend) then - module:log("debug", "We have passed into messages more recent than requested"); - break -- We have passed into messages more recent than requested - end - - -- RSM post-send-checking - if qset then - if qset.after == id then - module:log("debug", "Start of matching range found"); - qset_matches = true; - end - end - if n >= qmax then - module:log("debug", "Max number of items matched"); - break + -- RSM post-send-checking + if qset then + if qset.after == id then + module:log("debug", "Start of matching range found"); + qset_matches = true; end end - for _,v in pairs(results) do - origin.send(v); + if n >= qmax then + module:log("debug", "Max number of items matched"); + break end - -- That's all folks! - module:log("debug", "Archive query %s completed", tostring(qid)); + end + for _,v in pairs(results) do + origin.send(v); + end + -- That's all folks! + module:log("debug", "Archive query %s completed", tostring(qid)); - local reply = st.reply(stanza); - if last then - -- This is a bit redundant, isn't it? - reply:query(xmlns_mam):add_child(rsm.generate{first = (reverse and last or first), last = (reverse and first or last), count = #data}); - end - origin.send(reply); - return true + local reply = st.reply(stanza); + if last then + -- This is a bit redundant, isn't it? + reply:query(xmlns_mam):add_child(rsm.generate{first = (reverse and last or first), last = (reverse and first or last), count = #data}); end + origin.send(reply); + return true end); local function has_in_roster(user, who)