Diff

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
line wrap: on
line diff
--- a/plugins/mod_http_file_share.lua	Wed May 12 01:11:42 2021 +0200
+++ b/plugins/mod_http_file_share.lua	Sun May 16 16:52:59 2021 +0200
@@ -356,6 +356,20 @@
 		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 @@
 	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";