Expand description
A loopback HTTP server for locally downloaded media.
Tauri’s built-in asset protocol cannot serve a downloaded film to the
webview. Its response to a request without a Range header reads the whole
file into a Vec<u8>, and it only advertises Accept-Ranges: bytes from
inside the range branch — so the first request never learns ranges are
available and a multi-gigabyte body is attempted instead. Chromium abandoned
it with PIPELINE_ERROR_READ after ~31s, which reached the user as
“downloaded video does not play offline”.
Serving over real HTTP on 127.0.0.1 rather than a custom URI scheme is
deliberate: it makes range support a property of the transport instead of
depending on whether a platform’s webview forwards Range to a custom
scheme, which differs between Android and the desktop webviews.
Two things confine it, because loopback is shared between apps on Android — any other installed app can connect to this port:
- it binds
127.0.0.1only, so nothing off-device can reach it; and - every URL carries a random per-session token, so another app cannot guess a working URL, and paths are confined to the app data directory even if one did.
Phase 1 serves local files only. The same origin is the intended home for remote passthrough (and download-while-watching) later; see the stage-2 spec.
TRACES: UR-071 | DR-137 | UT-127
Structs§
- Media
Server - A running server. Dropping this does not stop the thread; the server lives for the life of the process by design, since playback can start at any time.
- Media
Server Wrapper - Managed state.
Nonewhen the server could not bind — local playback then fails with a clear error instead of the app refusing to start. - Span
- The byte range a response should carry.
endis inclusive.
Enums§
- Resolved
- What a request path resolved to, before any file is touched.
Constants§
- CHUNK_
LEN 🔒 - Bytes per response. Large enough that a film needs relatively few round trips, small enough that one response is never a memory problem on a phone. Tauri’s asset protocol uses 1 MiB; 4 MiB quarters the request count for the multi-gigabyte files this exists to serve.
Functions§
- content_
type 🔒 - Guess a content type.
- empty 🔒
- handle 🔒
- header 🔒
- resolve_
path - Resolve a percent-encoded request path to a file inside
root. - route 🔒
- Check the token and resolve the path, or return the status to answer with.
- span_
for - Decide which span to send for a
Rangeheader (or its absence). - start
- Bind to an ephemeral loopback port and start serving
rootin a background thread.