mirror of
https://github.com/versity/versitygw.git
synced 2026-07-19 14:32:20 +00:00
fix: support asterisk read preconditions
Fixes #2185 Add asterisk handling for `If-Match` and `If-None-Match` read preconditions across `GetObject`, `HeadObject`, `CopyObject`, and `UploadPartCopy`. `If-Match`: `*` now matches any `ETag`, while `If-None-Match`: `*` returns `304 Not Modified`.
This commit is contained in:
+3
-2
@@ -643,6 +643,7 @@ type PreConditions struct {
|
||||
// - if-modified-since
|
||||
// - if-unmodified-since
|
||||
// if-match and if-none-match are ETag comparisons
|
||||
// if-match "*" matches any ETag, and if-none-match "*" matches no ETag
|
||||
// if-modified-since and if-unmodified-since are last modifed time comparisons
|
||||
func EvaluatePreconditions(etag string, modTime time.Time, preconditions PreConditions) error {
|
||||
if preconditions.IfMatch == nil && preconditions.IfNoneMatch == nil && preconditions.IfModSince == nil && preconditions.IfUnmodeSince == nil {
|
||||
@@ -654,10 +655,10 @@ func EvaluatePreconditions(etag string, modTime time.Time, preconditions PreCond
|
||||
// convert all conditions to *bool to evaluate the conditions
|
||||
var ifMatch, ifNoneMatch, ifModSince, ifUnmodeSince *bool
|
||||
if preconditions.IfMatch != nil {
|
||||
ifMatch = getBoolPtr(*preconditions.IfMatch == etag)
|
||||
ifMatch = getBoolPtr(*preconditions.IfMatch == "*" || *preconditions.IfMatch == etag)
|
||||
}
|
||||
if preconditions.IfNoneMatch != nil {
|
||||
ifNoneMatch = getBoolPtr(*preconditions.IfNoneMatch != etag)
|
||||
ifNoneMatch = getBoolPtr(*preconditions.IfNoneMatch != "*" && *preconditions.IfNoneMatch != etag)
|
||||
}
|
||||
if preconditions.IfModSince != nil {
|
||||
ifModSince = getBoolPtr(preconditions.IfModSince.UTC().Before(modTime.UTC()))
|
||||
|
||||
@@ -1208,6 +1208,19 @@ func CopyObject_conditional_reads(s *S3Conf) error {
|
||||
{nil, &etagTrimmed, nil, &before, errCond},
|
||||
{nil, &etagTrimmed, nil, &after, errMod},
|
||||
{nil, &etagTrimmed, nil, nil, errMod},
|
||||
|
||||
// if-match and if-none-match with asterisk
|
||||
{getPtr("*"), nil, nil, nil, nil},
|
||||
{getPtr("*"), nil, &after, nil, errMod},
|
||||
{getPtr("*"), getPtr("invalid_etag"), nil, nil, nil},
|
||||
{getPtr("*"), etag, nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, &before, errMod},
|
||||
{nil, getPtr("*"), nil, nil, errMod},
|
||||
{nil, getPtr("*"), &before, nil, errMod},
|
||||
{nil, getPtr("*"), nil, &after, errMod},
|
||||
{nil, getPtr("*"), nil, &before, errCond},
|
||||
{getPtr("invalid_etag"), getPtr("*"), nil, nil, errCond},
|
||||
} {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.CopyObject(ctx, &s3.CopyObjectInput{
|
||||
|
||||
@@ -539,6 +539,19 @@ func GetObject_conditional_reads(s *S3Conf) error {
|
||||
{nil, &etagTrimmed, nil, &before, errCond},
|
||||
{nil, &etagTrimmed, nil, &after, errMod},
|
||||
{nil, &etagTrimmed, nil, nil, errMod},
|
||||
|
||||
// if-match and if-none-match with asterisk
|
||||
{getPtr("*"), nil, nil, nil, nil},
|
||||
{getPtr("*"), nil, &after, nil, errMod},
|
||||
{getPtr("*"), getPtr("invalid_etag"), nil, nil, nil},
|
||||
{getPtr("*"), etag, nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, &before, errMod},
|
||||
{nil, getPtr("*"), nil, nil, errMod},
|
||||
{nil, getPtr("*"), &before, nil, errMod},
|
||||
{nil, getPtr("*"), nil, &after, errMod},
|
||||
{nil, getPtr("*"), nil, &before, errCond},
|
||||
{getPtr("invalid_etag"), getPtr("*"), nil, nil, errCond},
|
||||
} {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.GetObject(ctx, &s3.GetObjectInput{
|
||||
|
||||
@@ -534,6 +534,19 @@ func HeadObject_conditional_reads(s *S3Conf) error {
|
||||
{nil, &etagTrimmed, nil, &before, errCond},
|
||||
{nil, &etagTrimmed, nil, &after, errMod},
|
||||
{nil, &etagTrimmed, nil, nil, errMod},
|
||||
|
||||
// if-match and if-none-match with asterisk
|
||||
{getPtr("*"), nil, nil, nil, nil},
|
||||
{getPtr("*"), nil, &after, nil, errMod},
|
||||
{getPtr("*"), getPtr("invalid_etag"), nil, nil, nil},
|
||||
{getPtr("*"), etag, nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, &before, errMod},
|
||||
{nil, getPtr("*"), nil, nil, errMod},
|
||||
{nil, getPtr("*"), &before, nil, errMod},
|
||||
{nil, getPtr("*"), nil, &after, errMod},
|
||||
{nil, getPtr("*"), nil, &before, errCond},
|
||||
{getPtr("invalid_etag"), getPtr("*"), nil, nil, errCond},
|
||||
} {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.HeadObject(ctx, &s3.HeadObjectInput{
|
||||
|
||||
@@ -804,6 +804,19 @@ func UploadPartCopy_conditional_reads(s *S3Conf) error {
|
||||
{nil, &etagTrimmed, nil, &before, errCond},
|
||||
{nil, &etagTrimmed, nil, &after, errMod},
|
||||
{nil, &etagTrimmed, nil, nil, errMod},
|
||||
|
||||
// if-match and if-none-match with asterisk
|
||||
{getPtr("*"), nil, nil, nil, nil},
|
||||
{getPtr("*"), nil, &after, nil, errMod},
|
||||
{getPtr("*"), getPtr("invalid_etag"), nil, nil, nil},
|
||||
{getPtr("*"), etag, nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, nil, errMod},
|
||||
{getPtr("*"), getPtr("*"), nil, &before, errMod},
|
||||
{nil, getPtr("*"), nil, nil, errMod},
|
||||
{nil, getPtr("*"), &before, nil, errMod},
|
||||
{nil, getPtr("*"), nil, &after, errMod},
|
||||
{nil, getPtr("*"), nil, &before, errCond},
|
||||
{getPtr("invalid_etag"), getPtr("*"), nil, nil, errCond},
|
||||
} {
|
||||
mpKey := "mp-key"
|
||||
mp, err := createMp(s3client, bucket, mpKey)
|
||||
|
||||
Reference in New Issue
Block a user