This commit is contained in:
himku 2025-08-02 10:50:22 +03:00 committed by GitHub
commit ea25942c1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 15 deletions

View File

@ -1739,8 +1739,7 @@ func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketNam
} }
uploadID := multipartResponse.UploadID uploadID := multipartResponse.UploadID
a := 0 a, b := 0, int(globalMinPartSize)
b := globalMinPartSize
var parts []CompletePart var parts []CompletePart
for partNumber := 1; partNumber <= 2; partNumber++ { for partNumber := 1; partNumber <= 2; partNumber++ {
// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler. // initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
@ -1760,7 +1759,7 @@ func testAPICopyObjectPartHandlerSanity(obj ObjectLayer, instanceType, bucketNam
// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler. // Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
// Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request. // Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request.
a = globalMinPartSize + 1 a = int(globalMinPartSize + 1)
b = len(bytesData[0].byteData) - 1 b = len(bytesData[0].byteData) - 1
apiRouter.ServeHTTP(rec, req) apiRouter.ServeHTTP(rec, req)
if rec.Code != http.StatusOK { if rec.Code != http.StatusOK {

View File

@ -448,6 +448,9 @@ func serverHandleCmdArgs(ctxt serverCtxt) {
} }
func initAllSubsystems(ctx context.Context) { func initAllSubsystems(ctx context.Context) {
// Initialize minimum part size configuration
initMinPartSize()
// Initialize notification peer targets // Initialize notification peer targets
globalNotificationSys = NewNotificationSys(globalEndpoints) globalNotificationSys = NewNotificationSys(globalEndpoints)

View File

@ -289,14 +289,31 @@ const (
// using 'curl' and presigned URL. // using 'curl' and presigned URL.
globalMaxObjectSize = 5 * humanize.TiByte globalMaxObjectSize = 5 * humanize.TiByte
// Minimum Part size for multipart upload is 5MiB
globalMinPartSize = 5 * humanize.MiByte
// Maximum Part ID for multipart upload is 10000 // Maximum Part ID for multipart upload is 10000
// (Acceptable values range from 1 to 10000 inclusive) // (Acceptable values range from 1 to 10000 inclusive)
globalMaxPartID = 10000 globalMaxPartID = 10000
) )
// Minimum Part size for multipart upload, configurable via environment variable
var globalMinPartSize int64
// initMinPartSize initializes the minimum part size from environment variable
// or uses default value of 5MiB
//
//nolint:unused
func initMinPartSize() {
defaultMinPartSize := int64(5 * humanize.MiByte)
if envMinPartSize := env.Get("MINIO_MIN_PART_SIZE", ""); envMinPartSize != "" {
if size, err := humanize.ParseBytes(envMinPartSize); err == nil {
globalMinPartSize = int64(size)
} else {
globalMinPartSize = defaultMinPartSize
}
} else {
globalMinPartSize = defaultMinPartSize
}
}
// isMaxObjectSize - verify if max object size // isMaxObjectSize - verify if max object size
func isMaxObjectSize(size int64) bool { func isMaxObjectSize(size int64) bool {
return size > globalMaxObjectSize return size > globalMaxObjectSize

View File

@ -23,9 +23,12 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"os"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"github.com/dustin/go-humanize"
) )
// Tests maximum object size. // Tests maximum object size.
@ -227,7 +230,7 @@ func TestDumpRequest(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
req.RequestURI = "/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=USWUXHGYZQYFYFFIT3RE%2F20170529%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20170529T190139Z&X-Amz-Expires=600&X-Amz-Signature=19b58080999df54b446fc97304eb8dda60d3df1812ae97f3e8783351bfd9781d&X-Amz-SignedHeaders=host&prefix=Hello%2AWorld%2A" req.RequestURI = "/?" + req.URL.RawQuery
req.Header.Set("content-md5", "====test") req.Header.Set("content-md5", "====test")
jsonReq := dumpRequest(req) jsonReq := dumpRequest(req)
type jsonResult struct { type jsonResult struct {
@ -246,15 +249,9 @@ func TestDumpRequest(t *testing.T) {
} }
// Look for expected query values // Look for expected query values
expectedQuery := url.Values{} expectedQuery := req.URL.Query()
expectedQuery.Set("prefix", "Hello*World*")
expectedQuery.Set("X-Amz-Algorithm", "AWS4-HMAC-SHA256")
expectedQuery.Set("X-Amz-Credential", "USWUXHGYZQYFYFFIT3RE/20170529/us-east-1/s3/aws4_request")
expectedQuery.Set("X-Amz-Date", "20170529T190139Z")
expectedQuery.Set("X-Amz-Expires", "600")
expectedQuery.Set("X-Amz-SignedHeaders", "host")
expectedQuery.Set("X-Amz-Signature", "19b58080999df54b446fc97304eb8dda60d3df1812ae97f3e8783351bfd9781d") expectedQuery.Set("X-Amz-Signature", "19b58080999df54b446fc97304eb8dda60d3df1812ae97f3e8783351bfd9781d")
expectedRequestURI := "/?" + expectedQuery.Encode() expectedRequestURI := req.URL.Path + "?" + expectedQuery.Encode()
if !reflect.DeepEqual(res.RequestURI, expectedRequestURI) { if !reflect.DeepEqual(res.RequestURI, expectedRequestURI) {
t.Fatalf("Expected %#v, got %#v", expectedRequestURI, res.RequestURI) t.Fatalf("Expected %#v, got %#v", expectedRequestURI, res.RequestURI)
} }
@ -399,3 +396,43 @@ func TestGetMinioMode(t *testing.T) {
globalIsDistErasure, globalIsErasure = false, false globalIsDistErasure, globalIsErasure = false, false
testMinioMode(globalMinioModeFS) testMinioMode(globalMinioModeFS)
} }
// Test initMinPartSize function
func TestInitMinPartSize(t *testing.T) {
// Save original value
originalValue := globalMinPartSize
// Test case 1: No environment variable set, should use default
os.Unsetenv("MINIO_MIN_PART_SIZE")
initMinPartSize()
expectedDefault := int64(5 * humanize.MiByte)
if globalMinPartSize != expectedDefault {
t.Errorf("Expected default value %d, got %d", expectedDefault, globalMinPartSize)
}
// Test case 2: Valid environment variable set
os.Setenv("MINIO_MIN_PART_SIZE", "10MiB")
initMinPartSize()
expectedFromEnv := int64(10 * humanize.MiByte)
if globalMinPartSize != expectedFromEnv {
t.Errorf("Expected value from env %d, got %d", expectedFromEnv, globalMinPartSize)
}
// Test case 3: Invalid environment variable set, should fallback to default
os.Setenv("MINIO_MIN_PART_SIZE", "invalid-size")
initMinPartSize()
if globalMinPartSize != expectedDefault {
t.Errorf("Expected fallback to default %d, got %d", expectedDefault, globalMinPartSize)
}
// Test case 4: Large value
os.Setenv("MINIO_MIN_PART_SIZE", "100MiB")
initMinPartSize()
expectedLarge := int64(100 * humanize.MiByte)
if globalMinPartSize != expectedLarge {
t.Errorf("Expected large value %d, got %d", expectedLarge, globalMinPartSize)
}
// Restore original value
globalMinPartSize = originalValue
}