mirror of
https://github.com/rclone/rclone.git
synced 2024-12-23 07:29:35 +01:00
putio: fix server side copy failures (400 errors)
For some unknown reason the API sometimes returns the name already exists on a server side copy. { "error_id": null, "error_message": "Name already exist", "error_type": "NAME_ALREADY_EXIST", "error_uri": "http://api.put.io/v2/docs", "extra": {}, "status": "ERROR", "status_code": 400 } This patch uploads to a temporary name then renames it which works around the problem. This was spotted by the integration tests.
This commit is contained in:
parent
14024936a8
commit
8308d5d640
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/rclone/rclone/lib/dircache"
|
"github.com/rclone/rclone/lib/dircache"
|
||||||
"github.com/rclone/rclone/lib/oauthutil"
|
"github.com/rclone/rclone/lib/oauthutil"
|
||||||
"github.com/rclone/rclone/lib/pacer"
|
"github.com/rclone/rclone/lib/pacer"
|
||||||
|
"github.com/rclone/rclone/lib/random"
|
||||||
"github.com/rclone/rclone/lib/readers"
|
"github.com/rclone/rclone/lib/readers"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -544,11 +545,20 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (o fs.Objec
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
modTime := src.ModTime(ctx)
|
modTime := src.ModTime(ctx)
|
||||||
|
var resp struct {
|
||||||
|
File putio.File `json:"file"`
|
||||||
|
}
|
||||||
|
// For some unknown reason the API sometimes returns the name
|
||||||
|
// already exists unless we upload to a temporary name and
|
||||||
|
// rename
|
||||||
|
//
|
||||||
|
// {"error_id":null,"error_message":"Name already exist","error_type":"NAME_ALREADY_EXIST","error_uri":"http://api.put.io/v2/docs","extra":{},"status":"ERROR","status_code":400}
|
||||||
|
suffix := "." + random.String(8)
|
||||||
err = f.pacer.Call(func() (bool, error) {
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Set("file_id", strconv.FormatInt(srcObj.file.ID, 10))
|
params.Set("file_id", strconv.FormatInt(srcObj.file.ID, 10))
|
||||||
params.Set("parent_id", directoryID)
|
params.Set("parent_id", directoryID)
|
||||||
params.Set("name", f.opt.Enc.FromStandardName(leaf))
|
params.Set("name", f.opt.Enc.FromStandardName(leaf+suffix))
|
||||||
|
|
||||||
req, err := f.client.NewRequest(ctx, "POST", "/v2/files/copy", strings.NewReader(params.Encode()))
|
req, err := f.client.NewRequest(ctx, "POST", "/v2/files/copy", strings.NewReader(params.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -556,13 +566,29 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (o fs.Objec
|
|||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
// fs.Debugf(f, "copying file (%d) to parent_id: %s", srcObj.file.ID, directoryID)
|
// fs.Debugf(f, "copying file (%d) to parent_id: %s", srcObj.file.ID, directoryID)
|
||||||
_, err = f.client.Do(req, nil)
|
_, err = f.client.Do(req, &resp)
|
||||||
return shouldRetry(ctx, err)
|
return shouldRetry(ctx, err)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
o, err = f.NewObject(ctx, remote)
|
err = f.pacer.Call(func() (bool, error) {
|
||||||
|
params := url.Values{}
|
||||||
|
params.Set("file_id", strconv.FormatInt(resp.File.ID, 10))
|
||||||
|
params.Set("name", f.opt.Enc.FromStandardName(leaf))
|
||||||
|
|
||||||
|
req, err := f.client.NewRequest(ctx, "POST", "/v2/files/rename", strings.NewReader(params.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
_, err = f.client.Do(req, &resp)
|
||||||
|
return shouldRetry(ctx, err)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
o, err = f.newObjectWithInfo(ctx, remote, resp.File)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user