* fix(playback): expose conditional range outcomes * fix(playback): classify rejected If-Range requests * fix(playback): evaluate If-Range diagnostics directly
58 lines
3.1 KiB
Markdown
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.
|