From 4660f5f15d87f8c1579e9cc914eefb84a4c9f13a Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 15 Nov 2022 12:39:17 +0000 Subject: [PATCH] dropbox: make across config server side Move/Copy/DirMove fallback to copy If we are doing a cross remote transfer then attempting a Move/Copy/DirMove where we don't have permission gives `from_lookup/not_found` errors. This patch notices that error and only if we are doing a cross remote transfer it engages the fallback where the file is streamed. See: https://forum.rclone.org/t/dropbox-io-error-movedir-failed-from-lookup-not-found-when-try-to-move-copy-works/34088 --- backend/dropbox/dropbox.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/backend/dropbox/dropbox.go b/backend/dropbox/dropbox.go index 740bd76e3..9ab8e8459 100644 --- a/backend/dropbox/dropbox.go +++ b/backend/dropbox/dropbox.go @@ -1078,6 +1078,15 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, return shouldRetry(ctx, err) }) if err != nil { + switch e := err.(type) { + case files.CopyV2APIError: + // If we are doing a cross remote transfer then from_lookup/not_found indicates we + // don't have permission to read the source, so engage the slow path + if srcObj.fs != f && e.EndpointError != nil && e.EndpointError.FromLookup != nil && e.EndpointError.FromLookup.Tag == files.LookupErrorNotFound { + fs.Debugf(srcObj, "Copy failed attempting fallback: %v", err) + return nil, fs.ErrorCantCopy + } + } return nil, fmt.Errorf("copy failed: %w", err) } @@ -1139,6 +1148,15 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object, return shouldRetry(ctx, err) }) if err != nil { + switch e := err.(type) { + case files.MoveV2APIError: + // If we are doing a cross remote transfer then from_lookup/not_found indicates we + // don't have permission to read the source, so engage the slow path + if srcObj.fs != f && e.EndpointError != nil && e.EndpointError.FromLookup != nil && e.EndpointError.FromLookup.Tag == files.LookupErrorNotFound { + fs.Debugf(srcObj, "Move failed attempting fallback: %v", err) + return nil, fs.ErrorCantMove + } + } return nil, fmt.Errorf("move failed: %w", err) } @@ -1257,6 +1275,15 @@ func (f *Fs) DirMove(ctx context.Context, src fs.Fs, srcRemote, dstRemote string return shouldRetry(ctx, err) }) if err != nil { + switch e := err.(type) { + case files.MoveV2APIError: + // If we are doing a cross remote transfer then from_lookup/not_found indicates we + // don't have permission to read the source, so engage the slow path + if srcFs != f && e.EndpointError != nil && e.EndpointError.FromLookup != nil && e.EndpointError.FromLookup.Tag == files.LookupErrorNotFound { + fs.Debugf(srcFs, "DirMove failed attempting fallback: %v", err) + return fs.ErrorCantDirMove + } + } return fmt.Errorf("MoveDir failed: %w", err) }