diff --git a/client.go b/client.go index 8802ed7..13209d0 100644 --- a/client.go +++ b/client.go @@ -247,16 +247,28 @@ func (c *Client) Mkdir(ctx context.Context, name string) error { return nil } -// CopyAll copies a file. If the file is a directory, all of its descendants -// are recursively copied as well. -func (c *Client) CopyAll(ctx context.Context, name, dest string, overwrite bool) error { +// Copy copies a file. +// +// By default, if the file is a directory, all descendants are recursively +// copied as well. +func (c *Client) Copy(ctx context.Context, name, dest string, options *CopyOptions) error { + if options == nil { + options = new(CopyOptions) + } + req, err := c.ic.NewRequest("COPY", name, nil) if err != nil { return err } + depth := internal.DepthInfinity + if options.NoRecursive { + depth = internal.DepthZero + } + req.Header.Set("Destination", c.ic.ResolveHref(dest).String()) - req.Header.Set("Overwrite", internal.FormatOverwrite(overwrite)) + req.Header.Set("Overwrite", internal.FormatOverwrite(!options.NoOverwrite)) + req.Header.Set("Depth", depth.String()) resp, err := c.ic.Do(req.WithContext(ctx)) if err != nil { diff --git a/fs_local.go b/fs_local.go index 1366f4b..84d38b1 100644 --- a/fs_local.go +++ b/fs_local.go @@ -154,7 +154,7 @@ func copyRegularFile(src, dst string, perm os.FileMode) error { return dstFile.Close() } -func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, recursive, overwrite bool) (created bool, err error) { +func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, options *CopyOptions) (created bool, err error) { srcPath, err := fs.localPath(src) if err != nil { return false, err @@ -179,7 +179,7 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, recursive, } created = true } else { - if !overwrite { + if options.NoOverwrite { return false, os.ErrExist } if err := os.RemoveAll(dstPath); err != nil { @@ -202,7 +202,7 @@ func (fs LocalFileSystem) Copy(ctx context.Context, src, dst string, recursive, } } - if fi.IsDir() && !recursive { + if fi.IsDir() && options.NoRecursive { return filepath.SkipDir } return nil diff --git a/server.go b/server.go index 617cb69..b7eb225 100644 --- a/server.go +++ b/server.go @@ -20,7 +20,7 @@ type FileSystem interface { 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) + Copy(ctx context.Context, name, dest string, options *CopyOptions) (created bool, err error) MoveAll(ctx context.Context, name, dest string, overwrite bool) (created bool, err error) } @@ -231,7 +231,11 @@ 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.Context(), r.URL.Path, dest.Path, recursive, overwrite) + options := CopyOptions{ + NoRecursive: !recursive, + NoOverwrite: !overwrite, + } + created, err = b.FileSystem.Copy(r.Context(), r.URL.Path, dest.Path, &options) if os.IsExist(err) { return false, &internal.HTTPError{http.StatusPreconditionFailed, err} } diff --git a/webdav.go b/webdav.go index 7397f9f..73a9c7f 100644 --- a/webdav.go +++ b/webdav.go @@ -16,3 +16,8 @@ type FileInfo struct { MIMEType string ETag string } + +type CopyOptions struct { + NoRecursive bool + NoOverwrite bool +}