Range with last-pos beyond EOF returns 416 instead of being clamped
Problem
A range whose last-pos exceeds the file size is rejected with 416, but per RFC 9110 it is satisfiable and last-pos should be clamped.
§14.1.2:
If the last-pos value is absent, or if the value is greater than or equal to the current length of the representation data, the byte range is interpreted as the remainder of the representation (i.e., the server replaces the value of last-pos with a value that is one less than the current length of the selected representation).
Minimal repro:
$ mkdir /tmp/dufs-repro && cd /tmp/dufs-repro
$ printf 'hello' > a.txt # 5 bytes
$ dufs & # serves /tmp/dufs-repro on port 5000
$ sleep 1 # wait for the listener
$ curl -si -H 'Range: bytes=0-9' http://127.0.0.1:5000/a.txt
HTTP/1.1 416 Range Not Satisfiable
content-range: bytes */5Expected: 206 Partial Content, content-range: bytes 0-4/5, body hello.
| Range | Actual | Expected |
|---|---|---|
bytes=0-4 |
206 bytes 0-4/5 |
same — OK |
bytes=0-5 |
416 | 206 bytes 0-4/5 |
bytes=0-9 |
416 | 206 bytes 0-4/5 |
bytes=5- |
416 | same — OK |
first-pos is within the file in every failing case, so these ranges are satisfiable and last-pos should be clamped rather than the range rejected.
Impact
Observed with Material Files on Android (okhttp/4.12.0): it issued a GET with Range: bytes=0-1048575 for a 442564-byte .mp4, dufs returned 416, and the download failed. Other files in the same directory downloaded fine, so the client appears to use ranged requests only for some files.
Configuration
None — reproduced with default settings (dufs with no arguments).
Log
From the original Android case (--log-format '$remote_addr "$request" $status $http_range $http_user_agent'):
192.168.2.101 "OPTIONS /dufs/aa.mp4" 200 - okhttp/4.12.0
192.168.2.101 "PROPFIND /dufs/aa.mp4" 207 - okhttp/4.12.0
192.168.2.101 "GET /dufs/aa.mp4" 416 bytes=0-1048575 okhttp/4.12.0Screenshots/Media
N/A — reproducible with curl alone.
Environment Information
- Dufs version:
dufs 0.46.0 - Browser/Webdav info: Material Files (Android, okhttp/4.12.0); minimal repro uses curl only
- OS info: NixOS (server), Android (client)
- Proxy server (if any): none
Happy to open a PR if you agree with this reading.
Source: sigoden/dufs