fix: move files between different volumes (closes #1177)

pull/1184/head^2
Oleg Lobanov 2020-12-24 17:50:27 +01:00
parent 7a5298a755
commit 58835b7e53
No known key found for this signature in database
GPG Key ID: 7CC64E41212621B0
2 changed files with 26 additions and 7 deletions

View File

@ -9,6 +9,25 @@ import (
"github.com/spf13/afero" "github.com/spf13/afero"
) )
// MoveFile moves file from src to dst.
// By default the rename filesystem system call is used. If src and dst point to different volumes
// the file copy is used as a fallback
func MoveFile(fs afero.Fs, src, dst string) error {
if fs.Rename(src, dst) == nil {
return nil
}
// fallback
err := CopyFile(fs, src, dst)
if err != nil {
_ = fs.Remove(dst)
return err
}
if err := fs.Remove(src); err != nil {
return err
}
return nil
}
// CopyFile copies a file from source to dest and returns // CopyFile copies a file from source to dest and returns
// an error if any. // an error if any.
func CopyFile(fs afero.Fs, source, dest string) error { func CopyFile(fs afero.Fs, source, dest string) error {
@ -39,14 +58,14 @@ func CopyFile(fs afero.Fs, source, dest string) error {
return err return err
} }
// Copy the mode if the user can't // Copy the mode
// open the file.
info, err := fs.Stat(source) info, err := fs.Stat(source)
if err != nil {
err = fs.Chmod(dest, info.Mode())
if err != nil { if err != nil {
return err return err
} }
err = fs.Chmod(dest, info.Mode())
if err != nil {
return err
} }
return nil return nil

View File

@ -200,7 +200,7 @@ var resourcePatchHandler = withUser(func(w http.ResponseWriter, r *http.Request,
src = path.Clean("/" + src) src = path.Clean("/" + src)
dst = path.Clean("/" + dst) dst = path.Clean("/" + dst)
return d.user.Fs.Rename(src, dst) return fileutils.MoveFile(d.user.Fs, src, dst)
default: default:
return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams) return fmt.Errorf("unsupported action %s: %w", action, errors.ErrInvalidRequestParams)
} }