mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 08:14:15 +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) {
|
||||
p, err := fs.localPath(name)
|
||||
if err != nil {
|
||||
@ -70,7 +82,7 @@ func (fs LocalFileSystem) Stat(ctx context.Context, name string) (*FileInfo, err
|
||||
}
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errFromOS(err)
|
||||
}
|
||||
return fileInfoFromOS(name, fi), nil
|
||||
}
|
||||
@ -99,7 +111,7 @@ func (fs LocalFileSystem) ReadDir(ctx context.Context, name string, recursive bo
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return l, err
|
||||
return l, errFromOS(err)
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
@ -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
|
||||
// case the resource doesn't exist. We need to Stat before RemoveAll.
|
||||
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 {
|
||||
@ -130,20 +143,21 @@ func (fs LocalFileSystem) Mkdir(ctx context.Context, name string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Mkdir(p, 0755)
|
||||
return errFromOS(os.Mkdir(p, 0755))
|
||||
}
|
||||
|
||||
func copyRegularFile(src, dst string, perm os.FileMode) error {
|
||||
srcFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return errFromOS(err)
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
dstFile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
|
||||
if err != nil {
|
||||
// TODO: send http.StatusConflict on os.IsNotExist
|
||||
return err
|
||||
if os.IsNotExist(err) {
|
||||
return NewHTTPError(http.StatusConflict, err)
|
||||
} else if err != nil {
|
||||
return errFromOS(err)
|
||||
}
|
||||
defer dstFile.Close()
|
||||
|
||||
@ -169,21 +183,21 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, options *Co
|
||||
|
||||
srcInfo, err := os.Stat(srcPath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
srcPerm := srcInfo.Mode() & os.ModePerm
|
||||
|
||||
if _, err := os.Stat(dstPath); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
created = true
|
||||
} else {
|
||||
if options.NoOverwrite {
|
||||
return false, os.ErrExist
|
||||
return false, NewHTTPError(http.StatusPreconditionFailed, os.ErrExist)
|
||||
}
|
||||
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 err := os.Mkdir(dstPath, srcPerm); err != nil {
|
||||
return err
|
||||
return errFromOS(err)
|
||||
}
|
||||
} else {
|
||||
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
|
||||
})
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
|
||||
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 !os.IsNotExist(err) {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
created = true
|
||||
} else {
|
||||
if options.NoOverwrite {
|
||||
return false, os.ErrExist
|
||||
return false, NewHTTPError(http.StatusPreconditionFailed, os.ErrExist)
|
||||
}
|
||||
if err := os.RemoveAll(dstPath); err != nil {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.Rename(srcPath, dstPath); err != nil {
|
||||
return false, err
|
||||
return false, errFromOS(err)
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
} else if err != nil {
|
||||
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 {
|
||||
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 {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
|
||||
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 {
|
||||
if err != nil {
|
||||
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 {
|
||||
err := b.FileSystem.RemoveAll(r.Context(), r.URL.Path)
|
||||
if os.IsNotExist(err) {
|
||||
return &internal.HTTPError{Code: http.StatusNotFound, Err: err}
|
||||
}
|
||||
return err
|
||||
return b.FileSystem.RemoveAll(r.Context(), r.URL.Path)
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
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 err
|
||||
|
Loading…
Reference in New Issue
Block a user