Conversation
…page The viewer read the whole file through the filesystem API and handed the media element a base64 data URI. That caps at 16MB, costs about three times the file in memory - the byte array, the intermediate strings, and the base64, which is itself a third larger - and cannot start playing or seek until all of it has been read and encoded. Anything longer than a short clip either refused to open or made the window sit still while it loaded. Serve the file from node instead, over the http server that is already running, and hand the element a url. The bytes never reach the renderer, so the cap stops applying and memory is one stream buffer rather than the whole file. The route answers byte ranges, which is what lets the element ask for the piece it needs: without that it cannot seek at all, and pulls everything to play anything. Any readable path is served, not only paths under the open project, since the editor can open media from anywhere. Nothing is registered first - the path rides in the query string, url encoded, so the viewer's whole job is building a string and there is no round trip to wait on and no state on either side to keep in step. It is absolute or it is refused, or a relative one would resolve against node's working directory. The route is guarded like every other route on this server, by the large random prefix chosen at startup, and that is the whole of it: reaching it means running code in the renderer, and renderer code can already read any file it likes through the filesystem API. Unlike the static route it sends no Access-Control-Allow-Origin, since a media element does not need one and other origins have no business reading local files. The browser build keeps the data URI. There is no node there to serve from, which is also why the size limit and its message still apply.
MCP is off outside dev builds, which is right for a program that can run arbitrary code in the user's editor, but it also meant a production problem could not be looked at with the tools that exist for looking at one. An admin can now permit it, by writing a date into the system override file. That file lives in a directory only root can write, so the fact of it being there is itself the proof an admin put it there - the same reasoning the update url override already relies on. It is a date rather than a flag because boot cannot read files: doing so would slow every start for a permission almost no machine has, so boot reads a copy cached in local storage instead, and a date means a copy left behind after the file is gone is worthless on any other day. The date is matched strictly against today, as text, so a malformed one fails closed rather than being read as something permissive. The permission is the whole of the setup. The app writes the builder's own enabled flag from it, since asking an admin to also type a command into the console of every machine would add a step without adding a decision. In dev that flag is left alone: it is the user's switch there, and the file plays no part in the gate. While something is connected, the window says so in the status bar, in a colour meant to be noticed. Shown on connection rather than on being allowed, because a build that merely permits instrumentation is not being instrumented, and what is worth telling the user is that someone is on the other end right now. Not shown in dev, where being driven by the builder is the ordinary way of working and a permanent badge would only be noise.
…uild Everything needed to instrument a production build was in the source, so using it meant reading the source. The dialog now says how, with the commands already filled in for this machine: the path comes from SystemConfigOverride rather than being written out a second time, so the two cannot drift, and the date is today's, which is the one that will work. It switches to Windows syntax on Windows. It explains why each step is there as well as what to type - why a root owned folder is what proves an admin allowed it, why the permission expires by itself, and why the app has to start twice before it takes. Knowing that is what stops the second restart looking like a bug.
|
| // spaces, & and # are what a query string is least happy about, and | ||
| // a real file can have all three | ||
| const info = await nodeConnector.execPeer("startMediaTestServer"); | ||
| const awkward = info.path.replace(/fixture\.mp4$/, "fixture.mp4"); |
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.



Three separate changes, one commit each.
Stream video and audio instead of reading them into the page
The media viewer read the whole file through the filesystem API and handed
the element a base64 data URI. That caps at 16MB, costs roughly three times
the file in memory — the byte array, the intermediate strings, and the
base64, which is itself a third larger — and cannot start playing or seek
until all of it has been read and encoded.
Node now serves the file over the http server already running, and the
viewer hands the element a url. The bytes never reach the renderer, so the
cap stops applying and memory is one stream buffer rather than the file.
The route answers byte ranges, which is what lets the element seek at all —
without it, it pulls everything to play anything.
Any readable path is served, not only paths under the open project, since
the editor can open media from anywhere. Nothing is registered first: the
path rides in the query string, url encoded. It must be absolute, or a
relative one would resolve against node's working directory.
Guarded by the same random route prefix as every other route on that
server, and that is the whole of it — reaching it means running code in
the renderer, which can already read any file through the filesystem API.
Unlike the static route it sends no
Access-Control-Allow-Origin.The browser build keeps the data URI; there is no node there to serve from,
which is also why the size limit still applies there.
Let an admin instrument a production build, for one day
MCP is off outside dev builds, which is right for something that can run
arbitrary code in the editor, but it meant a production problem could not
be looked at with the tools that exist for looking at one.
An admin can now permit it by writing a date into the system override file.
That file lives in a directory only root can write, so its presence is
itself the proof an admin put it there — the same reasoning the update url
override already relies on. A date rather than a flag because boot reads no
files, to keep startup quick; it consults a copy cached in local storage,
and a date means a copy left behind after the file is gone is worthless on
any other day. Matched strictly against today, as text, so a malformed date
fails closed.
While something is connected the window says so in the status bar, in a
colour meant to be noticed. Shown on connection rather than on being
allowed, and not in dev, where being driven by the builder is ordinary.
A Production tab in the builder dialog
Using the above previously meant reading the source. The dialog now says
how, with the commands filled in for the machine it is running on — the
path comes from
SystemConfigOverriderather than being written out asecond time, so the two cannot drift.
Testing
unit:Media Server— 15 new specs: ranges, clamping, 416, 400s, 404s,the absent CORS header, and posix / Windows / UNC path classification so
the Windows behaviour is covered from any host
unit: Tauri Platform Tests— 48/48, matching baselineold cap, seeking to 120s, a file outside the project, and a filename
containing a space,
&and#Known gaps
confirmed
phtauri://drives byte ranges againsthttp://localhost, soit is expected to hold, but every run since has been the dev build.
not be created in testing. The read, parse, allowlist filter, cache write
and revocation are all covered; a real file appearing there is not.