mirror of
https://github.com/sigoden/dufs.git
synced 2026-06-07 15:59:03 +03:00
[GH-ISSUE #714] Regression in v0.46.0: directory upload via drag-and-drop returns 404 due to guard_root_contained() #8817
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @nirvana6 on GitHub (May 27, 2026).
Original GitHub issue: https://github.com/sigoden/dufs/issues/714
Bug Description
Dragging a directory onto the dufs web UI causes all files to queue with status
-and then fail with 404 Not Found. Single file uploads to the root directory work fine.Root Cause
This is a regression introduced in v0.46.0 by PR #670 ("fix: ensure symlink inside serve root").
Before v0.46.0 (v0.45.0)
The root containment check was:
When
is_miss = true(path does not exist yet),!is_missisfalse, so the entire condition isfalseand the request proceeds tohandle_upload(), which callsensure_path_parent()to create the parent directory.v0.46.0 (current)
PR #670 replaced the above with
guard_root_contained():This check is unconditional — it runs for all requests regardless of whether the path exists. The function tries to handle non-existent paths by checking the parent:
But when uploading
PUT /subdir/file.txtwheresubdir/does not exist yet:fs::try_exists(path)→false(file does not exist)path.parent()→subdir/is_root_contained(subdir/)callsfs::canonicalize(subdir/)which fails becausesubdir/does not exist yet.ok().map(...).unwrap_or_default()→falseguard_root_containedreturns!false→truehandle_upload()is reachedensure_path_parent()insidehandle_upload()— which would createsubdir/— is never calledReproduction
--allow-upload-, then show✗with tooltip "404 Not Found"Single file uploads to the root directory work correctly because the parent (
.) already exists.Suggested Fix
In
guard_root_contained(), walk up the directory tree until an existing ancestor is found, then canonicalize that:This way, for
PUT /subdir/file.txtwhere neither the file norsubdir/exists, it walks up to.(the serve root), which does exist and canonicalizes correctly.Workarounds
allow-symlink: true(bypasses the guard entirely — safe for personal use sinceresolve_path()still blocks..traversal)Environment
@florinm03 commented on GitHub (May 30, 2026):
Why close this? 👀 Or has it been fixed? @sigoden