1
0
mirror of https://github.com/gilbertchen/duplicacy synced 2025-12-06 00:03:38 +00:00

Fixed a MoveFile bug in Wasabi when the storage is at the root of a bucket

When the storage dir is empty, the destination path passed to the MOVE api starts
with a / which causes Wasabi to fail silently.
This commit is contained in:
Gilbert Chen
2019-04-24 16:48:25 -04:00
parent 1da151f9d9
commit a6fe3d785e

View File

@@ -93,49 +93,49 @@ func (storage *WasabiStorage) DeleteFile(
// rename. It's designed to get the job done with as few dependencies // rename. It's designed to get the job done with as few dependencies
// on other packages as possible rather than being somethng // on other packages as possible rather than being somethng
// general-purpose and reusable. // general-purpose and reusable.
func (storage *WasabiStorage) MoveFile( func (storage *WasabiStorage) MoveFile(threadIndex int, from string, to string) (err error) {
threadIndex int, from string, to string,
) (err error) {
var from_path string var fromPath string
// The from path includes the bucket. Take care not to include an empty storageDir // The from path includes the bucket. Take care not to include an empty storageDir
// string as Wasabi's backend will return 404 on URLs with double slashes. // string as Wasabi's backend will return 404 on URLs with double slashes.
if storage.storageDir == "" { if storage.storageDir == "" {
from_path = fmt.Sprintf("/%s/%s", storage.bucket, from) fromPath = fmt.Sprintf("/%s/%s", storage.bucket, from)
} else { } else {
from_path = fmt.Sprintf("/%s/%s/%s", storage.bucket, storage.storageDir, from) fromPath = fmt.Sprintf("/%s/%s/%s", storage.bucket, storage.storageDir, from)
} }
object := fmt.Sprintf("https://%s@%s%s", object := fmt.Sprintf("https://%s@%s%s", storage.region, storage.endpoint, fromPath)
storage.region, storage.endpoint, from_path)
toPath := to
// The object's new name is relative to the top of the bucket. // The object's new name is relative to the top of the bucket.
new_name := fmt.Sprintf("%s/%s", storage.storageDir, to) if storage.storageDir != "" {
toPath = fmt.Sprintf("%s/%s", storage.storageDir, to)
}
timestamp := time.Now().Format(time.RFC1123Z) timestamp := time.Now().Format(time.RFC1123Z)
signing_string := fmt.Sprintf("MOVE\n\n\n%s\n%s", timestamp, from_path) signingString := fmt.Sprintf("MOVE\n\n\n%s\n%s", timestamp, fromPath)
signer := hmac.New(sha1.New, []byte(storage.secret)) signer := hmac.New(sha1.New, []byte(storage.secret))
signer.Write([]byte(signing_string)) signer.Write([]byte(signingString))
signature := base64.StdEncoding.EncodeToString(signer.Sum(nil)) signature := base64.StdEncoding.EncodeToString(signer.Sum(nil))
authorization := fmt.Sprintf("AWS %s:%s", storage.key, signature) authorization := fmt.Sprintf("AWS %s:%s", storage.key, signature)
request, error := http.NewRequest("MOVE", object, nil) request, err := http.NewRequest("MOVE", object, nil)
if error != nil { if err != nil {
return error return err
} }
request.Header.Add("Authorization", authorization) request.Header.Add("Authorization", authorization)
request.Header.Add("Date", timestamp) request.Header.Add("Date", timestamp)
request.Header.Add("Destination", new_name) request.Header.Add("Destination", toPath)
request.Header.Add("Host", storage.endpoint) request.Header.Add("Host", storage.endpoint)
request.Header.Add("Overwrite", "true") request.Header.Add("Overwrite", "true")
response, error := storage.client.Do(request) response, err := storage.client.Do(request)
if error != nil { if err != nil {
return error return err
} }
defer response.Body.Close() defer response.Body.Close()