Skip to content

Commit

Permalink
*: Limit DeleteObjects request object amount
Browse files Browse the repository at this point in the history
Closes #844.

Signed-off-by: Evgenii Baidakov <[email protected]>
  • Loading branch information
smallhive committed Oct 13, 2023
1 parent 459d65a commit 9a0aacc
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 4 deletions.
9 changes: 5 additions & 4 deletions api/handler/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ type (

// Config contains data which handler needs to keep.
Config struct {
Policy PlacementPolicy
DefaultMaxAge int
NotificatorEnabled bool
CopiesNumber uint32
Policy PlacementPolicy
DefaultMaxAge int
NotificatorEnabled bool
CopiesNumber uint32
MaxDeletePerRequest int
}

PlacementPolicy interface {
Expand Down
5 changes: 5 additions & 0 deletions api/handler/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
return
}

if len(requested.Objects) > h.cfg.MaxDeletePerRequest {
h.logAndSendError(w, "to many objects to delete", reqInfo, layer.ErrTooManyObjectForDeletion)
return
}

removed := make(map[string]*layer.VersionedObject)
toRemove := make([]*layer.VersionedObject, 0, len(requested.Objects))
for _, obj := range requested.Objects {
Expand Down
4 changes: 4 additions & 0 deletions api/handler/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func transformToS3Error(err error) error {
return s3errors.GetAPIError(s3errors.ErrUnsupportedMetadata)
}

if errors.Is(err, layer.ErrTooManyObjectForDeletion) {
return s3errors.GetAPIError(s3errors.ErrBadRequest)
}

return s3errors.GetAPIError(s3errors.ErrInternalError)
}

Expand Down
3 changes: 3 additions & 0 deletions api/layer/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ var ErrAccessDenied = errors.New("access denied")
// ErrMetaEmptyParameterValue describes situation when meta parameter was passed but with empty value.
var ErrMetaEmptyParameterValue = errors.New("meta empty parameter value")

// ErrTooManyObjectForDeletion is returned if user trying to delete to many objects per request.
var ErrTooManyObjectForDeletion = errors.New("to many objects for deletion")

// NeoFS represents virtual connection to NeoFS network.
type NeoFS interface {
// CreateContainer creates and saves parameterized container in NeoFS.
Expand Down
5 changes: 5 additions & 0 deletions cmd/s3-gw/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,11 @@ func (a *App) initHandler() {
cfg.CopiesNumber = val
}

cfg.MaxDeletePerRequest = a.cfg.GetInt(cfgMaxObjectToDeletePerRequest)
if cfg.MaxDeletePerRequest == 0 {
cfg.MaxDeletePerRequest = defaultMaxObjectDeletePerRequest
}

var err error
a.api, err = handler.New(a.log, a.obj, a.nc, cfg)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions cmd/s3-gw/app_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (

defaultMaxClientsCount = 100
defaultMaxClientsDeadline = time.Second * 30

defaultMaxObjectDeletePerRequest = 1000
)

const ( // Settings.
Expand Down Expand Up @@ -121,6 +123,9 @@ const ( // Settings.
// Number of the object copies to consider PUT to NeoFS successful.
cfgSetCopiesNumber = "neofs.set_copies_number"

// Maximum number of objects to be deleted per request limit by this value.
cfgMaxObjectToDeletePerRequest = "max_object_to_delete_per_request"

// Timeout between retrieving actual epoch from NeoFS. Actual only if slicer.enabled = true.
cfgEpochUpdateInterval = "neofs.epoch_update_interval"

Expand Down
5 changes: 5 additions & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,8 @@ allowed_access_key_id_prefixes:

# Allows to use slicer for Object uploading.
internal_slicer: false

# Requests

# Maximum number of objects to be deleted per request limit by this value.
max_object_to_delete_per_request: 1000
2 changes: 2 additions & 0 deletions docs/aws_s3_compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Reference:
| 🔵 | WriteGetObjectResponse | Waiting for Lambda to be developed |
| 🟢 | GetObjectAttributes | |

* DeleteObjects limited by max amount of objects which can be deleted per request. See `max_object_to_delete_per_request` parameter.

## ACL

For now there are some limitations:
Expand Down
7 changes: 7 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,10 @@ neofs:
| Parameter | Type | Default value | Description |
|---------------------|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `set_copies_number` | `uint32` | `0` | Number of the object copies to consider PUT to NeoFS successful. <br/>Default value `0` means that object will be processed according to the container's placement policy |

# `requests` section

Contains parameters to configure requests runtime.

* max_object_to_delete_per_request - allows to set maximum object amount which can be deleted per request.
If amount is higher `Bad request` will be returned. Default value is 1000.

0 comments on commit 9a0aacc

Please sign in to comment.