aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--weed/server/webdav_server.go8
-rw-r--r--weed/server/wrapped_webdav_fs.go97
2 files changed, 101 insertions, 4 deletions
diff --git a/weed/server/webdav_server.go b/weed/server/webdav_server.go
index 189378dcd..945c68279 100644
--- a/weed/server/webdav_server.go
+++ b/weed/server/webdav_server.go
@@ -63,6 +63,10 @@ func NewWebDavServer(option *WebDavOption) (ws *WebDavServer, err error) {
if option.FilerRootPath == "/" {
option.FilerRootPath = ""
}
+ // filer.path non "/" option means we are accessing filer's sub-folders
+ if option.FilerRootPath != "" {
+ fs = NewWrappedFs(fs, path.Clean(option.FilerRootPath))
+ }
ws = &WebDavServer{
option: option,
@@ -204,8 +208,6 @@ func (fs *WebDavFileSystem) Mkdir(ctx context.Context, fullDirPath string, perm
}
func (fs *WebDavFileSystem) OpenFile(ctx context.Context, fullFilePath string, flag int, perm os.FileMode) (webdav.File, error) {
- // Add filer.path
- fullFilePath = fs.option.FilerRootPath + fullFilePath
glog.V(2).Infof("WebDavFileSystem.OpenFile %v %x", fullFilePath, flag)
var err error
@@ -377,8 +379,6 @@ func (fs *WebDavFileSystem) stat(ctx context.Context, fullFilePath string) (os.F
}
func (fs *WebDavFileSystem) Stat(ctx context.Context, name string) (os.FileInfo, error) {
- // Add filer.path
- name = fs.option.FilerRootPath + name
glog.V(2).Infof("WebDavFileSystem.Stat %v", name)
return fs.stat(ctx, name)
diff --git a/weed/server/wrapped_webdav_fs.go b/weed/server/wrapped_webdav_fs.go
new file mode 100644
index 000000000..93e2b3122
--- /dev/null
+++ b/weed/server/wrapped_webdav_fs.go
@@ -0,0 +1,97 @@
+package weed_server
+
+import (
+ "context"
+ "golang.org/x/net/webdav"
+ "io/fs"
+ "os"
+ "strings"
+)
+
+type wrappedFs struct {
+ subFolder string
+ webdav.FileSystem
+}
+
+// NewWrappedFs returns a webdav.FileSystem identical to fs, except it
+// provides access to a sub-folder of fs that is denominated by subFolder.
+// It transparently handles renaming paths and filenames so that the outer part of the wrapped filesystem
+// does not leak out.
+func NewWrappedFs(fs webdav.FileSystem, subFolder string) webdav.FileSystem {
+ return wrappedFs{
+ subFolder: subFolder,
+ FileSystem: fs,
+ }
+}
+
+func (w wrappedFs) Mkdir(ctx context.Context, name string, perm os.FileMode) error {
+ name = w.subFolder + name
+ return w.FileSystem.Mkdir(ctx, name, perm)
+}
+
+func (w wrappedFs) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
+ name = w.subFolder + name
+ file, err := w.FileSystem.OpenFile(ctx, name, flag, perm)
+ file = wrappedFile{
+ File: file,
+ subFolder: &w.subFolder,
+ }
+
+ return file, err
+}
+
+func (w wrappedFs) RemoveAll(ctx context.Context, name string) error {
+ name = w.subFolder + name
+ return w.FileSystem.RemoveAll(ctx, name)
+}
+
+func (w wrappedFs) Rename(ctx context.Context, oldName, newName string) error {
+ oldName = w.subFolder + oldName
+ newName = w.subFolder + newName
+ return w.FileSystem.Rename(ctx, oldName, newName)
+}
+
+func (w wrappedFs) Stat(ctx context.Context, name string) (os.FileInfo, error) {
+ name = w.subFolder + name
+ info, err := w.FileSystem.Stat(ctx, name)
+ info = wrappedFileInfo{
+ subFolder: &w.subFolder,
+ FileInfo: info,
+ }
+ return info, err
+}
+
+type wrappedFile struct {
+ webdav.File
+ subFolder *string
+}
+
+func (w wrappedFile) Readdir(count int) ([]fs.FileInfo, error) {
+ infos, err := w.File.Readdir(count)
+ for i, info := range infos {
+ infos[i] = wrappedFileInfo{
+ subFolder: w.subFolder,
+ FileInfo: info,
+ }
+ }
+ return infos, err
+}
+
+func (w wrappedFile) Stat() (fs.FileInfo, error) {
+ info, err := w.File.Stat()
+ info = wrappedFileInfo{
+ subFolder: w.subFolder,
+ FileInfo: info,
+ }
+ return info, err
+}
+
+type wrappedFileInfo struct {
+ subFolder *string
+ fs.FileInfo
+}
+
+func (w wrappedFileInfo) Name() string {
+ name := w.FileInfo.Name()
+ return strings.TrimPrefix(name, *w.subFolder)
+}