webdav: don't delete files on error - fixes #3263

Previous to this change rclone deleted a file if the upload failed
half way through.

After this change we only delete the upload if the
--webdav-delete-on-error flag is set.

We set this in the serve webdav tests to make them pass.
This commit is contained in:
Nick Craig-Wood 2019-06-14 15:39:33 +01:00
parent cef51d58ac
commit 259d0bb8ce
2 changed files with 26 additions and 13 deletions

View File

@ -86,6 +86,15 @@ func init() {
Name: "bearer_token_command", Name: "bearer_token_command",
Help: "Command to run to get a bearer token", Help: "Command to run to get a bearer token",
Advanced: true, Advanced: true,
}, {
Name: "delete_on_error",
Default: false,
Help: `Delete a partially uploaded file on upload failure.
Some webdav backends (eg rclone serve webdav) leave behind half
written files on error. This flag causes them to be deleted if the
upload fails part of the way through.`,
Advanced: true,
}}, }},
}) })
} }
@ -98,6 +107,7 @@ type Options struct {
Pass string `config:"pass"` Pass string `config:"pass"`
BearerToken string `config:"bearer_token"` BearerToken string `config:"bearer_token"`
BearerTokenCommand string `config:"bearer_token_command"` BearerTokenCommand string `config:"bearer_token_command"`
DeleteOnError bool `config:"delete_on_error"`
} }
// Fs represents a remote webdav // Fs represents a remote webdav
@ -1193,6 +1203,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
return o.fs.shouldRetry(resp, err) return o.fs.shouldRetry(resp, err)
}) })
if err != nil { if err != nil {
if o.fs.opt.DeleteOnError {
// Give the WebDAV server a chance to get its internal state in order after the // Give the WebDAV server a chance to get its internal state in order after the
// error. The error may have been local in which case we closed the connection. // error. The error may have been local in which case we closed the connection.
// The server may still be dealing with it for a moment. A sleep isn't ideal but I // The server may still be dealing with it for a moment. A sleep isn't ideal but I
@ -1201,6 +1212,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
// Remove failed upload // Remove failed upload
_ = o.Remove(ctx) _ = o.Remove(ctx)
}
return err return err
} }
// read metadata from remote // read metadata from remote

View File

@ -67,6 +67,7 @@ func TestWebDav(t *testing.T) {
"url": w.Server.URL(), "url": w.Server.URL(),
"user": testUser, "user": testUser,
"pass": obscure.MustObscure(testPass), "pass": obscure.MustObscure(testPass),
"delete_on_error": "true",
} }
return config, func() { return config, func() {