Files
silo-server/docs/architecture/direct-stream-resume.md
QuickandGitHub 90bdbfeb84 fix(playback): expose conditional range outcomes (#594)
* fix(playback): expose conditional range outcomes

* fix(playback): classify rejected If-Range requests

* fix(playback): evaluate If-Range diagnostics directly
2026-08-11 10:31:39 -04:00

58 lines
3.1 KiB
Markdown

# Direct Stream Resumption
Protocol v3 advertises `direct_stream_resume_v1` for playback plans whose
delivery is `original_http`. The capability formalizes resumption of the
original file by issuing sequential authorized HTTP requests. It does not
change authentication, authorization, or playback-session ownership.
Original-file responses follow the HTTP byte-range contract:
- `Accept-Ranges: bytes` advertises byte addressing.
- A satisfiable `Range` request returns `206 Partial Content` with the selected
interval in `Content-Range`.
- Open-ended and suffix byte ranges are supported.
- A range starting at or past end of file, or another invalid range, returns
`416 Requested Range Not Satisfiable` with `Content-Range: bytes */<size>`.
- `HEAD` returns the same representation headers as `GET` without a body.
On Linux, macOS, and Windows, each response carries a strong, opaque `ETag`
derived from the open file's filesystem identity, change time, modification
time, and size. The validator is stable while the playback plan's original-file
entity is unchanged, but changes for same-size replacements even when their
modification time is preserved. Platforms that cannot expose a durable
filesystem revision omit the validator instead of hashing an entire media file
before each request. On those platforms an ETag-based `If-Range` request cannot
match and safely falls back to a full `200 OK` response.
A client resuming a transfer sends both `Range` and `If-Range` with the
validator. When it still matches, the server returns the requested `206`
response. When the entity changed, the server ignores the range and returns the
entire current entity as `200 OK`, preventing bytes from different revisions
from being combined. `If-None-Match` uses the same validator for ordinary
conditional requests.
For a bounded chunk read, a client can instead send `Range` and `If-Match`.
When the validator matches, the server returns the requested `206` interval.
When it does not match, the server returns `412 Precondition Failed` without a
body. This contract avoids materializing a full entity when a bounded read's
validator is stale. It does not change `If-Range`: an `If-Range` mismatch still
ignores the range and returns the full current entity as `200 OK`, as required
by the HTTP range contract.
Direct-stream completion logs record whether `If-Match` and `If-Range` were
present, a bounded conditional-result value, and short SHA-256 fingerprints for
the emitted and requested validators. The raw validators and media path are not
logged. The fingerprints are only correlation aids and are not protocol
validators.
Playback sessions already treat each transport request independently.
Sequential ranged requests refresh transport activity, and cleanup never
expires a session while one of those transport requests is active. A late
request within the paused-session grace remains valid under the same rules as
the initial request.
The capability does not apply to progressive remux delivery
`server_remux_progressive`, which is not byte-resumable. It applies only to
`original_http`; remux and transcode transports retain their existing
contracts.