Mercurial > prosody-modules
view mod_ogp/mod_ogp.lua @ 4931:13070c6a7ce8
mod_http_muc_log: Fix exception on lack of trailing slash in room path
A request to /room leads to the match call returning nil which in turn
calls nodeprep(nil). In Prosody 0.11.x this does nothing and simply
returns the nil, while in 0.12 it is an error.
Now it redirects to the calendar view at /room/ - even for non-existant
rooms.
Discovered at a deployment with http_paths = { muc_log = "/" } and
requests to /robots.txt and similar, which now result in a uses redirect
before returning 404.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 22 Apr 2022 14:29:32 +0200 |
parents | 09f0911c735d |
children |
line wrap: on
line source
local mod_muc = module:depends("muc") local http = require "net.http" local st = require "util.stanza" local url_pattern = [[https?://%S+]] local domain_pattern = '^%w+://([^/]+)' local xmlns_fasten = "urn:xmpp:fasten:0" local xmlns_xhtml = "http://www.w3.org/1999/xhtml" local allowlist = module:get_option_set("ogp_domain_allowlist", module:get_option_set("ogp_domain_whitelist", {})) local denylist = module:get_option_set("ogp_domain_denylist", {}) local function is_allowed(domain) if allowlist:empty() then return true end if allowlist:contains(domain) then return true end return false end local function is_denied(domain) if denylist:empty() then return false end if denylist:contains(domain) then return true end return false end local function fetch_ogp_data(room, url, origin_id) if not url then return; end local domain = url:match(domain_pattern); if is_denied(domain) or not is_allowed(domain) then return; end http.request( url, nil, function(response_body, response_code, _) if response_code ~= 200 then module:log("debug", "Call to %s returned code %s and body %s", url, response_code, response_body) return end local to = room.jid local from = room and room.jid or module.host local fastening = st.message({to = to, from = from, type = 'groupchat'}):tag("apply-to", {xmlns = xmlns_fasten, id = origin_id}) local found_metadata = false local message_body = "" local meta_pattern = [[<meta (.-)/?>]] for match in response_body:gmatch(meta_pattern) do local property = match:match([[property=%s*["']?(og:.-)["']?%s]]) if not property then property = match:match([[property=["']?(og:.-)["']$]]) end local content = match:match([[content=%s*["'](.-)["']%s]]) if not content then content = match:match([[content=["']?(.-)["']$]]) end if not content then content = match:match([[content=(.-) property]]) end if not content then content = match:match([[content=(.-)$]]) end if property and content then module:log("debug", property .. "\t" .. content) fastening:tag( "meta", { xmlns = xmlns_xhtml, property = property, content = content } ):up() found_metadata = true message_body = message_body .. property .. "\t" .. content .. "\n" end end if found_metadata then mod_muc.get_room_from_jid(room.jid):broadcast_message(fastening) end module:log("debug", tostring(fastening)) end ) end local function ogp_handler(event) local room, stanza = event.room, st.clone(event.stanza) local body = stanza:get_child_text("body") if not body then return; end local origin_id = stanza:find("{urn:xmpp:sid:0}origin-id@id") if not origin_id then return; end for url in body:gmatch(url_pattern) do fetch_ogp_data(room, url, origin_id); end end module:hook("muc-occupant-groupchat", ogp_handler) module:hook("muc-message-is-historic", function (event) local fastening = event.stanza:get_child('apply-to', xmlns_fasten) if fastening and fastening:get_child('meta', xmlns_xhtml) then return true end end);