diff --git a/README.md b/README.md index 8f23d5dcd380..43d485fe2d74 100644 --- a/README.md +++ b/README.md @@ -314,7 +314,7 @@ docker run --name new-api -d --restart always \ | `REDIS_CONN_STRING` | Redis connection string | - | | `STREAMING_TIMEOUT` | Streaming timeout (seconds) | `300` | | `STREAM_SCANNER_MAX_BUFFER_MB` | Max per-line buffer (MB) for the stream scanner; increase when upstream sends huge image/base64 payloads | `64` | -| `MAX_REQUEST_BODY_MB` | Max request body size (MB, counted **after decompression**; prevents huge requests/zip bombs from exhausting memory). Exceeding it returns `413` | `32` | +| `MAX_REQUEST_BODY_MB` | Max request body size (MB, counted **after decompression**; prevents huge requests/zip bombs from exhausting memory). Exceeding it returns `413` | `128` | | `AZURE_DEFAULT_API_VERSION` | Azure API version | `2025-04-01-preview` | | `ERROR_LOG_ENABLED` | Error log switch | `false` | | `PYROSCOPE_URL` | Pyroscope server address | - | diff --git a/common/gin.go b/common/gin.go index 5cad6e5c9512..b65572244d34 100644 --- a/common/gin.go +++ b/common/gin.go @@ -57,10 +57,7 @@ func GetRequestBody(c *gin.Context) (io.Seeker, error) { } } - maxMB := constant.MaxRequestBodyMB - if maxMB <= 0 { - maxMB = 128 // 默认 128MB - } + maxMB := constant.EffectiveMaxRequestBodyMB() maxBytes := int64(maxMB) << 20 contentLength := c.Request.ContentLength diff --git a/common/init.go b/common/init.go index 4ac7d2384f07..fc8cd2e35438 100644 --- a/common/init.go +++ b/common/init.go @@ -133,7 +133,7 @@ func initConstantEnv() { constant.MaxFileDownloadMB = GetEnvOrDefault("MAX_FILE_DOWNLOAD_MB", 64) constant.StreamScannerMaxBufferMB = GetEnvOrDefault("STREAM_SCANNER_MAX_BUFFER_MB", 64) // MaxRequestBodyMB 请求体最大大小(解压后),用于防止超大请求/zip bomb导致内存暴涨 - constant.MaxRequestBodyMB = GetEnvOrDefault("MAX_REQUEST_BODY_MB", 128) + constant.MaxRequestBodyMB = GetEnvOrDefault("MAX_REQUEST_BODY_MB", constant.DefaultMaxRequestBodyMB) // ForceStreamOption 覆盖请求参数,强制返回usage信息 constant.ForceStreamOption = GetEnvOrDefaultBool("FORCE_STREAM_OPTION", true) constant.CountToken = GetEnvOrDefaultBool("CountToken", true) diff --git a/constant/env.go b/constant/env.go index d5aff1b0b173..b919d6ee34fb 100644 --- a/constant/env.go +++ b/constant/env.go @@ -1,5 +1,14 @@ package constant +const DefaultMaxRequestBodyMB = 128 + +func EffectiveMaxRequestBodyMB() int { + if MaxRequestBodyMB <= 0 { + return DefaultMaxRequestBodyMB + } + return MaxRequestBodyMB +} + var StreamingTimeout int var DifyDebug bool var MaxFileDownloadMB int diff --git a/constant/env_test.go b/constant/env_test.go new file mode 100644 index 000000000000..7dee0b00ecbd --- /dev/null +++ b/constant/env_test.go @@ -0,0 +1,29 @@ +package constant + +import "testing" + +func TestEffectiveMaxRequestBodyMB(t *testing.T) { + original := MaxRequestBodyMB + t.Cleanup(func() { + MaxRequestBodyMB = original + }) + + tests := []struct { + name string + value int + want int + }{ + {name: "positive value", value: 64, want: 64}, + {name: "zero falls back to default", value: 0, want: DefaultMaxRequestBodyMB}, + {name: "negative falls back to default", value: -1, want: DefaultMaxRequestBodyMB}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + MaxRequestBodyMB = tt.value + if got := EffectiveMaxRequestBodyMB(); got != tt.want { + t.Fatalf("EffectiveMaxRequestBodyMB() = %d, want %d", got, tt.want) + } + }) + } +} diff --git a/middleware/gzip.go b/middleware/gzip.go index 5e5682532f7a..dad4a75a7769 100644 --- a/middleware/gzip.go +++ b/middleware/gzip.go @@ -28,10 +28,7 @@ func DecompressRequestMiddleware() gin.HandlerFunc { c.Next() return } - maxMB := constant.MaxRequestBodyMB - if maxMB <= 0 { - maxMB = 32 - } + maxMB := constant.EffectiveMaxRequestBodyMB() maxBytes := int64(maxMB) << 20 origBody := c.Request.Body