fix: honor mpMaxParts across partNumber validation

Multipart partNumber validation was inconsistent because some handlers still
enforced the hardcoded S3 default while others used the instance-level
mpMaxParts setting. This created a split API contract where changing mpMaxParts
did not reliably affect all relevant endpoints. This change routes all
partNumber upper-bound checks through a shared effective limit helper so
deployments that customize mpMaxParts get consistent behavior across GetObject,
HeadObject, UploadPart, and UploadPartCopy, while preserving the default
S3-compatible maximum when mpMaxParts is unset.
This commit is contained in:
Ben McClelland
2026-07-30 08:38:19 -07:00
parent f2bfe2f261
commit e146646665
4 changed files with 12 additions and 4 deletions
+8
View File
@@ -84,6 +84,14 @@ func (c S3ApiController) getAclHeaderValue(ctx fiber.Ctx, key string, defaultVal
return ctx.Get(key, defaultValues...)
}
func (c S3ApiController) effectiveMpMaxParts() int {
if c.mpMaxParts > 0 {
return c.mpMaxParts
}
return maxPartNumber
}
// Returns MethodNotAllowed for unmatched routes
func (c S3ApiController) HandleErrorRoute(err error) Controller {
return func(ctx fiber.Ctx) (*Response, error) {
+1 -1
View File
@@ -451,7 +451,7 @@ func (c S3ApiController) GetObject(ctx fiber.Ctx) (*Response, error) {
var partNumber *int32
if ctx.Request().URI().QueryArgs().Has("partNumber") {
if partNumberQuery < minPartNumber || partNumberQuery > maxPartNumber {
if partNumberQuery < minPartNumber || partNumberQuery > int32(c.effectiveMpMaxParts()) {
debuglogger.Logf("invalid part number: %d", partNumberQuery)
return &Response{
MetaOpts: &MetaOptions{
+1 -1
View File
@@ -99,7 +99,7 @@ func (c S3ApiController) HeadObject(ctx fiber.Ctx) (*Response, error) {
var partNumber *int32
if ctx.Request().URI().QueryArgs().Has("partNumber") {
if partNumberQuery < minPartNumber || partNumberQuery > maxPartNumber {
if partNumberQuery < minPartNumber || partNumberQuery > int32(c.effectiveMpMaxParts()) {
debuglogger.Logf("invalid part number: %d", partNumberQuery)
return &Response{
MetaOpts: &MetaOptions{
+2 -2
View File
@@ -255,7 +255,7 @@ func (c S3ApiController) UploadPart(ctx fiber.Ctx) (*Response, error) {
}, err
}
if partNumber < minPartNumber || partNumber > int32(c.mpMaxParts) {
if partNumber < minPartNumber || partNumber > int32(c.effectiveMpMaxParts()) {
debuglogger.Logf("invalid part number: %d", partNumber)
return &Response{
MetaOpts: &MetaOptions{
@@ -390,7 +390,7 @@ func (c S3ApiController) UploadPartCopy(ctx fiber.Ctx) (*Response, error) {
}, s3err.GetAPIError(s3err.ErrNonEmptyRequestBody)
}
if partNumber < minPartNumber || partNumber > maxPartNumber {
if partNumber < minPartNumber || partNumber > int32(c.effectiveMpMaxParts()) {
debuglogger.Logf("invalid part number: %d", partNumber)
return &Response{
MetaOpts: &MetaOptions{