Mercurial > prosody-hg
comparison plugins/mod_http_file_share.lua @ 11348:f076199b4d38
mod_http_file_share: Cache quotas to avoid hitting storage
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sun, 31 Jan 2021 17:56:49 +0100 |
| parents | 5b3ad3c7fe47 |
| children | a219001b449d |
comparison
equal
deleted
inserted
replaced
| 11347:5b3ad3c7fe47 | 11348:f076199b4d38 |
|---|---|
| 58 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; }; | 58 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; }; |
| 59 quota = { type = "wait"; condition = "resource-constraint"; text = "Daily quota reached"; }; | 59 quota = { type = "wait"; condition = "resource-constraint"; text = "Daily quota reached"; }; |
| 60 }); | 60 }); |
| 61 | 61 |
| 62 local upload_cache = cache.new(1024); | 62 local upload_cache = cache.new(1024); |
| 63 local quota_cache = cache.new(1024); | |
| 63 | 64 |
| 64 -- Convenience wrapper for logging file sizes | 65 -- Convenience wrapper for logging file sizes |
| 65 local function B(bytes) return hi.format(bytes, "B", "b"); end | 66 local function B(bytes) return hi.format(bytes, "B", "b"); end |
| 66 | 67 |
| 67 local function get_filename(slot, create) | 68 local function get_filename(slot, create) |
| 68 return dm.getpath(slot, module.host, module.name, "bin", create) | 69 return dm.getpath(slot, module.host, module.name, "bin", create) |
| 69 end | 70 end |
| 70 | 71 |
| 71 -- TODO cache | |
| 72 function get_daily_quota(uploader) | 72 function get_daily_quota(uploader) |
| 73 local now = os.time(); | 73 local now = os.time(); |
| 74 local max_age = now - 86400; | 74 local max_age = now - 86400; |
| 75 local cached = quota_cache:get(uploader); | |
| 76 if cached and cached.time > max_age then | |
| 77 return cached.size; | |
| 78 end | |
| 75 local iter, err = uploads:find(nil, {with = uploader; start = max_age }); | 79 local iter, err = uploads:find(nil, {with = uploader; start = max_age }); |
| 76 if not iter then return iter, err; end | 80 if not iter then return iter, err; end |
| 77 local total_bytes = 0; | 81 local total_bytes = 0; |
| 78 for _, slot in iter do | 82 local oldest_upload; |
| 83 for _, slot, when in iter do | |
| 79 local size = tonumber(slot.attr.size); | 84 local size = tonumber(slot.attr.size); |
| 80 if size then total_bytes = total_bytes + size; end | 85 if size then total_bytes = total_bytes + size; end |
| 81 end | 86 if not oldest_upload then oldest_upload = when; end |
| 87 end | |
| 88 quota_cache:set(uploader, { time = oldest_upload or now, size = total_bytes }); | |
| 82 return total_bytes; | 89 return total_bytes; |
| 83 end | 90 end |
| 84 | 91 |
| 85 function may_upload(uploader, filename, filesize, filetype) -- > boolean, error | 92 function may_upload(uploader, filename, filesize, filetype) -- > boolean, error |
| 86 local uploader_host = jid.host(uploader); | 93 local uploader_host = jid.host(uploader); |
| 157 local slot, storage_err = errors.coerce(uploads:append(nil, nil, request, os.time(), uploader)) | 164 local slot, storage_err = errors.coerce(uploads:append(nil, nil, request, os.time(), uploader)) |
| 158 if not slot then | 165 if not slot then |
| 159 origin.send(st.error_reply(stanza, storage_err)); | 166 origin.send(st.error_reply(stanza, storage_err)); |
| 160 return true; | 167 return true; |
| 161 end | 168 end |
| 169 | |
| 170 -- Invalidate cache | |
| 171 quota_cache:set(uploader, nil); | |
| 162 | 172 |
| 163 local authz = get_authz(uploader, filename, filesize, filetype, slot); | 173 local authz = get_authz(uploader, filename, filesize, filetype, slot); |
| 164 local slot_url = get_url(slot, filename); | 174 local slot_url = get_url(slot, filename); |
| 165 local upload_url = slot_url; | 175 local upload_url = slot_url; |
| 166 | 176 |
