Generate and call MultiDelete S3 requests based on entries received from the iterator.
(ctx context.Context, bucketName string, objectsIter iter.Seq[ObjectInfo], yield func(RemoveObjectResult) bool, opts RemoveObjectsOptions)
| 419 | |
| 420 | // Generate and call MultiDelete S3 requests based on entries received from the iterator. |
| 421 | func (c *Client) removeObjectsIter(ctx context.Context, bucketName string, objectsIter iter.Seq[ObjectInfo], yield func(RemoveObjectResult) bool, opts RemoveObjectsOptions) { |
| 422 | // NOTE: GCS does not support multi-object delete, use single DELETE requests. |
| 423 | if !c.useMultiDeleteForBulkDelete() { |
| 424 | c.removeObjectsSingleIter(ctx, bucketName, objectsIter, yield, opts) |
| 425 | return |
| 426 | } |
| 427 | |
| 428 | maxEntries := 1000 |
| 429 | urlValues := make(url.Values) |
| 430 | urlValues.Set("delete", "") |
| 431 | |
| 432 | // Build headers. |
| 433 | headers := make(http.Header) |
| 434 | if opts.GovernanceBypass { |
| 435 | // Set the bypass goverenance retention header |
| 436 | headers.Set(amzBypassGovernance, "true") |
| 437 | } |
| 438 | |
| 439 | processRemoveMultiObjectsResponseIter := func(batch []ObjectInfo, yield func(RemoveObjectResult) bool) bool { |
| 440 | if len(batch) == 0 { |
| 441 | return false |
| 442 | } |
| 443 | |
| 444 | // Generate remove multi objects XML request |
| 445 | removeBytes := generateRemoveMultiObjectsRequest(batch) |
| 446 | // Execute POST on bucket to remove objects. |
| 447 | resp, err := c.executeMethod(ctx, http.MethodPost, requestMetadata{ |
| 448 | bucketName: bucketName, |
| 449 | queryValues: urlValues, |
| 450 | contentBody: bytes.NewReader(removeBytes), |
| 451 | contentLength: int64(len(removeBytes)), |
| 452 | contentMD5Base64: sumMD5Base64(removeBytes), |
| 453 | contentSHA256Hex: sum256Hex(removeBytes), |
| 454 | customHeader: headers, |
| 455 | }) |
| 456 | if resp != nil { |
| 457 | defer closeResponse(resp) |
| 458 | if resp.StatusCode != http.StatusOK { |
| 459 | err = httpRespToErrorResponse(resp, bucketName, "") |
| 460 | } |
| 461 | } |
| 462 | if err != nil { |
| 463 | for _, b := range batch { |
| 464 | if !yield(RemoveObjectResult{ |
| 465 | ObjectName: b.Key, |
| 466 | ObjectVersionID: b.VersionID, |
| 467 | Err: err, |
| 468 | }) { |
| 469 | return false |
| 470 | } |
| 471 | } |
| 472 | return false |
| 473 | } |
| 474 | |
| 475 | // Parse multi delete XML response |
| 476 | rmResult := &deleteMultiObjectsResult{} |
| 477 | if err := xmlDecoder(resp.Body, rmResult); err != nil { |
| 478 | yield(RemoveObjectResult{ObjectName: "", Err: err}) |
no test coverage detected