Mercurial > prosody-hg
changeset 14073:dfbc60d47668 13.0
mod_http_file_share: Improve handling of Range requests
There were reports of clients always including the Range header, even
when not resuming a download. Since it is equivalent to a non-Range
request, better to simply send the whole file instead of an error.
Range requests with units other than bytes are also ignored now.
RFC 9110 states:
> An origin server MUST ignore a Range header field that contains a
> range unit it does not understand.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Fri, 13 Feb 2026 14:54:57 +0100 |
| parents | d7f2ffc25273 |
| children | b688908622a1 79a6598cef0b |
| files | plugins/mod_http_file_share.lua |
| diffstat | 1 files changed, 7 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/mod_http_file_share.lua Wed Feb 11 11:38:55 2026 +0000 +++ b/plugins/mod_http_file_share.lua Fri Feb 13 14:54:57 2026 +0100 @@ -431,23 +431,22 @@ local request_range = request.headers.range; local response_range; - if request_range then - local last_byte = string.format("%d", tonumber(filesize) - 1); + -- "bytes=0-" just means "the whole file", so ignore it along with non-byte-range requests + if request_range and request_range ~= "bytes=0-" and request_range:find("^bytes=") then + local size = tonumber(filesize); + local last_byte = string.format("%d", size - 1); 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_end == "" or range_end == last_byte) then - local pos, size = tonumber(range_start), tonumber(filesize); + if range_end == "" or range_end == last_byte then + local pos = tonumber(range_start); local new_pos = pos < size and handle:seek("set", pos); if new_pos and new_pos < size then - response_range = "bytes "..range_start.."-"..last_byte.."/"..filesize; + response_range = string.format("bytes %d-%d/%s", range_start, last_byte, filesize); filesize = string.format("%d", size-pos); else handle:close(); return 416; end - else - handle:close(); - return 416; end end
