Commit Graph
3 Commits
Author SHA1 Message Date
Mitchell-JohnsonandClaude Fable 5.1 285278abdb A sweep of the whole console: status codes, a data race, atomic writes, dead code
From the race detector, staticcheck, a garbage-in battery over every safe route and a
headless pass through every tab on two machines. Fixed:
- docker inspect/health of a container that isn't there answered 500; now 404, and a
  daemon that is down 503 (dockerErr, with a test).
- /api/virt/instances/{name} on a machine without Incus answered 502 "incus not found";
  it now says Incus isn't ready, like its siblings.
- Deleting a ZFS snapshot with a bad name answered 500; a bad name is 400, a snapshot
  that doesn't exist 404.
- The task list read a task's Running flag without the task's lock while the waiter
  goroutine cleared it: a data race, now read under the lock.
- The Virtualization export config and run record were written in place; a crash
  mid-write would have left a half file. Atomic now, like the config and state files.
- An unused function in kvm.go, one in incus/subnet.go, an unused field in files/move.go
  and a capitalised error string, from staticcheck.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-13 17:52:18 -07:00
Mitchell-JohnsonandClaude Fable 5.1 1038c010fa Files: a sweep of the edges
Found by walking every handler and the UI with odd inputs, then a battery of requests
against the live hub. Fixed:
- A save over the 8 MiB cap was cut short in place: the file was truncated, then the
  first 8 MiB written, and the caller told 204. Now the body is read whole first and a
  body over the cap is a 413 with the file untouched.
- A link to a file showed the link's own time; now the file's, so the row reads right
  and the preview key follows the file.
- Reading a link to nothing answered 200 with an empty body (the open failed after the
  headers in root mode); now a 404 that names the target.
- A play request with an unknown codec or size was answered by inspecting the file
  first, so an audio-only file said "no video stream" instead of what was wrong; the
  choice is checked before any work, and is a 400.
- A stream that ended in failure was handed back to the next identical request for ten
  minutes; a failed one is now dropped and a fresh one made.
- A player that left while its stream was still finding a first segment made the loop
  try the next recipe; it stops. A stream closed mid-start is not started again.
- Ending a root-mode ffmpeg could wait forever: the daemon cannot signal root's
  processes, so the wait is bounded and the helper's own grace does the rest.
- A page going away (a phone closing the tab) releases its stream by a beacon, rather
  than ten minutes later by the sweeper.
- The path box resolves like a shell — relative to the folder shown, . and .. applied,
  trailing slashes dropped — in the tab and in the Move picker, with a test. A typed path
  that is a file opens it; a remembered folder that is gone falls back to / once.
- A dropped folder arrived as a nameless empty file; it is refused with a word. The
  upload toast counts what was actually uploaded.
- The viewer names a device, pipe or socket, and a dangling link, instead of calling
  them binary files.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 20:31:10 -07:00
Mitchell-JohnsonandClaude Fable 5.1 a9bcb88212 Files: play video and audio in the viewer, as the file is; reads answer Range requests
The viewer hands a video or audio file to the browser untouched — container, codec and
all — and the browser plays what it can; when it can't, the viewer says so and offers the
download. What the server adds is the part a player needs: /api/files/read now goes
through http.ServeContent for a real file of known size, so Range requests (seeking) and
HEAD work, and a download can resume. The root backend's helper takes an offset for that,
and a Seeker opens the backend once, at the range asked for, instead of streaming from
the top. Audio files are a preview kind too: their cover art is the thumbnail.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-11 16:40:42 -07:00