Mercurial > prosody-modules
changeset 6417:dcc8d4af8d4f
mod_muc_cache_media: move to storage that matches RFC 6920
| author | Stephen Paul Weber <singpolyma@singpolyma.net> |
|---|---|
| date | Tue, 24 Feb 2026 11:57:09 -0500 |
| parents | 2511bf07b8d2 |
| children | 98e06fc5680f |
| files | mod_muc_cache_media/mod_muc_cache_media.lua |
| diffstat | 1 files changed, 35 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/mod_muc_cache_media/mod_muc_cache_media.lua Tue Feb 24 16:39:04 2026 +0100 +++ b/mod_muc_cache_media/mod_muc_cache_media.lua Tue Feb 24 11:57:09 2026 -0500 @@ -10,31 +10,12 @@ local jid = require "util.jid" local storage_path = module:get_option_string("muc_media_store_path", "/var/lib/prosody/muc-media") -local public_base_url = module:get_option_string("muc_media_public_base", "https://cache.example.com") -local files_have_extensions = module:get_option_boolean("muc_media_files_have_extensions", true) +local public_base_url = module:get_option_string("muc_media_public_base") local max_size = module:get_option_number("muc_media_max_size", 10 * 1024 * 1024) lfs.mkdir(storage_path) - -local mime_extensions = { - ["image/jpeg"] = ".jpg", - ["image/jpg"] = ".jpg", - ["image/png"] = ".png", - ["image/gif"] = ".gif", - ["image/webp"] = ".webp", - ["image/avif"] = ".avif", - ["video/mp4"] = ".mp4", - ["video/webm"] = ".webm", - ["audio/mpeg"] = ".mp3", - ["audio/ogg"] = ".ogg", -} - -local function extension_from_content_type(content_type) - if not content_type then return ".bin" end - local clean = content_type:match("^[^;]+") - clean = clean and clean:lower() - return mime_extensions[clean] or ".bin" -end +lfs.mkdir(storage_path.."/sha-256") +lfs.mkdir(storage_path.."/sha3-256") local function ipv4_to_number(ip) local a,b,c,d = ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$") @@ -160,20 +141,20 @@ local sha3 = sha3_256_file(tmp_path) local size = file_size(tmp_path) local name = filename_from_url(original_url) - if sha2 then - local ext = extension_from_content_type(content_type) - local file_name = sha2:gsub("+","-"):gsub("/","_"):gsub("=","") - local url_name = file_name..ext - if files_have_extensions then - file_name = file_name..ext - end - local final_path = storage_path.."/"..file_name + if sha2 and sha3 then + local final_name = "sha3-256/"..sha3:gsub("+","-"):gsub("/","_"):gsub("=","") + local final_path = storage_path.."/"..final_name if not lfs.attributes(final_path) then os.rename(tmp_path, final_path) else + lfs.touch(final_path) os.remove(tmp_path) end - url_map[original_url] = { local_url = public_base_url.."/"..url_name, path=final_path, sha2=sha2, sha3=sha3, size=size, name=name, content_type=content_type } + local sha2_path = storage_path.."/sha-256/"..sha2:gsub("+","-"):gsub("/","_"):gsub("=","") + if not lfs.attributes(sha2_path) then + lfs.link(final_path, sha2_path, true) + end + url_map[original_url] = { local_url = public_base_url..final_name.."?ct="..content_type, path=final_path, sha2=sha2, sha3=sha3, size=size, name=name, content_type=content_type } else os.remove(tmp_path) end @@ -247,20 +228,18 @@ -- Fill SHA256 hash local sha2_tag = nil for htag in file_tag:childtags("hash","urn:xmpp:hashes:2") do - if htag.attr.algo=="sha2-256" then sha2_tag = htag end + if htag.attr.algo=="sha-256" then sha2_tag = htag end end if not sha2_tag then - file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha2-256" }):text(data.sha2)) + file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha-256" }):text(data.sha2)) end - if data.sha3 then - -- Fill SHA3-256 hash - local sha3_tag = nil - for htag in file_tag:childtags("hash","urn:xmpp:hashes:2") do - if htag.attr.algo=="sha3-256" then sha3_tag = htag end - end - if not sha3_tag then - file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha3-256" }):text(data.sha3)) - end + -- Fill SHA3-256 hash + local sha3_tag = nil + for htag in file_tag:childtags("hash","urn:xmpp:hashes:2") do + if htag.attr.algo=="sha3-256" then sha3_tag = htag end + end + if not sha3_tag then + file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha3-256" }):text(data.sha3)) end end end @@ -275,8 +254,8 @@ file_tag:add_child(st.stanza("media-type"):text(data.content_type or "application/octet-stream")) file_tag:add_child(st.stanza("name"):text(data.name)) file_tag:add_child(st.stanza("size"):text(tostring(data.size))) - file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha2-256" }):text(data.sha2)) - if data.sha3 then file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha3-256" }):text(data.sha3)) end + file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha-256" }):text(data.sha2)) + file_tag:add_child(st.stanza("hash",{ xmlns="urn:xmpp:hashes:2", algo="sha3-256" }):text(data.sha3)) ms:add_child(file_tag) local sources = st.stanza("sources") sources:add_child(st.stanza("reference",{ xmlns="urn:xmpp:reference:0", type="data", uri=data.local_url })) @@ -310,36 +289,19 @@ -- Extract SIMS hashes for ref in stanza:childtags("reference", "urn:xmpp:reference:0") do for ms in ref:childtags("media-sharing", "urn:xmpp:sims:1") do - local file_tag = ms:get_child("file", "urn:xmpp:jingle:apps:file-transfer:5") - if file_tag then + for file_tag in ms:childtags("file", "urn:xmpp:jingle:apps:file-transfer:5") do for hash_tag in file_tag:childtags("hash", "urn:xmpp:hashes:2") do - if hash_tag.attr.algo == "sha2-256" then - local sha2 = hash_tag:get_text() - if sha2 then - local prefix = sha2:gsub("+","-"):gsub("/","_"):gsub("=","") - if files_have_extensions then - -- Files are named: hash + extension - for file in lfs.dir(storage_path) do - if file:match("^" .. prefix) then - local path = storage_path .. "/" .. file - if lfs.attributes(path) then - os.remove(path) - module:log("debug", - "Deleted cached media %s for moderated message %s", - file, stanza_id - ) - end - end - end - else - local path = storage_path .. "/" .. prefix - if lfs.attributes(path) then - os.remove(path) - module:log("debug", - "Deleted cached media %s for moderated message %s", - file, stanza_id - ) - end + if hash_tag.attr.algo == "sha3-256" then + local sha3 = hash_tag:get_text() + if sha3 then + local file = sha3:gsub("+","-"):gsub("/","_"):gsub("=","") + local path = storage_path .. "/sha3-256/" .. file + if lfs.attributes(path) then + os.remove(path) + module:log("debug", + "Deleted cached media %s for moderated message %s", + file, stanza_id + ) end end end
