Mercurial > prosody-hg
comparison plugins/mod_http_file_share.lua @ 11332:3e0dcdf6283e
mod_http_file_share: Cache file metadata
For faster access by avoiding archive ID.
No benchmarks were harmed in the making of this commit.
... no benchmarks were performed at all.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Thu, 28 Jan 2021 16:34:13 +0100 |
| parents | 7a915fa49373 |
| children | f80056b97cf0 |
comparison
equal
deleted
inserted
replaced
| 11331:7a915fa49373 | 11332:3e0dcdf6283e |
|---|---|
| 15 local jwt = require "util.jwt"; | 15 local jwt = require "util.jwt"; |
| 16 local errors = require "util.error"; | 16 local errors = require "util.error"; |
| 17 local dataform = require "util.dataforms".new; | 17 local dataform = require "util.dataforms".new; |
| 18 local dt = require "util.datetime"; | 18 local dt = require "util.datetime"; |
| 19 local hi = require "util.human.units"; | 19 local hi = require "util.human.units"; |
| 20 local cache = require "util.cache"; | |
| 20 | 21 |
| 21 local namespace = "urn:xmpp:http:upload:0"; | 22 local namespace = "urn:xmpp:http:upload:0"; |
| 22 | 23 |
| 23 module:depends("disco"); | 24 module:depends("disco"); |
| 24 | 25 |
| 52 filesize = { type = "modify"; condition = "not-acceptable"; text = "File too large"; | 53 filesize = { type = "modify"; condition = "not-acceptable"; text = "File too large"; |
| 53 extra = {tag = st.stanza("file-too-large", {xmlns = namespace}):tag("max-file-size"):text(tostring(file_size_limit)) }; | 54 extra = {tag = st.stanza("file-too-large", {xmlns = namespace}):tag("max-file-size"):text(tostring(file_size_limit)) }; |
| 54 }; | 55 }; |
| 55 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; } | 56 filesizefmt = { type = "modify"; condition = "bad-request"; text = "File size must be positive integer"; } |
| 56 }); | 57 }); |
| 58 | |
| 59 local upload_cache = cache.new(1024); | |
| 57 | 60 |
| 58 -- Convenience wrapper for logging file sizes | 61 -- Convenience wrapper for logging file sizes |
| 59 local function B(bytes) return hi.format(bytes, "B", "b"); end | 62 local function B(bytes) return hi.format(bytes, "B", "b"); end |
| 60 | 63 |
| 61 local function get_filename(slot, create) | 64 local function get_filename(slot, create) |
| 212 uploaded, err = false, 413; | 215 uploaded, err = false, 413; |
| 213 end | 216 end |
| 214 if uploaded then | 217 if uploaded then |
| 215 module:log("debug", "Upload of %q completed, %s", filename, B(final_size)); | 218 module:log("debug", "Upload of %q completed, %s", filename, B(final_size)); |
| 216 assert(os.rename(filename.."~", filename)); | 219 assert(os.rename(filename.."~", filename)); |
| 220 | |
| 221 upload_cache:set(upload_info.slot, { | |
| 222 name = upload_info.filename; | |
| 223 size = tostring(upload_info.filesize); | |
| 224 type = upload_info.filetype; | |
| 225 time = os.time(); | |
| 226 }); | |
| 217 return 201; | 227 return 201; |
| 218 else | 228 else |
| 219 assert(os.remove(filename.."~")); | 229 assert(os.remove(filename.."~")); |
| 220 return err; | 230 return err; |
| 221 end | 231 end |
| 224 end | 234 end |
| 225 | 235 |
| 226 function handle_download(event, path) -- GET /uploads/:slot+filename | 236 function handle_download(event, path) -- GET /uploads/:slot+filename |
| 227 local request, response = event.request, event.response; | 237 local request, response = event.request, event.response; |
| 228 local slot_id = path:match("^[^/]+"); | 238 local slot_id = path:match("^[^/]+"); |
| 229 -- TODO cache | |
| 230 local basename, filetime, filetype, filesize; | 239 local basename, filetime, filetype, filesize; |
| 231 local slot, when = errors.coerce(uploads:get(nil, slot_id)); | 240 local cached = upload_cache:get(slot_id); |
| 232 if not slot then | 241 if cached then |
| 233 module:log("debug", "uploads:get(%q) --> not-found, %s", slot_id, when); | 242 module:log("debug", "Cache hit"); |
| 243 -- TODO stats (instead of logging?) | |
| 244 basename = cached.name; | |
| 245 filesize = cached.size; | |
| 246 filetype = cached.type; | |
| 247 filetime = cached.time; | |
| 248 upload_cache:set(slot_id, cached); | |
| 249 -- TODO cache negative hits? | |
| 234 else | 250 else |
| 235 basename = slot.attr.filename; | 251 module:log("debug", "Cache miss"); |
| 236 filesize = slot.attr.size; | 252 local slot, when = errors.coerce(uploads:get(nil, slot_id)); |
| 237 filetype = slot.attr["content-type"]; | 253 if not slot then |
| 238 filetime = when; | 254 module:log("debug", "uploads:get(%q) --> not-found, %s", slot_id, when); |
| 255 else | |
| 256 module:log("debug", "uploads:get(%q) --> %s, %d", slot_id, slot, when); | |
| 257 basename = slot.attr.filename; | |
| 258 filesize = slot.attr.size; | |
| 259 filetype = slot.attr["content-type"]; | |
| 260 filetime = when; | |
| 261 upload_cache:set(slot_id, { | |
| 262 name = basename; | |
| 263 size = slot.attr.size; | |
| 264 type = filetype; | |
| 265 time = when; | |
| 266 }); | |
| 267 end | |
| 239 end | 268 end |
| 240 if not basename then | 269 if not basename then |
| 241 return 404; | 270 return 404; |
| 242 end | 271 end |
| 243 module:log("debug", "uploads:get(%q) --> %s, %d", slot_id, slot, when); | |
| 244 local last_modified = os.date('!%a, %d %b %Y %H:%M:%S GMT', filetime); | 272 local last_modified = os.date('!%a, %d %b %Y %H:%M:%S GMT', filetime); |
| 245 if request.headers.if_modified_since == last_modified then | 273 if request.headers.if_modified_since == last_modified then |
| 246 return 304; | 274 return 304; |
| 247 end | 275 end |
| 248 local filename = get_filename(slot_id); | 276 local filename = get_filename(slot_id); |
| 290 local obsolete_files = array(); | 318 local obsolete_files = array(); |
| 291 local i = 0; | 319 local i = 0; |
| 292 for slot_id in iter do | 320 for slot_id in iter do |
| 293 i = i + 1; | 321 i = i + 1; |
| 294 obsolete_files:push(get_filename(slot_id)); | 322 obsolete_files:push(get_filename(slot_id)); |
| 323 upload_cache:set(slot_id, nil); | |
| 295 end | 324 end |
| 296 | 325 |
| 297 sleep(0.1); | 326 sleep(0.1); |
| 298 local n = 0; | 327 local n = 0; |
| 299 obsolete_files:filter(function(filename) | 328 obsolete_files:filter(function(filename) |
