mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 11:35:35 +00:00
50fb8b9123
Instead of modeling remote WebDAV servers as actual webdav.FS instances, we now just proxy traffic to them. This not only simplifies the code, but it also allows WebDAV locking to work correctly by making sure locks are handled by the servers that need to (i.e. the ones actually serving the files). Updates tailscale/corp#16827 Signed-off-by: Percy Wegmann <percy@tailscale.com>
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package dirfs
|
|
|
|
import (
|
|
"context"
|
|
"io/fs"
|
|
"os"
|
|
|
|
"github.com/tailscale/xnet/webdav"
|
|
"tailscale.com/tailfs/tailfsimpl/shared"
|
|
)
|
|
|
|
// OpenFile implements interface webdav.Filesystem.
|
|
func (dfs *FS) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
|
|
_, isStaticRoot := dfs.trimStaticRoot(name)
|
|
if !isStaticRoot && !shared.IsRoot(name) {
|
|
// Show a folder with no children to represent the requested child. In
|
|
// practice, the children of this folder are never read, we just need
|
|
// to give webdav a file here which it uses to call file.Stat(). So,
|
|
// even though the Child may in fact have its own children, it doesn't
|
|
// matter here.
|
|
return &shared.DirFile{
|
|
Info: shared.ReadOnlyDirInfo(name, dfs.now()),
|
|
LoadChildren: func() ([]fs.FileInfo, error) {
|
|
return nil, nil
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
di, err := dfs.Stat(ctx, name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if dfs.StaticRoot != "" && !isStaticRoot {
|
|
// Show a folder with a single subfolder that is the static root.
|
|
return &shared.DirFile{
|
|
Info: di,
|
|
LoadChildren: func() ([]fs.FileInfo, error) {
|
|
return []fs.FileInfo{
|
|
shared.ReadOnlyDirInfo(dfs.StaticRoot, dfs.now()),
|
|
}, nil
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// Show a folder with one subfolder for each Child of this FS.
|
|
return &shared.DirFile{
|
|
Info: di,
|
|
LoadChildren: func() ([]fs.FileInfo, error) {
|
|
childInfos := make([]fs.FileInfo, 0, len(dfs.Children))
|
|
for _, c := range dfs.Children {
|
|
if c.isAvailable() {
|
|
childInfo := shared.ReadOnlyDirInfo(c.Name, dfs.now())
|
|
childInfos = append(childInfos, childInfo)
|
|
}
|
|
}
|
|
return childInfos, nil
|
|
},
|
|
}, nil
|
|
}
|