diff --git a/weed/s3api/filer_util.go b/weed/s3api/filer_util.go index ad16a3b48..9dd9a684e 100644 --- a/weed/s3api/filer_util.go +++ b/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) } } diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index 36d630f95..edda10e2d 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/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,7 +131,26 @@ func (s3a *S3ApiServer) PutBucketHandler(w http.ResponseWriter, r *http.Request) return } if exist, err := s3a.exists(s3a.option.BucketsPath, bucket, true); err == nil && exist { - errCode = s3err.ErrBucketAlreadyExists + // 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) @@ -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)