comparison plugins/mod_http_file_share.lua @ 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 9974b210d620
children b688908622a1
comparison
equal deleted inserted replaced
14070:d7f2ffc25273 14073:dfbc60d47668
429 return 410; 429 return 410;
430 end 430 end
431 431
432 local request_range = request.headers.range; 432 local request_range = request.headers.range;
433 local response_range; 433 local response_range;
434 if request_range then 434 -- "bytes=0-" just means "the whole file", so ignore it along with non-byte-range requests
435 local last_byte = string.format("%d", tonumber(filesize) - 1); 435 if request_range and request_range ~= "bytes=0-" and request_range:find("^bytes=") then
436 local size = tonumber(filesize);
437 local last_byte = string.format("%d", size - 1);
436 local range_start, range_end = request_range:match("^bytes=(%d+)%-(%d*)$") 438 local range_start, range_end = request_range:match("^bytes=(%d+)%-(%d*)$")
437 -- Only support resumption, ie ranges from somewhere in the middle until the end of the file. 439 -- Only support resumption, ie ranges from somewhere in the middle until the end of the file.
438 if (range_start and range_start ~= "0") and (range_end == "" or range_end == last_byte) then 440 if range_end == "" or range_end == last_byte then
439 local pos, size = tonumber(range_start), tonumber(filesize); 441 local pos = tonumber(range_start);
440 local new_pos = pos < size and handle:seek("set", pos); 442 local new_pos = pos < size and handle:seek("set", pos);
441 if new_pos and new_pos < size then 443 if new_pos and new_pos < size then
442 response_range = "bytes "..range_start.."-"..last_byte.."/"..filesize; 444 response_range = string.format("bytes %d-%d/%s", range_start, last_byte, filesize);
443 filesize = string.format("%d", size-pos); 445 filesize = string.format("%d", size-pos);
444 else 446 else
445 handle:close(); 447 handle:close();
446 return 416; 448 return 416;
447 end 449 end
448 else
449 handle:close();
450 return 416;
451 end 450 end
452 end 451 end
453 452
454 453
455 if not filetype then 454 if not filetype then