Comparison

plugins/mod_http_file_share.lua @ 11564:60e31c9ece57

mod_http_file_share: Support download resumption via Range requests Only a starting point is supported due to the way response:send_file() sends everything it gets from the provided file handle but does not have any way to specify how much to read. This matches what Conversations appears to be doing.
author Kim Alvefur <zash@zash.se>
date Sun, 16 May 2021 16:52:59 +0200
parent 11503:7adda14945ad
child 11568:d5360307a99d
comparison
equal deleted inserted replaced
11563:0983653cbfdf 11564:60e31c9ece57
354 -- This can be because the upload slot wasn't used, or the file disappeared 354 -- This can be because the upload slot wasn't used, or the file disappeared
355 -- somehow, or permission issues. 355 -- somehow, or permission issues.
356 return 410; 356 return 410;
357 end 357 end
358 358
359 local request_range = request.headers.range;
360 local response_range;
361 if request_range then
362 local range_start, range_end = request_range:match("^bytes=(%d+)%-(%d*)$")
363 -- Only support resumption, ie ranges from somewhere in the middle until the end of the file.
364 if (range_start and range_start ~= "0" and range_start ~= filesize) and (range_end == "" or range_end == filesize) then
365 if handle:seek("set", tonumber(range_start)) then
366 response_range = "bytes "..range_start.."-"..filesize.."/"..filesize;
367 filesize = string.format("%d", tonumber(filesize)-tonumber(range_start));
368 end
369 end
370 end
371
372
359 if not filetype then 373 if not filetype then
360 filetype = "application/octet-stream"; 374 filetype = "application/octet-stream";
361 end 375 end
362 local disposition = "attachment"; 376 local disposition = "attachment";
363 if safe_types:contains(filetype) or safe_types:contains(filetype:gsub("/.*", "/*")) then 377 if safe_types:contains(filetype) or safe_types:contains(filetype:gsub("/.*", "/*")) then
366 380
367 response.headers.last_modified = last_modified; 381 response.headers.last_modified = last_modified;
368 response.headers.content_length = filesize; 382 response.headers.content_length = filesize;
369 response.headers.content_type = filetype; 383 response.headers.content_type = filetype;
370 response.headers.content_disposition = string.format("%s; filename=%q", disposition, basename); 384 response.headers.content_disposition = string.format("%s; filename=%q", disposition, basename);
385
386 if response_range then
387 response.status_code = 206;
388 response.headers.content_range = response_range;
389 end
390 response.headers.accept_ranges = "bytes";
371 391
372 response.headers.cache_control = "max-age=31556952, immutable"; 392 response.headers.cache_control = "max-age=31556952, immutable";
373 response.headers.content_security_policy = "default-src 'none'; frame-ancestors 'none';" 393 response.headers.content_security_policy = "default-src 'none'; frame-ancestors 'none';"
374 response.headers.strict_transport_security = "max-age=31556952"; 394 response.headers.strict_transport_security = "max-age=31556952";
375 response.headers.x_content_type_options = "nosniff"; 395 response.headers.x_content_type_options = "nosniff";