diff options
author | Kim Alvefur <zash@zash.se> | 2021-01-31 14:43:42 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2021-01-31 14:43:42 +0100 |
commit | 55cb283433026ad2b04597090ff0a730e8c93f57 (patch) | |
tree | 6fa5ef09df9524eb305f25674d9516c70b1aede9 | |
parent | 8767624de1e0125010103ed6d6c6bb160e6e2667 (diff) | |
download | prosody-55cb283433026ad2b04597090ff0a730e8c93f57.tar.gz prosody-55cb283433026ad2b04597090ff0a730e8c93f57.zip |
mod_http_file_share: Add support for daily upload quotas.
Daily instead of total quotas, should be more efficient to calculate.
Still O(n), but a smaller n. Less affected by total retention period.
-rw-r--r-- | plugins/mod_http_file_share.lua | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/plugins/mod_http_file_share.lua b/plugins/mod_http_file_share.lua index 9554b2f4..63bb7193 100644 --- a/plugins/mod_http_file_share.lua +++ b/plugins/mod_http_file_share.lua @@ -35,6 +35,7 @@ local file_size_limit = module:get_option_number(module.name .. "_size_limit", 1 local file_types = module:get_option_set(module.name .. "_allowed_file_types", {}); local safe_types = module:get_option_set(module.name .. "_safe_file_types", {"image/*","video/*","audio/*","text/plain"}); local expiry = module:get_option_number(module.name .. "_expires_after", 7 * 86400); +local daily_quota = module:get_option_number(module.name .. "_daily_quota", file_size_limit*10); -- 100 MB / day local access = module:get_option_set(module.name .. "_access", {}); @@ -55,6 +56,7 @@ local upload_errors = errors.init(module.name, namespace, { extra = {tag = st.stanza("file-too-large", {xmlns = namespace}):tag("max-file-size"):text(tostring(file_size_limit)) }; }; filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; }; + quota = { type = "wait"; condition = "resource-constraint"; text = "Daily quota reached"; }; }); local upload_cache = cache.new(1024); @@ -66,6 +68,18 @@ local function get_filename(slot, create) return dm.getpath(slot, module.host, module.name, "bin", create) end +-- TODO cache +function get_daily_quota(uploader) + local iter, err = uploads:find(nil, {with = uploader; start = os.time() - 86400}); + if not iter then return iter, err; end + local total_bytes = 0; + for _, slot in iter do + local size = tonumber(slot.attr.size); + if size then total_bytes = total_bytes + size; end + end + return total_bytes; +end + function may_upload(uploader, filename, filesize, filetype) -- > boolean, error local uploader_host = jid.host(uploader); if not ((access:empty() and prosody.hosts[uploader_host]) or access:contains(uploader) or access:contains(uploader_host)) then @@ -84,6 +98,11 @@ function may_upload(uploader, filename, filesize, filetype) -- > boolean, error return false, upload_errors.new("filesize"); end + local uploader_quota = get_daily_quota(uploader); + if uploader_quota + filesize > daily_quota then + return false, upload_errors.new("quota"); + end + if not ( file_types:empty() or file_types:contains(filetype) or file_types:contains(filetype:gsub("/.*", "/*")) ) then return false, upload_errors.new("filetype"); end |