Commit Graph
6 Commits
Author SHA1 Message Date
b7b571d469 webdav: copy a file onto a collection URL without losing the collection (#12068)
* webdav: copy a file onto a collection URL without losing the collection

An overwriting COPY of a file to dir/ removed dir, then OpenFile refused
the name ending in / and the request failed with 403, leaving neither.
Drop the trailing slash from the destination when the source is a file.

* webdav: cover file-over-collection COPY through the real handler

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* webdav: keep a root destination out of the slash trim

A file COPY or MOVE onto / would rewrite the Destination to an empty
path, turning the existing refusal into x/net's bad-gateway error; leave
the root untouched so RemoveAll refuses it as before.

---------

Co-authored-by: user.email <chrislusf@users.noreply.github.com>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-26 06:08:24 -07:00
863efb3d35 webdav: delete a folder with its contents (#11811)
* webdav: delete a folder with its contents

* webdav: guard the recursive delete against stale and confined paths

- propagate stat lookup errors instead of returning an error-bearing
  FileInfo: OpenFile and DELETE would otherwise take the recursive
  removeAll on a path whose type was never confirmed, wiping a
  directory on a transient filer error
- refuse wrappedFs.Rename from or to the served root, matching the
  RemoveAll guard and webdav.Dir
- normalize trailing slashes in removeAll so the delete names the
  entry itself, and refuse the root for every caller

* webdav: keep file-only deletes shallow and refuse ancestor destinations

- removeAll used by OpenFile and failed-upload cleanup now deletes
  non-recursively, so a folder swapped in after the stat check is not
  emptied by a pending file delete
- MOVE and COPY whose destination contains the source are refused
  before the handler removes the destination, which would otherwise
  take the source down with it

* webdav: also refuse a destination inside the source

a MOVE or COPY into its own subtree recurses into the destination it
just created; refuse it with the same guard instead of burning the
recursion budget for a 500

* webdav: allow a shallow copy into the source subtree

a COPY with Depth: 0 creates only the destination collection and never
reads children, so it is safe inside the source; only deep copies and
moves are refused there

* webdav: refuse a copy/move whose source is unreadable

* webdav: cover the missing-source refusal in the guard test

* webdav: 500 on a source lookup failure, 404 only when absent

---------

Co-authored-by: Chris Lu <chris.lu@gmail.com>
Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
2026-10-18 12:57:10 -07:00
Jay HemnaniandChris Lu 006d4150f0 webdav: create a folder under its own name (#11810)
* webdav: create a folder under its own name

* webdav: reuse NormalizePath for the MKCOL entry split

---------

Co-authored-by: Chris Lu <chris.lu@gmail.com>
2026-10-18 11:43:19 -07:00
Jay Hemnani 3659c369e0 webdav: read small files stored inline in the entry (#11733) 2026-10-15 06:38:53 -07:00
Bruce ZouandChris Lu ea179963c0 filer: clean up manifest resolve error propagation and add webdav tes… (#11297)
filer: clean up manifest resolve error propagation and add webdav test (#78)

Drop GitHub issue references from comments and trim verbose comments.
Replace the viewFromChunksOrErr helper with the existing
NonOverlappingVisibleIntervals + ViewFromVisibleIntervals at the stream
call sites, and add a WebDavFile.Read regression test for the manifest
resolution failure path.

Co-authored-by: Chris Lu <chrislusf@users.noreply.github.com>
2026-09-13 18:34:09 -07:00
Chris Lu e9a464840c webdav: describe a listed entry the way clients expect (#10993)
* webdav: name the entry, not its path, in a listing

DAV:displayname carried the full path of every entry. A client that
takes displayname for the child's name - Windows Explorer does - then
looks for /dir/name under /dir and finds nothing, so a folder shows up
empty while the root, where the two spellings differ only by a leading
slash, still lists.

Readdir now builds its entries with toFileInfo like stat does, so a
listing and a lookup describe a child the same way, and the wrapper that
was trimming the sub-folder back off a name goes away with it.

Claude-Session: https://claude.ai/code/session_01XCeuCWpF9xo9CfyHvCQE9c

* webdav: derive an ETag when nothing hashed the entry

Uploads through this gateway carry no content MD5, so filer.ETag comes
back empty and every file in a PROPFIND answered with an empty
DAV:getetag, which is not a valid entity-tag. Report it as unimplemented
instead, the way the sub-folder wrapper already did, and webdav falls
back to modification time and size. The wrapper's copy went with it - it
swallowed the stat error a caller was meant to see.

Claude-Session: https://claude.ai/code/session_01XCeuCWpF9xo9CfyHvCQE9c
2026-08-27 16:21:14 -07:00