WebDAV
Edit the files in your Yatta storage from any WebDAV client: Finder, Windows Explorer, or a command line tool. No extra setup.
WebDAV is file access over plain HTTP. Your Yatta server already serves it on /dav, backed by the same storage engine as uploads. Files you put there are the same files the storage engine sees.
Upload and download
PUT stores a file. The first PUT answers 201; putting the same path again overwrites it and answers 204.
# Upload a file — 201 the first time, 204 on overwritecurl -X PUT --data-binary @report.pdf http://localhost:4000/dav/report.pdf # Download it backcurl http://localhost:4000/dav/report.pdf -o report.pdf # Just the headers, no bodycurl -I http://localhost:4000/dav/report.pdfGET on a folder does not return XML. It returns a plain text list, one path per line, with a trailing slash on folders — and (empty) when there is nothing in it.
curl http://localhost:4000/dav/docs/ # Answerreport.pdfnotes/# (empty) if the folder has nothing in itMake folders, move, copy
MKCOL makes one folder. Its parent must already exist, or you get a 409.
# Make a folder — 201curl -X MKCOL http://localhost:4000/dav/docs # Move a file into it — 201 (or 204 if it overwrites)curl -X MOVE \ -H "Destination: http://localhost:4000/dav/docs/report.pdf" \ http://localhost:4000/dav/report.pdf # Copy instead of moving — the source stays putcurl -X COPY \ -H "Destination: http://localhost:4000/dav/docs/report-copy.pdf" \ http://localhost:4000/dav/report.pdf # Delete a file or an empty folder — 204curl -X DELETE http://localhost:4000/dav/docs/report-copy.pdf/dav. A destination on another host, or outside /dav, is refused with a 400. A destination that already exists is refused with a 412 — there is no overwrite flag. And a destination inside the source itself is refused with a 400.List with PROPFIND
PROPFIND returns XML, not a plain list. Depth 0 describes just the path you asked about; Depth 1 adds its children. Send one of those two — leaving Depth out answers 403.
curl -X PROPFIND -H "Depth: 1" http://localhost:4000/dav/docs/ # Answer (shortened) — 207 Multi-Status<D:multistatus xmlns:D="DAV:"> <D:response> <D:href>/dav/docs/</D:href> <D:propstat><D:prop> <D:displayname>docs</D:displayname> <D:resourcetype><D:collection/></D:resourcetype> </D:prop></D:propstat> </D:response> <D:response> <D:href>/dav/docs/report.pdf</D:href> <D:propstat><D:prop> <D:displayname>report.pdf</D:displayname> <D:resourcetype/> <D:getcontentlength>18204</D:getcontentlength> </D:prop></D:propstat> </D:response></D:multistatus>Properties on every entry
displaynameresourcetypegetcontentlengthLock a file
LOCK takes an exclusive write lock. Other writes to that path are then refused with a 423 until you unlock it or show the token. A lock on a folder covers everything under it.
# Lock — the answer carries the token in the Lock-Token headercurl -X LOCK -H "Content-Type: application/xml" \ --data '<D:lockinfo xmlns:D="DAV:"><D:lockscope><D:exclusive/></D:lockscope><D:locktype><D:write/></D:locktype><D:owner>ada</D:owner></D:lockinfo>' \ http://localhost:4000/dav/report.pdf# Lock-Token: <opaquelocktoken:abc123> # Write without the token — 423 Lockedcurl -X PUT --data-binary @new.pdf http://localhost:4000/dav/report.pdf # Write with the token — goes throughcurl -X PUT -H "Lock-Token: <opaquelocktoken:abc123>" \ --data-binary @new.pdf http://localhost:4000/dav/report.pdf # Unlock — 204 (a wrong token gets 409)curl -X UNLOCK -H "Lock-Token: <opaquelocktoken:abc123>" \ http://localhost:4000/dav/report.pdfA lock lasts until you unlock it, or until the Timeout you asked for runs out. Ask with a Timeout header in seconds — the longest it can be is 24 hours.
Methods
OPTIONSGETHEADPUTMKCOLDELETEMOVE / COPYLOCKUNLOCKPROPFIND/dav behind a proxy or middleware that checks who the caller is.