serve s3: fix modtime not being set when only mtime metadata is supplied on PUT
The mtime metadata fallback was nested inside the X-Amz-Meta-Mtime branch, so it only ran when X-Amz-Meta-Mtime was present but invalid - and then set the modtime from the invalid value's failed parse rather than parsing mtime. An object PUT with only mtime metadata kept the upload time as its modtime. Now the two keys are checked independently, as TouchObject already does.
This commit is contained in:
@@ -424,8 +424,11 @@ func (b *s3Backend) PutObject(
|
||||
return result, _vfs.Chtimes(fp, ti, ti)
|
||||
}
|
||||
// ignore error since the file is successfully created
|
||||
}
|
||||
|
||||
if val, ok := meta["mtime"]; ok {
|
||||
if val, ok := meta["mtime"]; ok {
|
||||
ti, err := swift.FloatStringToTime(val)
|
||||
if err == nil {
|
||||
b.storeModtime(fp, meta, val)
|
||||
return result, _vfs.Chtimes(fp, ti, ti)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ncw/swift/v2"
|
||||
"github.com/rclone/gofakes3"
|
||||
"github.com/rclone/rclone/cmd/serve/proxy"
|
||||
"github.com/rclone/rclone/fs"
|
||||
@@ -152,6 +153,28 @@ func TestPutObjectFailureNewKey(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestPutObjectMtime checks that the object's modtime is set from the
|
||||
// "X-Amz-Meta-Mtime" or "mtime" metadata supplied with the PUT.
|
||||
func TestPutObjectMtime(t *testing.T) {
|
||||
want := fstest.Time("2011-12-25T12:59:59.123456789Z")
|
||||
for _, metaKey := range []string{"X-Amz-Meta-Mtime", "mtime"} {
|
||||
t.Run(metaKey, func(t *testing.T) {
|
||||
b, f, bucket := newPutTestBackend(t, "", nil)
|
||||
ctx := context.Background()
|
||||
const object = "mtime.txt"
|
||||
|
||||
contents := []byte(random.String(50))
|
||||
meta := map[string]string{metaKey: swift.TimeToFloatString(want)}
|
||||
_, err := b.PutObject(ctx, bucket, object, meta, bytes.NewReader(contents), int64(len(contents)))
|
||||
require.NoError(t, err)
|
||||
|
||||
o, err := f.NewObject(ctx, path.Join(bucket, object))
|
||||
require.NoError(t, err)
|
||||
fstest.AssertTimeEqualWithPrecision(t, object, want, o.ModTime(ctx), f.Precision())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// waitForObject waits for bucket/object to appear on the backing Fs (e.g.
|
||||
// after the VFS write-back delay).
|
||||
func waitForObject(t *testing.T, f fs.Fs, bucket, object string) {
|
||||
|
||||
Reference in New Issue
Block a user