WebDAV: in-flight upload temp files (.cairn-upload-*) appear in PROPFIND listings #495

Closed
opened 2026-09-11 21:03:57 +00:00 by Cordy · 1 comment
Owner

Status: verified at runtime against cairnd built from bd006ef; unchanged on main (e1c855d).

What happens

While a PUT is streaming, the posix driver's temp file sits in the target directory (internal/storage/posix/posix.go:156, CreateTemp) and is listed by PROPFIND. Observed during a rate-limited 3 MB PUT:

<D:href>/dav/home/</D:href>
<D:href>/dav/home/.cairn-upload-731916555</D:href>

After the upload completes, the listing shows slow.bin and the temp entry is gone.

Impact

Every other client sees a half-written file appear and vanish. A sync client may download the partial bytes, or later read its disappearance as a delete; a user may open or delete it. cairn-desktop now skips .cairn-upload-* names (its ruling P2-R14), but other WebDAV clients (Finder, rclone, mobile apps) will not.

Suggested fix

Filter the prefix out of List and Stat and add it to the reserved names (internal/storage/reserved/reserved.go) so users cannot create it — or stage temp files in a hidden spool directory on the same filesystem and rename into place.


Found while building the cairn-desktop WebDAV client (phase 2, Cordy/cairn-desktop#22). Filed by Claude on behalf of @Cordy.

**Status: verified at runtime** against cairnd built from `bd006ef`; unchanged on `main` (`e1c855d`). ## What happens While a `PUT` is streaming, the posix driver's temp file sits in the target directory (`internal/storage/posix/posix.go:156`, `CreateTemp`) and is **listed** by PROPFIND. Observed during a rate-limited 3 MB PUT: ``` <D:href>/dav/home/</D:href> <D:href>/dav/home/.cairn-upload-731916555</D:href> ``` After the upload completes, the listing shows `slow.bin` and the temp entry is gone. ## Impact Every other client sees a half-written file appear and vanish. A sync client may download the partial bytes, or later read its disappearance as a delete; a user may open or delete it. cairn-desktop now skips `.cairn-upload-*` names (its ruling P2-R14), but other WebDAV clients (Finder, rclone, mobile apps) will not. ## Suggested fix Filter the prefix out of List and Stat and add it to the reserved names (`internal/storage/reserved/reserved.go`) so users cannot create it — or stage temp files in a hidden spool directory on the same filesystem and rename into place. --- Found while building the cairn-desktop WebDAV client (phase 2, Cordy/cairn-desktop#22). Filed by Claude on behalf of @Cordy.
Author
Owner

Shipped in v0.6.169, live on both dogfoods.

What landed in the posix driver:

  • .cairn-upload-* (and .cairn-replace-* staging names from #496) are now invisible to every read path: List skips them, Stat/Open on such a name → ErrNotFound.
  • Users can't create or collide with them either: Write/Mkdir on a hidden name → ErrInvalidPath. The driver's own temp files bypass the guard via os.Root directly, so uploads are unaffected.
  • copyFile was made atomic on the way through (temp + rename, same retry loop as Write), so COPY no longer exposes half-written destinations.

TDD: temp_test.go fixtures plant stray temp files via os directly and assert invisibility — witnessed red first. Orphaned temps from a crashed upload no longer surface in listings, WebDAV PROPFINDs, or sync clients.

Shipped in **v0.6.169**, live on both dogfoods. What landed in the posix driver: - `.cairn-upload-*` (and `.cairn-replace-*` staging names from #496) are now invisible to every read path: `List` skips them, `Stat`/`Open` on such a name → `ErrNotFound`. - Users can't create or collide with them either: `Write`/`Mkdir` on a hidden name → `ErrInvalidPath`. The driver's own temp files bypass the guard via `os.Root` directly, so uploads are unaffected. - `copyFile` was made atomic on the way through (temp + rename, same retry loop as `Write`), so COPY no longer exposes half-written destinations. TDD: `temp_test.go` fixtures plant stray temp files via `os` directly and assert invisibility — witnessed red first. Orphaned temps from a crashed upload no longer surface in listings, WebDAV PROPFINDs, or sync clients.
Cordy closed this issue 2026-09-12 16:35:51 +00:00
Sign in to join this conversation.
No labels
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#495
No description provided.