mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 16:24:14 +00:00
webdav: add context to FileSystem
This commit is contained in:
parent
379a418130
commit
d033e09835
21
fs_local.go
21
fs_local.go
@ -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("")
|
||||
|
36
server.go
36
server.go
@ -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}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user