mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-23 18:21:28 +00:00
s3api: evaluate conditional headers after version resolution
Move conditional header evaluation (If-Match, If-None-Match, etc.) to after the version resolution step in GetObjectAttributesHandler. This ensures that when a specific versionId is requested, conditions are checked against the correct version entry rather than always against the latest version. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -105,12 +105,6 @@ func (s3a *S3ApiServer) GetObjectAttributesHandler(w http.ResponseWriter, r *htt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process conditional headers
|
|
||||||
result, handled := s3a.processConditionalHeaders(w, r, bucket, object, "GetObjectAttributesHandler")
|
|
||||||
if handled {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for specific version ID
|
// Check for specific version ID
|
||||||
versionId := r.URL.Query().Get("versionId")
|
versionId := r.URL.Query().Get("versionId")
|
||||||
|
|
||||||
@@ -192,19 +186,33 @@ func (s3a *S3ApiServer) GetObjectAttributesHandler(w http.ResponseWriter, r *htt
|
|||||||
|
|
||||||
w.Header().Set("x-amz-version-id", targetVersionId)
|
w.Header().Set("x-amz-version-id", targetVersionId)
|
||||||
} else {
|
} else {
|
||||||
// Non-versioned: reuse entry from conditional check or fetch
|
entry, err = s3a.fetchObjectEntry(bucket, object)
|
||||||
if result.Entry != nil {
|
if err != nil {
|
||||||
entry = result.Entry
|
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||||
} else {
|
return
|
||||||
entry, err = s3a.fetchObjectEntry(bucket, object)
|
}
|
||||||
if err != nil {
|
if entry == nil {
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if entry == nil {
|
}
|
||||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
|
||||||
return
|
// Evaluate conditional headers against the resolved entry (after version resolution)
|
||||||
|
// This ensures conditions are checked against the correct version, not always the latest
|
||||||
|
if s3a.hasConditionalHeaders(r) {
|
||||||
|
headers, errCode := parseConditionalHeaders(r)
|
||||||
|
if errCode != s3err.ErrNone {
|
||||||
|
s3err.WriteErrorResponse(w, r, errCode)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result := s3a.validateConditionalHeadersForReads(r, headers, entry, bucket, object)
|
||||||
|
if result.ErrorCode != s3err.ErrNone {
|
||||||
|
glog.V(3).Infof("GetObjectAttributesHandler: Conditional header check failed for %s/%s with error %v", bucket, object, result.ErrorCode)
|
||||||
|
if result.ErrorCode == s3err.ErrNotModified && result.ETag != "" {
|
||||||
|
w.Header().Set("ETag", result.ETag)
|
||||||
}
|
}
|
||||||
|
s3err.WriteErrorResponse(w, r, result.ErrorCode)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user