mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-06-13 23:36:45 +03:00
s3: return NoSuchVersion (not NoSuchKey) for a missing versionId (#9749)
GET/HEAD object with an explicit versionId that does not exist returned NoSuchKey. AWS S3 returns NoSuchVersion (404) for this case; tools that distinguish "key gone" from "this version gone" rely on that code. Add the ErrNoSuchVersion error code and use it on the GET and HEAD specific-version lookups. Only a genuine not-found maps to NoSuchVersion; a transient or internal filer error now maps to InternalError (500) instead of a misleading 404. getSpecificObjectVersion wraps its lookup error with %w so callers can detect filer_pb.ErrNotFound.
This commit is contained in:
@@ -641,7 +641,11 @@ func (s3a *S3ApiServer) GetObjectHandler(w http.ResponseWriter, r *http.Request)
|
||||
entry, err = s3a.getSpecificObjectVersion(bucket, object, versionId)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get specific version %s: %v", versionId, err)
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
||||
if errors.Is(err, filer_pb.ErrNotFound) {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchVersion)
|
||||
} else {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||
}
|
||||
return
|
||||
}
|
||||
targetVersionId = versionId
|
||||
@@ -2149,7 +2153,11 @@ func (s3a *S3ApiServer) HeadObjectHandler(w http.ResponseWriter, r *http.Request
|
||||
entry, err = s3a.getSpecificObjectVersion(bucket, object, versionId)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to get specific version %s for %s/%s: %v", versionId, bucket, object, err)
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchKey)
|
||||
if errors.Is(err, filer_pb.ErrNotFound) {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchVersion)
|
||||
} else {
|
||||
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
|
||||
}
|
||||
return
|
||||
}
|
||||
targetVersionId = versionId
|
||||
|
||||
@@ -984,7 +984,7 @@ func (s3a *S3ApiServer) getSpecificObjectVersion(bucket, object, versionId strin
|
||||
bucketDir := s3a.bucketDir(bucket)
|
||||
entry, err := s3a.getEntry(bucketDir, normalizedObject)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("null version object %s not found: %v", normalizedObject, err)
|
||||
return nil, fmt.Errorf("null version object %s not found: %w", normalizedObject, err)
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
@@ -995,7 +995,7 @@ func (s3a *S3ApiServer) getSpecificObjectVersion(bucket, object, versionId strin
|
||||
|
||||
entry, err := s3a.getEntry(versionsDir, versionFile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("version %s not found: %v", versionId, err)
|
||||
return nil, fmt.Errorf("version %s not found: %w", versionId, err)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
|
||||
@@ -57,6 +57,7 @@ const (
|
||||
ErrNoSuchCORSConfiguration
|
||||
ErrNoSuchLifecycleConfiguration
|
||||
ErrNoSuchKey
|
||||
ErrNoSuchVersion
|
||||
ErrNoSuchUpload
|
||||
ErrInvalidBucketName
|
||||
ErrInvalidBucketState
|
||||
@@ -281,6 +282,11 @@ var errorCodeResponse = map[ErrorCode]APIError{
|
||||
Description: "The specified key does not exist.",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
},
|
||||
ErrNoSuchVersion: {
|
||||
Code: "NoSuchVersion",
|
||||
Description: "The specified version does not exist.",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
},
|
||||
ErrNoSuchUpload: {
|
||||
Code: "NoSuchUpload",
|
||||
Description: "The specified multipart upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed.",
|
||||
|
||||
Reference in New Issue
Block a user