From 395de7cde5b3b2134df24fbf7b03e4bcba2c1af2 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 27 Jan 2021 22:09:26 +0100 Subject: mod_http_file_share: Add support for removing old files (default 2 weeks) --- plugins/mod_http_file_share.lua | 60 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/plugins/mod_http_file_share.lua b/plugins/mod_http_file_share.lua index c2aa4301..090a056a 100644 --- a/plugins/mod_http_file_share.lua +++ b/plugins/mod_http_file_share.lua @@ -32,6 +32,7 @@ local secret = module:get_option_string(module.name.."_secret", require"util.id" local external_base_url = module:get_option_string(module.name .. "_base_url"); local file_size_limit = module:get_option_number(module.name .. "_size_limit", 10 * 1024 * 1024); -- 10 MB local file_types = module:get_option_set(module.name .. "_allowed_file_types", {}); +local expiry = module:get_option_number(module.name .. "_expires_after", 7 * 86400); local access = module:get_option_set(module.name .. "_access", {}); @@ -256,7 +257,64 @@ function handle_download(event, path) -- GET /uploads/:slot+filename return response:send_file(handle); end --- TODO periodic cleanup job +if expiry >= 0 and not external_base_url then + -- TODO HTTP DELETE to the external endpoint? + local array = require "util.array"; + local async = require "util.async"; + local ENOENT = require "util.pposix".ENOENT; + + local reaper_task = async.runner(function(boundary_time) + local iter, total = assert(uploads:find(nil, {["end"] = boundary_time; total = true})); + + if total == 0 then + module:log("info", "No expired to prune"); + return; + end + + module:log("info", "Pruning expired files uploaded earlier than %s", dt.datetime(boundary_time)); + + local obsolete_files = array(); + local i = 0; + for slot_id in iter do + i = i + 1; + obsolete_files:push(get_filename(slot_id)); + end + + local n = 0; + obsolete_files:filter(function(filename) + n = n + 1; + local deleted, err, errno = os.remove(filename); + if deleted or errno == ENOENT then + return false; + else + module:log("error", "Could not delete file %q: %s", filename, err); + return true; + end + end); + + local deletion_query = {["end"] = boundary_time}; + if #obsolete_files == 0 then + module:log("info", "All %d expired files deleted", n); + else + module:log("warn", "%d out of %d expired files could not be deleted", #obsolete_files, n); + deletion_query = {ids = obsolete_files}; + end + + local removed, err = uploads:delete(nil, deletion_query); + + if removed == true or removed == n or removed == #obsolete_files then + module:log("debug", "Removed all metadata for expired uploaded files"); + else + module:log("error", "Problem removing metadata for deleted files: %s", err); + end + + end); + + module:add_timer(1, function () + reaper_task:run(os.time()-expiry); + return 60*60; + end); +end module:hook("iq-get/host/urn:xmpp:http:upload:0:request", handle_slot_request); -- cgit v1.2.3