Browse Source

ErrBucketAlreadyOwnedByYou ErrNoSuchBucket

do-not-retry-if-error-is-NotFound
chrislu 3 months ago
parent
commit
b579532c31
  1. 8
      weed/s3api/filer_util.go
  2. 44
      weed/s3api/s3api_bucket_handlers.go

8
weed/s3api/filer_util.go

@ -65,18 +65,10 @@ func doDeleteEntry(client filer_pb.SeaweedFilerClient, parentDirectoryPath strin
glog.V(1).Infof("delete entry %v/%v: %v", parentDirectoryPath, entryName, request)
if resp, err := client.DeleteEntry(context.Background(), request); err != nil {
// Treat NotFound as success for idempotency
if strings.Contains(err.Error(), filer_pb.ErrNotFound.Error()) {
return nil
}
glog.V(0).Infof("delete entry %v: %v", request, err)
return fmt.Errorf("delete entry %s/%s: %v", parentDirectoryPath, entryName, err)
} else {
if resp.Error != "" {
// Treat NotFound as success for idempotency
if strings.Contains(resp.Error, filer_pb.ErrNotFound.Error()) {
return nil
}
return fmt.Errorf("delete entry %s/%s: %v", parentDirectoryPath, entryName, resp.Error)
}
}

44
weed/s3api/s3api_bucket_handlers.go

@ -108,27 +108,6 @@ func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request)
return
}
// Idempotency: if bucket already exists and is owned by the requester, return success.
identityId := r.Header.Get(s3_constants.AmzIdentityId)
if existingEntry, err := s3a.getEntry(s3a.option.BucketsPath, bucket); err == nil && existingEntry != nil && existingEntry.IsDirectory {
if owner, ok := existingEntry.Extended[s3_constants.AmzIdentityId]; ok {
if string(owner) == identityId || identityId == "" {
w.Header().Set("Location", "/"+bucket)
writeSuccessResponseEmpty(w, r)
return
}
} else {
// No owner recorded; treat as success for idempotency
w.Header().Set("Location", "/"+bucket)
writeSuccessResponseEmpty(w, r)
return
}
} else if err != nil && !errors.Is(err, filer_pb.ErrNotFound) {
// Unexpected error fetching existing entry
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
// avoid duplicated buckets
errCode := s3err.ErrNone
if err := s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
@ -152,8 +131,27 @@ func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request)
return
}
if exist, err := s3a.exists(s3a.option.BucketsPath, bucket, true); err == nil && exist {
// Check if the bucket is owned by the same user
identityId := r.Header.Get(s3_constants.AmzIdentityId)
if existingEntry, err := s3a.getEntry(s3a.option.BucketsPath, bucket); err == nil && existingEntry != nil {
if owner, ok := existingEntry.Extended[s3_constants.AmzIdentityId]; ok {
if string(owner) == identityId {
errCode = s3err.ErrBucketAlreadyOwnedByYou
} else {
errCode = s3err.ErrBucketAlreadyExists
}
} else {
// No owner recorded, treat as owned by current user if no identity
if identityId == "" {
errCode = s3err.ErrBucketAlreadyOwnedByYou
} else {
errCode = s3err.ErrBucketAlreadyExists
}
}
} else {
errCode = s3err.ErrBucketAlreadyExists
}
}
if errCode != s3err.ErrNone {
s3err.WriteErrorResponse(w, r, errCode)
return
@ -213,10 +211,10 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
bucket, _ := s3_constants.GetBucketAndObject(r)
glog.V(3).Infof("DeleteBucketHandler %s", bucket)
// Idempotency: if the bucket doesn't exist, return NoContent (success)
// Check if bucket exists - return proper AWS error if not found
if entry, err := s3a.getEntry(s3a.option.BucketsPath, bucket); err != nil || entry == nil {
if errors.Is(err, filer_pb.ErrNotFound) || entry == nil {
s3err.WriteEmptyResponse(w, r, http.StatusNoContent)
s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchBucket)
return
}
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)

Loading…
Cancel
Save