changeset 2678:2dec7cad9218

mod_http_upload: Implement quota support (closes #823)
author Kim Alvefur <zash@zash.se>
date Thu, 13 Apr 2017 16:35:10 +0200
parents 6daaa1ad2559
children 5f60dd12dbb8
files mod_http_upload/README.markdown mod_http_upload/mod_http_upload.lua
diffstat 2 files changed, 22 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mod_http_upload/README.markdown	Thu Apr 13 16:31:00 2017 +0200
+++ b/mod_http_upload/README.markdown	Thu Apr 13 16:35:10 2017 +0200
@@ -43,6 +43,12 @@
 http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds
 ```
 
+A total maximum size of all uploaded files per user can be set by:
+
+``` lua
+http_upload_quota = 1234 -- bytes
+```
+
 Path
 ----
 
--- a/mod_http_upload/mod_http_upload.lua	Thu Apr 13 16:31:00 2017 +0200
+++ b/mod_http_upload/mod_http_upload.lua	Thu Apr 13 16:35:10 2017 +0200
@@ -29,6 +29,7 @@
 
 -- config
 local file_size_limit = module:get_option_number(module.name .. "_file_size_limit", 1024 * 1024); -- 1 MB
+local quota = module:get_option_number(module.name .. "_quota");
 local max_age = module:get_option_number(module.name .. "_expire_after");
 
 --- sanity
@@ -88,6 +89,17 @@
 	return datamanager.list_store(username, host, module.name, uploads);
 end
 
+local function check_quota(username, host, does_it_fit)
+	if not quota then return true; end
+	local uploads, err = datamanager.list_load(username, host, module.name);
+	if not uploads then return true; end
+	local sum = does_it_fit or 0;
+	for _, item in ipairs(uploads) do
+		sum = sum + item.size;
+	end
+	return sum < quota;
+end
+
 local function handle_request(origin, stanza, xmlns, filename, filesize)
 	-- local clients only
 	if origin.type ~= "c2s" then
@@ -112,6 +124,10 @@
 			:tag("file-too-large", {xmlns=xmlns})
 				:tag("max-file-size"):text(tostring(file_size_limit)));
 		return true;
+	elseif not check_quota(origin.username, origin.host, filesize) then
+		module:log("debug", "Upload of %dB by %s would exceed quota", filesize, origin.full_jid);
+		origin.send(st.error_reply(stanza, "wait", "resource-constraint", "Quota reached"));
+		return true;
 	end
 	local reply = st.reply(stanza);
 	reply:tag("slot", { xmlns = xmlns });