aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-01-27 22:09:26 +0100
committerKim Alvefur <zash@zash.se>2021-01-27 22:09:26 +0100
commitcdccf238547d8500b117335b6b2024caff190c4e (patch)
tree6b94cdba0e9b8581b436a1eb7ba4ebf4492eafe6
parentaf9f7de3789f0b98e5322a66bcc8509561cc3d0e (diff)
downloadprosody-cdccf238547d8500b117335b6b2024caff190c4e.tar.gz
prosody-cdccf238547d8500b117335b6b2024caff190c4e.zip
mod_http_file_share: Add support for removing old files (default 2 weeks)
-rw-r--r--plugins/mod_http_file_share.lua60
1 files changed, 59 insertions, 1 deletions
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);