Skip to content
8 changes: 8 additions & 0 deletions internal/configs/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ func parseAnnotations(ingEx *IngressEx, baseCfgParams *ConfigParams, isPlus bool
cfgParams.ClientMaxBodySize = clientMaxBodySize
}

if clientBodyBufferSize, exists := ingEx.Ingress.Annotations["nginx.org/client-body-buffer-size"]; exists {
size, err := ParseSize(clientBodyBufferSize)
if err != nil {
nl.Errorf(l, "Ingress %s/%s: Invalid value nginx.org/client-body-buffer-size: got %q: %v", ingEx.Ingress.GetNamespace(), ingEx.Ingress.GetName(), clientBodyBufferSize, err)
}
cfgParams.ClientBodyBufferSize = size
}

if redirectToHTTPS, exists, err := GetMapKeyAsBool(ingEx.Ingress.Annotations, "nginx.org/redirect-to-https", ingEx.Ingress); exists {
if err != nil {
nl.Error(l, err)
Expand Down
172 changes: 172 additions & 0 deletions internal/configs/annotations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,3 +755,175 @@ func TestGetRewriteTargetWithComplexValues(t *testing.T) {
})
}
}

func TestClientBodyBufferSizeAnnotationValid(t *testing.T) {
t.Parallel()

tests := []struct {
name string
clientBodyBufferSize string
expected string
}{
{
name: "valid size with k",
clientBodyBufferSize: "16k",
expected: "16k",
},
{
name: "valid size with M",
clientBodyBufferSize: "4M",
expected: "4M",
},
{
name: "valid size without suffix",
clientBodyBufferSize: "8192",
expected: "8192",
},
{
name: "single digit",
clientBodyBufferSize: "1k",
expected: "1k",
},
{
name: "zero value",
clientBodyBufferSize: "0",
expected: "0",
},
{
name: "large buffer size",
clientBodyBufferSize: "512K",
expected: "512K",
},
{
name: "megabyte buffer size",
clientBodyBufferSize: "64M",
expected: "64M",
},
{
name: "empty annotation",
clientBodyBufferSize: "",
expected: "",
},
{
name: "very large number",
clientBodyBufferSize: "999999999",
expected: "999999999",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

ingress := &networking.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test-ingress",
Namespace: "default",
Annotations: map[string]string{
"nginx.org/client-body-buffer-size": tt.clientBodyBufferSize,
},
},
}

ingEx := &IngressEx{
Ingress: ingress,
}

baseCfgParams := NewDefaultConfigParams(context.Background(), false)
result := parseAnnotations(ingEx, baseCfgParams, false, false, false, false, false)

if result.ClientBodyBufferSize != tt.expected {
t.Errorf("Test %q: expected ClientBodyBufferSize %q, got %q", tt.name, tt.expected, result.ClientBodyBufferSize)
}

result2 := parseAnnotations(ingEx, baseCfgParams, false, false, false, false, false)
if result2.ClientBodyBufferSize != tt.expected {
t.Errorf("Test %q with other annotations: expected ClientBodyBufferSize %q, got %q", tt.name, tt.expected, result2.ClientBodyBufferSize)
}
})
}
}

func TestClientBodyBufferSizeAnnotationInvalid(t *testing.T) {
t.Parallel()

tests := []struct {
name string
annotations map[string]string
}{
{
name: "annotation name case sensitivity",
annotations: map[string]string{
"nginx.org/Client-Body-Buffer-Size": "16k", // capital letters
},
},
{
name: "invalid time unit h",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "4h",
},
},
{
name: "invalid random string",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "3cd2", // wrong format, too many chars
},
},
{
name: "invalid with g suffix",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "2g",
},
},

{
name: "invalid negative value",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "-16k",
},
},
{
name: "invalid with text prefix",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "abc16k",
},
},
{
name: "invalid with special characters",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "16@k",
},
},
{
name: "invalid with letters",
annotations: map[string]string{
"nginx.org/client-body-buffer-size": "abcdef",
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()

ingress := &networking.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "test-ingress",
Namespace: "default",
Annotations: tt.annotations,
},
}

ingEx := &IngressEx{
Ingress: ingress,
}

baseCfgParams := NewDefaultConfigParams(context.Background(), false)
result := parseAnnotations(ingEx, baseCfgParams, false, false, false, false, false)

if result.ClientBodyBufferSize != "" {
t.Errorf(`Test %q: expected ClientBodyBufferSize %q, got ""`, tt.name, result.ClientBodyBufferSize)
}
})
}
}
3 changes: 3 additions & 0 deletions internal/configs/config_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type ConfigParams struct {
Context context.Context
ClientMaxBodySize string
ClientBodyBufferSize string
DefaultServerAccessLogOff bool
DefaultServerReturn string
FailTimeout string
Expand Down Expand Up @@ -52,6 +53,7 @@ type ConfigParams struct {
MainWorkerProcesses string
MainWorkerRlimitNofile string
MainWorkerShutdownTimeout string
MainClientBodyBufferSize string
MaxConns int
MaxFails int
AppProtectEnable string
Expand Down Expand Up @@ -247,6 +249,7 @@ func NewDefaultConfigParams(ctx context.Context, isPlus bool) *ConfigParams {
MainServerNamesHashMaxSize: "1024",
MainMapHashBucketSize: "256",
MainMapHashMaxSize: "2048",
MainClientBodyBufferSize: "8k",
ProxyBuffering: true,
MainWorkerProcesses: "auto",
MainWorkerConnections: "1024",
Expand Down
12 changes: 12 additions & 0 deletions internal/configs/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ func ParseConfigMap(ctx context.Context, cfgm *v1.ConfigMap, nginxPlus bool, has
cfgParams.ClientMaxBodySize = clientMaxBodySize
}

if clientBodyBufferSize, exists := cfgm.Data["client-body-buffer-size"]; exists {
if parsedClientBodyBufferSize, err := ParseSize(clientBodyBufferSize); err != nil {
wrappedError := fmt.Errorf("ConfigMap %s/%s: invalid value for 'client-body-buffer-size': %w", cfgm.GetNamespace(), cfgm.GetName(), err)
nl.Errorf(l, "%s", wrappedError.Error())
eventLog.Event(cfgm, v1.EventTypeWarning, nl.EventReasonInvalidValue, wrappedError.Error())
configOk = false
} else {
cfgParams.MainClientBodyBufferSize = parsedClientBodyBufferSize
}
}

if serverNamesHashBucketSize, exists := cfgm.Data["server-names-hash-bucket-size"]; exists {
cfgParams.MainServerNamesHashBucketSize = serverNamesHashBucketSize
}
Expand Down Expand Up @@ -1146,6 +1157,7 @@ func GenerateNginxMainConfig(staticCfgParams *StaticConfigParams, config *Config
ServerNamesHashMaxSize: config.MainServerNamesHashMaxSize,
MapHashBucketSize: config.MainMapHashBucketSize,
MapHashMaxSize: config.MainMapHashMaxSize,
ClientBodyBufferSize: config.MainClientBodyBufferSize,
ServerTokens: config.ServerTokens,
SSLCiphers: config.MainServerSSLCiphers,
SSLDHParam: config.MainServerSSLDHParam,
Expand Down
Loading
Loading