From bf0bbe0be7d47695f2e40608ea24c339b2b538fe Mon Sep 17 00:00:00 2001 From: erio Date: Fri, 17 Apr 2026 22:07:15 +0800 Subject: [PATCH] feat(gateway): raise upstream response read limit 8MB -> 128MB (configurable) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 图片生成 API 返回的 base64 内联图响应经常超过 8MB 单次读取上限,被 ReadUpstreamResponseBody 拦截成 502 upstream_error。 单张 4K PNG base64 最坏约 67MB,多张候选图或 imageSize=4K 的 image_generation 一次请求能轻松到 30MB+。把默认上限提到 128MB 能覆盖 2-3 张 4K 图,相对 请求体上限 256MB 仍有缓冲;同时抽出 config.DefaultUpstreamResponseReadMaxBytes 共享常量,viper 默认值和 service 层兜底共用,消除两处同步魔法数字。 仍可通过 gateway.upstream_response_read_max_bytes 配置项覆盖。 --- backend/internal/config/config.go | 7 ++++++- backend/internal/service/upstream_response_limit.go | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index dd9a4e58..15592905 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -52,6 +52,11 @@ const ( ConnectionPoolIsolationAccountProxy = "account_proxy" ) +// DefaultUpstreamResponseReadMaxBytes 上游非流式响应体的默认读取上限。 +// 128 MB 可容纳 2-3 张 4K PNG(base64 膨胀 33%,单张 4K PNG 最坏约 67MB base64)。 +// 可通过 gateway.upstream_response_read_max_bytes 配置项覆盖。 +const DefaultUpstreamResponseReadMaxBytes int64 = 128 * 1024 * 1024 + type Config struct { Server ServerConfig `mapstructure:"server"` Log LogConfig `mapstructure:"log"` @@ -1407,7 +1412,7 @@ func setDefaults() { viper.SetDefault("gateway.antigravity_fallback_cooldown_minutes", 1) viper.SetDefault("gateway.antigravity_extra_retries", 10) viper.SetDefault("gateway.max_body_size", int64(256*1024*1024)) - viper.SetDefault("gateway.upstream_response_read_max_bytes", int64(8*1024*1024)) + viper.SetDefault("gateway.upstream_response_read_max_bytes", DefaultUpstreamResponseReadMaxBytes) viper.SetDefault("gateway.proxy_probe_response_read_max_bytes", int64(1024*1024)) viper.SetDefault("gateway.gemini_debug_response_headers", false) viper.SetDefault("gateway.connection_pool_isolation", ConnectionPoolIsolationAccountProxy) diff --git a/backend/internal/service/upstream_response_limit.go b/backend/internal/service/upstream_response_limit.go index a0444d52..ddf0e818 100644 --- a/backend/internal/service/upstream_response_limit.go +++ b/backend/internal/service/upstream_response_limit.go @@ -12,7 +12,9 @@ import ( var ErrUpstreamResponseBodyTooLarge = errors.New("upstream response body too large") -const defaultUpstreamResponseReadMaxBytes int64 = 8 * 1024 * 1024 +// defaultUpstreamResponseReadMaxBytes 源自 config.DefaultUpstreamResponseReadMaxBytes, +// 仅在 cfg 为 nil 时作为兜底(测试或极端场景)。 +const defaultUpstreamResponseReadMaxBytes = config.DefaultUpstreamResponseReadMaxBytes func resolveUpstreamResponseReadLimit(cfg *config.Config) int64 { if cfg != nil && cfg.Gateway.UpstreamResponseReadMaxBytes > 0 {