s3: try to keep the maximum precision in ModTime with --user-server-modtime

Before this change if --user-server-modtime was in use the ModTime
could change for an object as we receive it accurate to the nearest ms
in listings, but only accurate to the nearest second in HEAD and GET
requests.

Normally AWS returns the milliseconds as .000 in listings, but if
versions are in use it may not. Storj S3 also seems to return
milliseconds.

This patch tries to keep the maximum precision in the last modified
time, so it doesn't update a last modified time with a truncated
version if the times were the same to the nearest second.

See: https://forum.rclone.org/t/cache-fingerprint-miss-behavior-leading-to-false-positive-stalen-cache/33404/
This commit is contained in:
Nick Craig-Wood 2022-10-08 11:27:17 +01:00
parent 6654b66114
commit cf0bf159ab

View File

@ -4507,7 +4507,15 @@ func (o *Object) setMetaData(resp *s3.HeadObjectOutput) {
o.lastModified = time.Now()
fs.Logf(o, "Failed to read last modified")
} else {
o.lastModified = *resp.LastModified
// Try to keep the maximum precision in lastModified. If we read
// it from listings then it may have millisecond precision, but
// if we read it from a HEAD/GET request then it will have
// second precision.
equalToWithinOneSecond := o.lastModified.Truncate(time.Second).Equal((*resp.LastModified).Truncate(time.Second))
newHasNs := (*resp.LastModified).Nanosecond() != 0
if !equalToWithinOneSecond || newHasNs {
o.lastModified = *resp.LastModified
}
}
o.mimeType = aws.StringValue(resp.ContentType)