navidrome/core/stream
TowyTowy 8d77a06ea0 fix(stream): revalidate repeated transcode requests with a weak ETag
Transcoded stream responses only carried Last-Modified (the source file's
mtime, which is identical across every bitrate/format/offset), so a client
had no cheap way to confirm it already holds a specific transcoded
representation and re-downloaded the full audio on every repeat request
within a single playback.

Advertise a weak, representation-specific ETag derived from the transcode
cache key (id, mtime, bitrate, format, sampleRate, bitDepth, channels,
offset). On the fully-cached seekable path http.ServeContent now answers a
matching If-None-Match with 304 Not Modified instead of re-sending the
audio, cutting redundant transfer for repeated in-playback requests. The
tag is weak because ffmpeg output is not guaranteed byte-identical across
runs; it stays valid for If-None-Match revalidation while http.ServeContent
correctly declines to use it for If-Range sub-range assembly.

Fixes #5720

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: TowyTowy <towy@airreps.link>
2026-07-09 12:24:44 +02:00
..
aliases.go fix: use ADTS for AAC transcoding, temporarily exclude AAC from transcode decisions (#5167) 2026-03-11 09:26:32 -04:00
aliases_test.go fix: use ADTS for AAC transcoding, temporarily exclude AAC from transcode decisions (#5167) 2026-03-11 09:26:32 -04:00
codec.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
codec_test.go fix(transcoding): clamp target channels to codec limit (#5336) (#5345) 2026-04-11 23:15:07 -04:00
decider.go feat(smartplaylist): extend isMissing/isPresent to bpm, bitDepth and many text fields (#5603) 2026-06-13 13:15:20 -04:00
decider_test.go feat(smartplaylist): extend isMissing/isPresent to bpm, bitDepth and many text fields (#5603) 2026-06-13 13:15:20 -04:00
legacy_client.go fix(transcoding): enforce server-side player MaxBitRate on /rest/stream (#5611) 2026-06-14 16:52:01 -04:00
legacy_client_test.go fix(transcoding): enforce server-side player MaxBitRate on /rest/stream (#5611) 2026-06-14 16:52:01 -04:00
limitations.go refactor: rename core/transcode to core/stream, simplify MediaStreamer (#5166) 2026-03-09 22:22:58 -04:00
limiter.go fix(transcoding): cap concurrent transcodes to prevent ffmpeg DoS (#5522) 2026-05-24 00:24:30 -03:00
limiter_test.go fix(transcoding): cap concurrent transcodes to prevent ffmpeg DoS (#5522) 2026-05-24 00:24:30 -03:00
media_streamer.go fix(stream): revalidate repeated transcode requests with a weak ETag 2026-07-09 12:24:44 +02:00
media_streamer_test.go fix(stream): revalidate repeated transcode requests with a weak ETag 2026-07-09 12:24:44 +02:00
stream_suite_test.go refactor: rename core/transcode to core/stream, simplify MediaStreamer (#5166) 2026-03-09 22:22:58 -04:00
token.go refactor(stream): remove dead type branches from getIntClaim (#5594) 2026-06-10 23:15:58 -04:00
token_test.go refactor: rename core/transcode to core/stream, simplify MediaStreamer (#5166) 2026-03-09 22:22:58 -04:00
types.go fix(transcoding): honor player forced format on the WebUI transcode flow (#5613) 2026-06-14 20:52:19 -04:00
types_test.go fix(transcoding): honor player forced format on the WebUI transcode flow (#5613) 2026-06-14 20:52:19 -04:00