mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-21 19:10:42 +08:00
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package lib
|
|
|
|
import (
|
|
"path"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"golang.org/x/net/webdav"
|
|
)
|
|
|
|
var _ webdav.LockSystem = &lockSystem{}
|
|
|
|
// lockSystem wraps a [webdav.LockSystem], mapping virtual request names to the
|
|
// real backing paths via resolve. This allows reusing the same
|
|
// [webdav.LockSystem] for multiple users with different base directories,
|
|
// meaning we can correctly lock the files across different users.
|
|
type lockSystem struct {
|
|
webdav.LockSystem
|
|
resolve func(name string) (string, error)
|
|
}
|
|
|
|
// newLockSystem returns a lockSystem for a single-directory user, resolving
|
|
// names relative to directory.
|
|
func newLockSystem(ls webdav.LockSystem, directory string) *lockSystem {
|
|
return &lockSystem{
|
|
LockSystem: ls,
|
|
resolve: func(name string) (string, error) {
|
|
// Lock names share a slash-separated namespace across users, even
|
|
// on Windows where filepath.Join would emit backslashes and break
|
|
// descendant-lock matching in the underlying LockSystem.
|
|
return path.Join(filepath.ToSlash(directory), name), nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// newMultiDirLockSystem returns a lockSystem for a multi-directory user,
|
|
// resolving names against the real backing path of each mount.
|
|
func newMultiDirLockSystem(ls webdav.LockSystem, mounts DirectoryMounts) *lockSystem {
|
|
return &lockSystem{
|
|
LockSystem: ls,
|
|
resolve: func(name string) (string, error) {
|
|
if cleanName(name) == "/" {
|
|
return "/", nil
|
|
}
|
|
|
|
mount, rest, err := multiDir{mounts: mounts}.resolve(name)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// filePath returns an OS-native path for real file operations; the
|
|
// lock namespace must stay slash-separated so descendant locks match
|
|
// on Windows.
|
|
return filepath.ToSlash(mount.filePath(rest)), nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func (l *lockSystem) Confirm(now time.Time, name0, name1 string, conditions ...webdav.Condition) (release func(), err error) {
|
|
if name0 != "" {
|
|
name0, err = l.resolve(name0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if name1 != "" {
|
|
name1, err = l.resolve(name1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return l.LockSystem.Confirm(now, name0, name1, conditions...)
|
|
}
|
|
|
|
func (l *lockSystem) Create(now time.Time, details webdav.LockDetails) (token string, err error) {
|
|
details.Root, err = l.resolve(details.Root)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return l.LockSystem.Create(now, details)
|
|
}
|