- _file_etag streams a SHA-256 digest through the already-authorized fd
instead of using mtime+size metadata, so same-size in-place replacements
on coarse-mtime filesystems (2s granularity) produce a new ETag — the
exact stale-cache bug this feature sets out to fix. fd is rewound before
the normal/Range send.
- close fd on the 304 early-return path (was leaking a descriptor per
revalidated hit)
- drop Content-Length: 0 from 304 responses (RFC 9110 §15.4.5)
- non-HTML /api/media cache policy is now "private, no-cache" so shared
intermediary caches cannot store per-user/per-session media
- regression test: equal-size + equal-mtime (ns-pinned) replacement must
change the ETag and return 200, not a stale 304