webdav: add context to FileSystem

This commit is contained in:
Simon Ser 2023-12-19 21:29:28 +01:00
parent 379a418130
commit d033e09835
2 changed files with 29 additions and 28 deletions

View File

@ -1,6 +1,7 @@
package webdav
import (
"context"
"fmt"
"io"
"mime"
@ -15,6 +16,8 @@ import (
type LocalFileSystem string
var _ FileSystem = LocalFileSystem("")
func (fs LocalFileSystem) localPath(name string) (string, error) {
if (filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0) || strings.Contains(name, "\x00") {
return "", internal.HTTPErrorf(http.StatusBadRequest, "webdav: invalid character in path")
@ -34,7 +37,7 @@ func (fs LocalFileSystem) externalPath(name string) (string, error) {
return "/" + filepath.ToSlash(rel), nil
}
func (fs LocalFileSystem) Open(name string) (io.ReadCloser, error) {
func (fs LocalFileSystem) Open(ctx context.Context, name string) (io.ReadCloser, error) {
p, err := fs.localPath(name)
if err != nil {
return nil, err
@ -59,7 +62,7 @@ func fileInfoFromOS(p string, fi os.FileInfo) *FileInfo {
}
}
func (fs LocalFileSystem) Stat(name string) (*FileInfo, error) {
func (fs LocalFileSystem) Stat(ctx context.Context, name string) (*FileInfo, error) {
p, err := fs.localPath(name)
if err != nil {
return nil, err
@ -71,7 +74,7 @@ func (fs LocalFileSystem) Stat(name string) (*FileInfo, error) {
return fileInfoFromOS(name, fi), nil
}
func (fs LocalFileSystem) Readdir(name string, recursive bool) ([]FileInfo, error) {
func (fs LocalFileSystem) ReadDir(ctx context.Context, name string, recursive bool) ([]FileInfo, error) {
path, err := fs.localPath(name)
if err != nil {
return nil, err
@ -98,7 +101,7 @@ func (fs LocalFileSystem) Readdir(name string, recursive bool) ([]FileInfo, erro
return l, err
}
func (fs LocalFileSystem) Create(name string) (io.WriteCloser, error) {
func (fs LocalFileSystem) Create(ctx context.Context, name string) (io.WriteCloser, error) {
p, err := fs.localPath(name)
if err != nil {
return nil, err
@ -106,7 +109,7 @@ func (fs LocalFileSystem) Create(name string) (io.WriteCloser, error) {
return os.Create(p)
}
func (fs LocalFileSystem) RemoveAll(name string) error {
func (fs LocalFileSystem) RemoveAll(ctx context.Context, name string) error {
p, err := fs.localPath(name)
if err != nil {
return err
@ -121,7 +124,7 @@ func (fs LocalFileSystem) RemoveAll(name string) error {
return os.RemoveAll(p)
}
func (fs LocalFileSystem) Mkdir(name string) error {
func (fs LocalFileSystem) Mkdir(ctx context.Context, name string) error {
p, err := fs.localPath(name)
if err != nil {
return err
@ -150,7 +153,7 @@ func copyRegularFile(src, dst string, perm os.FileMode) error {
return dstFile.Close()
}
func (fs LocalFileSystem) Copy(src, dst string, recursive, overwrite bool) (created bool, err error) {
func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, recursive, overwrite bool) (created bool, err error) {
srcPath, err := fs.localPath(src)
if err != nil {
return false, err
@ -210,7 +213,7 @@ func (fs LocalFileSystem) Copy(src, dst string, recursive, overwrite bool) (crea
return created, nil
}
func (fs LocalFileSystem) MoveAll(src, dst string, overwrite bool) (created bool, err error) {
func (fs LocalFileSystem) MoveAll(ctx context.Context, src, dst string, overwrite bool) (created bool, err error) {
srcPath, err := fs.localPath(src)
if err != nil {
return false, err
@ -240,5 +243,3 @@ func (fs LocalFileSystem) MoveAll(src, dst string, overwrite bool) (created bool
return created, nil
}
var _ FileSystem = LocalFileSystem("")

View File

@ -14,14 +14,14 @@ import (
// FileSystem is a WebDAV server backend.
type FileSystem interface {
Open(name string) (io.ReadCloser, error)
Stat(name string) (*FileInfo, error)
Readdir(name string, recursive bool) ([]FileInfo, error)
Create(name string) (io.WriteCloser, error)
RemoveAll(name string) error
Mkdir(name string) error
Copy(name, dest string, recursive, overwrite bool) (created bool, err error)
MoveAll(name, dest string, overwrite bool) (created bool, err error)
Open(ctx context.Context, name string) (io.ReadCloser, error)
Stat(ctx context.Context, name string) (*FileInfo, error)
ReadDir(ctx context.Context, name string, recursive bool) ([]FileInfo, error)
Create(ctx context.Context, name string) (io.WriteCloser, error)
RemoveAll(ctx context.Context, name string) error
Mkdir(ctx context.Context, name string) error
Copy(ctx context.Context, name, dest string, recursive, overwrite bool) (created bool, err error)
MoveAll(ctx context.Context, name, dest string, overwrite bool) (created bool, err error)
}
// Handler handles WebDAV HTTP requests. It can be used to create a WebDAV
@ -56,7 +56,7 @@ type backend struct {
}
func (b *backend) Options(r *http.Request) (caps []string, allow []string, err error) {
fi, err := b.FileSystem.Stat(r.URL.Path)
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
if os.IsNotExist(err) {
return nil, []string{http.MethodOptions, http.MethodPut, "MKCOL"}, nil
} else if err != nil {
@ -79,7 +79,7 @@ func (b *backend) Options(r *http.Request) (caps []string, allow []string, err e
}
func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
fi, err := b.FileSystem.Stat(r.URL.Path)
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
if os.IsNotExist(err) {
return &internal.HTTPError{Code: http.StatusNotFound, Err: err}
} else if err != nil {
@ -89,7 +89,7 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
return &internal.HTTPError{Code: http.StatusMethodNotAllowed}
}
f, err := b.FileSystem.Open(r.URL.Path)
f, err := b.FileSystem.Open(r.Context(), r.URL.Path)
if err != nil {
return err
}
@ -120,7 +120,7 @@ func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
func (b *backend) PropFind(r *http.Request, propfind *internal.PropFind, depth internal.Depth) (*internal.MultiStatus, error) {
// TODO: use partial error Response on error
fi, err := b.FileSystem.Stat(r.URL.Path)
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
if os.IsNotExist(err) {
return nil, &internal.HTTPError{Code: http.StatusNotFound, Err: err}
} else if err != nil {
@ -129,7 +129,7 @@ func (b *backend) PropFind(r *http.Request, propfind *internal.PropFind, depth i
var resps []internal.Response
if depth != internal.DepthZero && fi.IsDir {
children, err := b.FileSystem.Readdir(r.URL.Path, depth == internal.DepthInfinity)
children, err := b.FileSystem.ReadDir(r.Context(), r.URL.Path, depth == internal.DepthInfinity)
if err != nil {
return nil, err
}
@ -198,7 +198,7 @@ func (b *backend) PropPatch(r *http.Request, update *internal.PropertyUpdate) (*
}
func (b *backend) Put(r *http.Request) (*internal.Href, error) {
wc, err := b.FileSystem.Create(r.URL.Path)
wc, err := b.FileSystem.Create(r.Context(), r.URL.Path)
if err != nil {
return nil, err
}
@ -212,7 +212,7 @@ func (b *backend) Put(r *http.Request) (*internal.Href, error) {
}
func (b *backend) Delete(r *http.Request) error {
err := b.FileSystem.RemoveAll(r.URL.Path)
err := b.FileSystem.RemoveAll(r.Context(), r.URL.Path)
if os.IsNotExist(err) {
return &internal.HTTPError{Code: http.StatusNotFound, Err: err}
}
@ -223,7 +223,7 @@ func (b *backend) Mkcol(r *http.Request) error {
if r.Header.Get("Content-Type") != "" {
return internal.HTTPErrorf(http.StatusUnsupportedMediaType, "webdav: request body not supported in MKCOL request")
}
err := b.FileSystem.Mkdir(r.URL.Path)
err := b.FileSystem.Mkdir(r.Context(), r.URL.Path)
if os.IsNotExist(err) {
return &internal.HTTPError{Code: http.StatusConflict, Err: err}
}
@ -231,7 +231,7 @@ func (b *backend) Mkcol(r *http.Request) error {
}
func (b *backend) Copy(r *http.Request, dest *internal.Href, recursive, overwrite bool) (created bool, err error) {
created, err = b.FileSystem.Copy(r.URL.Path, dest.Path, recursive, overwrite)
created, err = b.FileSystem.Copy(r.Context(), r.URL.Path, dest.Path, recursive, overwrite)
if os.IsExist(err) {
return false, &internal.HTTPError{http.StatusPreconditionFailed, err}
}
@ -239,7 +239,7 @@ func (b *backend) Copy(r *http.Request, dest *internal.Href, recursive, overwrit
}
func (b *backend) Move(r *http.Request, dest *internal.Href, overwrite bool) (created bool, err error) {
created, err = b.FileSystem.MoveAll(r.URL.Path, dest.Path, overwrite)
created, err = b.FileSystem.MoveAll(r.Context(), r.URL.Path, dest.Path, overwrite)
if os.IsExist(err) {
return false, &internal.HTTPError{http.StatusPreconditionFailed, err}
}