Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 | - |
Expand Down
5 changes: 1 addition & 4 deletions common/gin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion common/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions constant/env.go
Original file line number Diff line number Diff line change
@@ -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
Expand Down
29 changes: 29 additions & 0 deletions constant/env_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
})
}
}
5 changes: 1 addition & 4 deletions middleware/gzip.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down