Repository navigation
Conversation
stream_episode served local files via tower_http ServeFile but built the inner request with no headers, so the client Range header was dropped and every response was 200 + full body. iOS AVPlayer re-fetched from byte 0 on each buffer refill, making YouTube playback restart every ~60s. Forward Range/If-Range/If-Modified-Since/If-None-Match/If-Unmodified-Since into the ServeFile request so it can answer 206 Partial Content.
This was referenced Oct 18, 2026
Contributor
Author
|
@madeofpendletonwool for when you get to this one: @ashtonian has opened #1012, which keeps this commit as-is and builds on it. It tightens the If-Range handling, returns the right response for HEAD requests, and adds regression tests for the streaming endpoint. I'm happy either way. If you'd rather take the fuller version, merge #1012 and I'll close this. If you'd prefer to land the small fix first, this one is ready and #1012 can sync on top of it. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #980.
Independent implementation of the fix @davegallant diagnosed in #980. Their fork commit forwards
Range; this also forwardsIf-Rangeand the other conditional headers (see Change).What
stream_episodeserves downloaded and local episode files throughtower_http'sServeFile, which handles HTTP range requests. But it builds the inner request with an empty body and no headers, so the client'sRangeheader is discarded beforeServeFileever sees it. Every response is a200 OKwith the full file and no206 Partial Contentis produced - even though the response still advertisesAccept-Ranges: bytes.This forwards the range and conditional headers (
Range,If-Range,If-Modified-Since,If-None-Match,If-Unmodified-Since) from the incoming request onto the request handed toServeFile, so it can answer with206when the client asks for a byte range.Why it matters
Clients that depend on range requests to seek and to buffer ahead - the iOS native player (AVPlayer) most notably - treat a full-file
200where they expected a206as a brand-new resource load. Playback then jumps back to the start on roughly every buffer refill, which makes downloaded and YouTube episodes unusable on iOS. RSS episodes streamed straight from the publisher are unaffected, since those requests never reach this endpoint. Seeking also could not work on any client, because the server always returned the whole file from byte 0.Change
Add a
HeaderMapextractor tostream_episodeand copy the range and conditional headers onto theServeFilerequest. Only those headers are forwarded; the API key stays in the query string as before.Forwarding
If-Rangeas well asRangemeans that if the file on disk changes between requests - for example a server-side re-download replacing the mp3 -ServeFilecorrectly falls back to a full200rather than splicing new bytes onto the client's stale partial.Testing
Built the
rust-apicrate against this branch, then checked a running instance:Range: bytes=0-1023now returnsHTTP/1.1 206 Partial ContentwithContent-Range: bytes 0-1023/<total>andContent-Length: 1024.Rangeheader still returnsHTTP/1.1 200 OKwith the full file.