Bug Report
Version
tower-http 0.6.8
cargo tree | grep tower-http:
Platform
Linux 6.14.0-1017-oracle (Ubuntu 24.04.1)
Crates
tower-http (services::fs::ServeDir, services::fs::ServeFile)
Description
ServeDir / ServeFile do not support multipart range responses, but they still parse and validate multipart Range headers before later rejecting them with 416 Range Not Satisfiable.
Current flow is roughly:
open_file.rs::try_parse_range() calls http_range_header::parse_range_header(...).and_then(|p| p.validate(file_size))
- later,
future.rs::build_response() rejects ranges.len() > 1 with 416
So a request like:
Range: bytes=0-0,2-2,4-4,6-6
is guaranteed to be rejected, but still pays multipart validation cost first, with the validation step doing O(n²) pairwise overlap checks across ranges.
Since multipart responses are not supported here, it seems better to reject ranges.len() > 1 before calling validate(file_size).
A minimal fix seems to be:
- parse the header
- if there is more than one range, immediately return unsatisfiable
- only call validate(file_size) for single-range requests
Bug Report
Version
tower-http 0.6.8cargo tree | grep tower-http:tower-http v0.6.8Platform
Linux 6.14.0-1017-oracle (Ubuntu 24.04.1)
Crates
tower-http(services::fs::ServeDir,services::fs::ServeFile)Description
ServeDir/ServeFiledo not support multipart range responses, but they still parse and validate multipartRangeheaders before later rejecting them with416 Range Not Satisfiable.Current flow is roughly:
open_file.rs::try_parse_range()callshttp_range_header::parse_range_header(...).and_then(|p| p.validate(file_size))future.rs::build_response()rejectsranges.len() > 1with416So a request like:
Range: bytes=0-0,2-2,4-4,6-6is guaranteed to be rejected, but still pays multipart validation cost first, with the validation step doing
O(n²)pairwise overlap checks across ranges.Since multipart responses are not supported here, it seems better to reject
ranges.len() > 1before callingvalidate(file_size).A minimal fix seems to be: