Changeset

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
parents 11563:0983653cbfdf
children 11567:c471e19a238e
files doc/doap.xml plugins/mod_http_file_share.lua
diffstat 2 files changed, 21 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/doc/doap.xml	Wed May 12 01:11:42 2021 +0200
+++ b/doc/doap.xml	Sun May 16 16:52:59 2021 +0200
@@ -52,6 +52,7 @@
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc6121"/>
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc6122"/>
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc6455"/>
+    <implements rdf:resource="https://www.rfc-editor.org/info/rfc7233"/>
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc7301"/>
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc7395"/>
     <implements rdf:resource="https://www.rfc-editor.org/info/rfc7590"/>
--- 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";