aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-05-16 16:52:59 +0200
committerKim Alvefur <zash@zash.se>2021-05-16 16:52:59 +0200
commitf5757cae7fff33b74783b8006cbfc1a57ec7c4be (patch)
tree1beabaad97e9c16eb4a500a3f0efd2a0de4ff247 /plugins
parent8164b929893a089b85be15efd8c599693fef1b7b (diff)
downloadprosody-f5757cae7fff33b74783b8006cbfc1a57ec7c4be.tar.gz
prosody-f5757cae7fff33b74783b8006cbfc1a57ec7c4be.zip
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.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/mod_http_file_share.lua20
1 files changed, 20 insertions, 0 deletions
diff --git a/plugins/mod_http_file_share.lua b/plugins/mod_http_file_share.lua
index 0ef6f856..4b6030bf 100644
--- a/plugins/mod_http_file_share.lua
+++ b/plugins/mod_http_file_share.lua
@@ -356,6 +356,20 @@ function handle_download(event, path) -- GET /uploads/:slot+filename
return 410;
end
+ local request_range = request.headers.range;
+ local response_range;
+ if request_range then
+ local range_start, range_end = request_range:match("^bytes=(%d+)%-(%d*)$")
+ -- Only support resumption, ie ranges from somewhere in the middle until the end of the file.
+ if (range_start and range_start ~= "0" and range_start ~= filesize) and (range_end == "" or range_end == filesize) then
+ if handle:seek("set", tonumber(range_start)) then
+ response_range = "bytes "..range_start.."-"..filesize.."/"..filesize;
+ filesize = string.format("%d", tonumber(filesize)-tonumber(range_start));
+ end
+ end
+ end
+
+
if not filetype then
filetype = "application/octet-stream";
end
@@ -369,6 +383,12 @@ function handle_download(event, path) -- GET /uploads/:slot+filename
response.headers.content_type = filetype;
response.headers.content_disposition = string.format("%s; filename=%q", disposition, basename);
+ if response_range then
+ response.status_code = 206;
+ response.headers.content_range = response_range;
+ end
+ response.headers.accept_ranges = "bytes";
+
response.headers.cache_control = "max-age=31556952, immutable";
response.headers.content_security_policy = "default-src 'none'; frame-ancestors 'none';"
response.headers.strict_transport_security = "max-age=31556952";