mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 16:24:14 +00:00
webdav: stop using os errors in FileSystem interface
Use NewHTTPError instead. Closes: https://github.com/emersion/go-webdav/issues/20
This commit is contained in:
parent
eaac65215b
commit
80d77a977a
54
fs_local.go
54
fs_local.go
@ -63,6 +63,18 @@ func fileInfoFromOS(p string, fi os.FileInfo) *FileInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func errFromOS(err error) error {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return NewHTTPError(http.StatusNotFound, err)
|
||||||
|
} else if os.IsPermission(err) {
|
||||||
|
return NewHTTPError(http.StatusForbidden, err)
|
||||||
|
} else if os.IsTimeout(err) {
|
||||||
|
return NewHTTPError(http.StatusServiceUnavailable, err)
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (fs LocalFileSystem) Stat(ctx context.Context, name string) (*FileInfo, error) {
|
func (fs LocalFileSystem) Stat(ctx context.Context, name string) (*FileInfo, error) {
|
||||||
p, err := fs.localPath(name)
|
p, err := fs.localPath(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -70,7 +82,7 @@ func (fs LocalFileSystem) Stat(ctx context.Context, name string) (*FileInfo, err
|
|||||||
}
|
}
|
||||||
fi, err := os.Stat(p)
|
fi, err := os.Stat(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errFromOS(err)
|
||||||
}
|
}
|
||||||
return fileInfoFromOS(name, fi), nil
|
return fileInfoFromOS(name, fi), nil
|
||||||
}
|
}
|
||||||
@ -99,7 +111,7 @@ func (fs LocalFileSystem) ReadDir(ctx context.Context, name string, recursive bo
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return l, err
|
return l, errFromOS(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs LocalFileSystem) Create(ctx context.Context, name string) (io.WriteCloser, error) {
|
func (fs LocalFileSystem) Create(ctx context.Context, name string) (io.WriteCloser, error) {
|
||||||
@ -107,7 +119,8 @@ func (fs LocalFileSystem) Create(ctx context.Context, name string) (io.WriteClos
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return os.Create(p)
|
wc, err := os.Create(p)
|
||||||
|
return wc, errFromOS(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs LocalFileSystem) RemoveAll(ctx context.Context, name string) error {
|
func (fs LocalFileSystem) RemoveAll(ctx context.Context, name string) error {
|
||||||
@ -119,10 +132,10 @@ func (fs LocalFileSystem) RemoveAll(ctx context.Context, name string) error {
|
|||||||
// WebDAV semantics are that it should return a "404 Not Found" error in
|
// WebDAV semantics are that it should return a "404 Not Found" error in
|
||||||
// case the resource doesn't exist. We need to Stat before RemoveAll.
|
// case the resource doesn't exist. We need to Stat before RemoveAll.
|
||||||
if _, err = os.Stat(p); err != nil {
|
if _, err = os.Stat(p); err != nil {
|
||||||
return err
|
return errFromOS(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.RemoveAll(p)
|
return errFromOS(os.RemoveAll(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs LocalFileSystem) Mkdir(ctx context.Context, name string) error {
|
func (fs LocalFileSystem) Mkdir(ctx context.Context, name string) error {
|
||||||
@ -130,20 +143,21 @@ func (fs LocalFileSystem) Mkdir(ctx context.Context, name string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.Mkdir(p, 0755)
|
return errFromOS(os.Mkdir(p, 0755))
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyRegularFile(src, dst string, perm os.FileMode) error {
|
func copyRegularFile(src, dst string, perm os.FileMode) error {
|
||||||
srcFile, err := os.Open(src)
|
srcFile, err := os.Open(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errFromOS(err)
|
||||||
}
|
}
|
||||||
defer srcFile.Close()
|
defer srcFile.Close()
|
||||||
|
|
||||||
dstFile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
|
dstFile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
|
||||||
if err != nil {
|
if os.IsNotExist(err) {
|
||||||
// TODO: send http.StatusConflict on os.IsNotExist
|
return NewHTTPError(http.StatusConflict, err)
|
||||||
return err
|
} else if err != nil {
|
||||||
|
return errFromOS(err)
|
||||||
}
|
}
|
||||||
defer dstFile.Close()
|
defer dstFile.Close()
|
||||||
|
|
||||||
@ -169,21 +183,21 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, options *Co
|
|||||||
|
|
||||||
srcInfo, err := os.Stat(srcPath)
|
srcInfo, err := os.Stat(srcPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
srcPerm := srcInfo.Mode() & os.ModePerm
|
srcPerm := srcInfo.Mode() & os.ModePerm
|
||||||
|
|
||||||
if _, err := os.Stat(dstPath); err != nil {
|
if _, err := os.Stat(dstPath); err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
created = true
|
created = true
|
||||||
} else {
|
} else {
|
||||||
if options.NoOverwrite {
|
if options.NoOverwrite {
|
||||||
return false, os.ErrExist
|
return false, NewHTTPError(http.StatusPreconditionFailed, os.ErrExist)
|
||||||
}
|
}
|
||||||
if err := os.RemoveAll(dstPath); err != nil {
|
if err := os.RemoveAll(dstPath); err != nil {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +208,7 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, options *Co
|
|||||||
|
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
if err := os.Mkdir(dstPath, srcPerm); err != nil {
|
if err := os.Mkdir(dstPath, srcPerm); err != nil {
|
||||||
return err
|
return errFromOS(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := copyRegularFile(srcPath, dstPath, srcPerm); err != nil {
|
if err := copyRegularFile(srcPath, dstPath, srcPerm); err != nil {
|
||||||
@ -208,7 +222,7 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, options *Co
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return created, nil
|
return created, nil
|
||||||
@ -226,20 +240,20 @@ func (fs LocalFileSystem) Move(ctx context.Context, src, dst string, options *Mo
|
|||||||
|
|
||||||
if _, err := os.Stat(dstPath); err != nil {
|
if _, err := os.Stat(dstPath); err != nil {
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
created = true
|
created = true
|
||||||
} else {
|
} else {
|
||||||
if options.NoOverwrite {
|
if options.NoOverwrite {
|
||||||
return false, os.ErrExist
|
return false, NewHTTPError(http.StatusPreconditionFailed, os.ErrExist)
|
||||||
}
|
}
|
||||||
if err := os.RemoveAll(dstPath); err != nil {
|
if err := os.RemoveAll(dstPath); err != nil {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Rename(srcPath, dstPath); err != nil {
|
if err := os.Rename(srcPath, dstPath); err != nil {
|
||||||
return false, err
|
return false, errFromOS(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return created, nil
|
return created, nil
|
||||||
|
18
server.go
18
server.go
@ -57,7 +57,7 @@ type backend struct {
|
|||||||
|
|
||||||
func (b *backend) Options(r *http.Request) (caps []string, allow []string, err error) {
|
func (b *backend) Options(r *http.Request) (caps []string, allow []string, err error) {
|
||||||
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
||||||
if os.IsNotExist(err) {
|
if internal.IsNotFound(err) {
|
||||||
return nil, []string{http.MethodOptions, http.MethodPut, "MKCOL"}, nil
|
return nil, []string{http.MethodOptions, http.MethodPut, "MKCOL"}, nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -80,9 +80,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 {
|
func (b *backend) HeadGet(w http.ResponseWriter, r *http.Request) error {
|
||||||
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
||||||
if os.IsNotExist(err) {
|
if err != nil {
|
||||||
return &internal.HTTPError{Code: http.StatusNotFound, Err: err}
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if fi.IsDir {
|
if fi.IsDir {
|
||||||
@ -121,9 +119,7 @@ func (b *backend) PropFind(r *http.Request, propfind *internal.PropFind, depth i
|
|||||||
// TODO: use partial error Response on error
|
// TODO: use partial error Response on error
|
||||||
|
|
||||||
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
fi, err := b.FileSystem.Stat(r.Context(), r.URL.Path)
|
||||||
if os.IsNotExist(err) {
|
if err != nil {
|
||||||
return nil, &internal.HTTPError{Code: http.StatusNotFound, Err: err}
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,11 +208,7 @@ func (b *backend) Put(r *http.Request) (*internal.Href, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) Delete(r *http.Request) error {
|
func (b *backend) Delete(r *http.Request) error {
|
||||||
err := b.FileSystem.RemoveAll(r.Context(), r.URL.Path)
|
return b.FileSystem.RemoveAll(r.Context(), r.URL.Path)
|
||||||
if os.IsNotExist(err) {
|
|
||||||
return &internal.HTTPError{Code: http.StatusNotFound, Err: err}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *backend) Mkcol(r *http.Request) error {
|
func (b *backend) Mkcol(r *http.Request) error {
|
||||||
@ -224,7 +216,7 @@ func (b *backend) Mkcol(r *http.Request) error {
|
|||||||
return internal.HTTPErrorf(http.StatusUnsupportedMediaType, "webdav: request body not supported in MKCOL request")
|
return internal.HTTPErrorf(http.StatusUnsupportedMediaType, "webdav: request body not supported in MKCOL request")
|
||||||
}
|
}
|
||||||
err := b.FileSystem.Mkdir(r.Context(), r.URL.Path)
|
err := b.FileSystem.Mkdir(r.Context(), r.URL.Path)
|
||||||
if os.IsNotExist(err) {
|
if internal.IsNotFound(err) {
|
||||||
return &internal.HTTPError{Code: http.StatusConflict, Err: err}
|
return &internal.HTTPError{Code: http.StatusConflict, Err: err}
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user