wrapped_webdav_fs.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package weed_server
  2. import (
  3. "context"
  4. "golang.org/x/net/webdav"
  5. "io/fs"
  6. "os"
  7. "strings"
  8. )
  9. type wrappedFs struct {
  10. subFolder string
  11. webdav.FileSystem
  12. }
  13. // NewWrappedFs returns a webdav.FileSystem identical to fs, except it
  14. // provides access to a sub-folder of fs that is denominated by subFolder.
  15. // It transparently handles renaming paths and filenames so that the outer part of the wrapped filesystem
  16. // does not leak out.
  17. func NewWrappedFs(fs webdav.FileSystem, subFolder string) webdav.FileSystem {
  18. return wrappedFs{
  19. subFolder: subFolder,
  20. FileSystem: fs,
  21. }
  22. }
  23. func (w wrappedFs) Mkdir(ctx context.Context, name string, perm os.FileMode) error {
  24. name = w.subFolder + name
  25. return w.FileSystem.Mkdir(ctx, name, perm)
  26. }
  27. func (w wrappedFs) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
  28. name = w.subFolder + name
  29. file, err := w.FileSystem.OpenFile(ctx, name, flag, perm)
  30. file = wrappedFile{
  31. File: file,
  32. subFolder: &w.subFolder,
  33. }
  34. return file, err
  35. }
  36. func (w wrappedFs) RemoveAll(ctx context.Context, name string) error {
  37. name = w.subFolder + name
  38. return w.FileSystem.RemoveAll(ctx, name)
  39. }
  40. func (w wrappedFs) Rename(ctx context.Context, oldName, newName string) error {
  41. oldName = w.subFolder + oldName
  42. newName = w.subFolder + newName
  43. return w.FileSystem.Rename(ctx, oldName, newName)
  44. }
  45. func (w wrappedFs) Stat(ctx context.Context, name string) (os.FileInfo, error) {
  46. name = w.subFolder + name
  47. info, err := w.FileSystem.Stat(ctx, name)
  48. info = wrappedFileInfo{
  49. subFolder: &w.subFolder,
  50. FileInfo: info,
  51. }
  52. return info, err
  53. }
  54. type wrappedFile struct {
  55. webdav.File
  56. subFolder *string
  57. }
  58. func (w wrappedFile) Readdir(count int) ([]fs.FileInfo, error) {
  59. infos, err := w.File.Readdir(count)
  60. for i, info := range infos {
  61. infos[i] = wrappedFileInfo{
  62. subFolder: w.subFolder,
  63. FileInfo: info,
  64. }
  65. }
  66. return infos, err
  67. }
  68. func (w wrappedFile) Stat() (fs.FileInfo, error) {
  69. info, err := w.File.Stat()
  70. info = wrappedFileInfo{
  71. subFolder: w.subFolder,
  72. FileInfo: info,
  73. }
  74. return info, err
  75. }
  76. type wrappedFileInfo struct {
  77. subFolder *string
  78. fs.FileInfo
  79. }
  80. func (w wrappedFileInfo) Name() string {
  81. name := w.FileInfo.Name()
  82. return strings.TrimPrefix(name, *w.subFolder)
  83. }
  84. func (w wrappedFileInfo) ETag(ctx context.Context) (string, error) {
  85. etag, _ := w.FileInfo.(webdav.ETager).ETag(ctx)
  86. if len(etag) == 0 {
  87. return etag, webdav.ErrNotImplemented
  88. }
  89. return etag, nil
  90. }