Documentation
¶
Overview ¶
Package dav exposes filex storages as a WebDAV server under /dav.
Layout: /dav/<storage-name>/<path> — the first path segment selects a configured storage; the (virtual) root collection lists every storage the authenticated caller may see. The heavy lifting is done by golang.org/x/net/webdav; this package contributes:
- HTTP Basic authentication (username = account e-mail OR the account's username, whichever the client typed; the password is tried first against the account password, then as an API token), see authenticate().
- A composite webdav.FileSystem bridging storage.Driver + its optional capability sub-interfaces (fs.go / file.go).
- Authorization: storage read_only flag, ACL/RBAC via internal/acl, and API-token verb scopes — enforced BOTH in a pre-gate here (so read-only / forbidden writes deterministically return 403; x/net/webdav maps filesystem errors to 404/405, never 403) AND inside the FileSystem (defense in depth).
- Class-2 locking via webdav.NewMemLS() so Windows drive mapping can write.
- Best-effort DB node-cache + search-index + thumbnail sync after mutations (dbsync.go) — a sync failure never breaks the WebDAV reply.
Kill switch: FILEX_DAV=0 (config.DAV.Enabled) — the handler then answers 404 for the whole subtree.
Index ¶
Constants ¶
const Prefix = "/dav"
Prefix is the URL prefix the handler is mounted at.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Enabled — FILEX_DAV kill switch. When false ServeHTTP answers 404.
Enabled bool
Store db.Store
// Resolver returns the live storage.Driver for a storage id (the same
// resolver the API handlers use).
Resolver func(int64) (storage.Driver, error)
// ACL resolves per-user grants (RBAC). Required.
ACL *acl.Resolver
// E2EPolicy is who may encrypt (internal/e2epolicy): a write that CREATES
// an encrypted folder's key file or a `.fxe` asks it
// (protoperm.EncryptionAllowed). The router's own, handed over like ACL.
// nil: NewHandler builds one over Store (protoperm.EncryptionPolicy), so a
// lost wiring line never switches the rule off.
E2EPolicy *e2epolicy.Service
// Index — optional search index; mutated nodes are (re/de)indexed.
Index *search.Index
// Thumbs — optional thumbnail pipeline; written files get async thumbs.
Thumbs *thumb.Pipeline
// Body resolves where a file's bytes are: the storage driver, or filex's
// staging area while a staged upload is still transferring. Nil-safe —
// unwired means driver-only, which is what /dav did before staging.
Body *filebody.Resolver
// Quota enforces the account's storage ceiling. Nil disables the check,
// which is right for a test and wrong for the server — see preGate.
Quota *quota.Service
// MultiTenant mirrors config.MultiTenant for the login policy check.
MultiTenant bool
// Auth is the shared protocol credential resolver. Nil builds a private
// one, which is correct for a test but wrong for the server: a resolver
// per protocol is a credential cache per protocol, and therefore a
// different answer per protocol to how long a revoked password keeps
// working.
Auth *protocolauth.Resolver
// LockDir is where the WebDAV lock table is persisted. Empty keeps the
// locks in memory only, which is what /dav did before 2026-08-16 and is
// still right for a test — see internal/davlock for why it is wrong for a
// server.
LockDir string
// Realm for WWW-Authenticate (default "filex").
Realm string
}
Config wires the handler to the server's shared services.
type Handler ¶
type Handler struct {
// contains filtered or unexported fields
}
Handler is the /dav HTTP handler.
func NewHandler ¶
NewHandler builds the /dav handler. The lock system is shared across all requests (class-2 locks demand server-side state).