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:
Simon Ser
2024-02-06 15:23:30 +01:00
parent eaac65215b
commit 80d77a977a
2 changed files with 39 additions and 33 deletions

View File

@@ -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