From 39a0359dd5a26b5e79f94b6c83610448b3003a78 Mon Sep 17 00:00:00 2001 From: Lemon Date: Thu, 5 Feb 2026 12:48:05 +0800 Subject: [PATCH] feat: enhance HTTP/2 Cleartext (h2c) configuration options --- backend/internal/config/config.go | 34 +++++++++++++++++++++++-------- backend/internal/server/http.go | 30 ++++++++++++++++++++------- config.yaml | 29 +++++++++++++++++++++++--- deploy/.env.example | 23 ++++++++++++++++++++- deploy/config.example.yaml | 29 +++++++++++++++++++++++--- 5 files changed, 123 insertions(+), 22 deletions(-) diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 0790ed06..f0eb1ceb 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -144,13 +144,24 @@ type PricingConfig struct { } type ServerConfig struct { - Host string `mapstructure:"host"` - Port int `mapstructure:"port"` - Mode string `mapstructure:"mode"` // debug/release - ReadHeaderTimeout int `mapstructure:"read_header_timeout"` // 读取请求头超时(秒) - IdleTimeout int `mapstructure:"idle_timeout"` // 空闲连接超时(秒) - TrustedProxies []string `mapstructure:"trusted_proxies"` // 可信代理列表(CIDR/IP) - EnableH2C bool `mapstructure:"enable_h2c"` // 启用 HTTP/2 Cleartext (h2c) + Host string `mapstructure:"host"` + Port int `mapstructure:"port"` + Mode string `mapstructure:"mode"` // debug/release + ReadHeaderTimeout int `mapstructure:"read_header_timeout"` // 读取请求头超时(秒) + IdleTimeout int `mapstructure:"idle_timeout"` // 空闲连接超时(秒) + TrustedProxies []string `mapstructure:"trusted_proxies"` // 可信代理列表(CIDR/IP) + MaxRequestBodySize int64 `mapstructure:"max_request_body_size"` // 全局最大请求体限制 + H2C H2CConfig `mapstructure:"h2c"` // HTTP/2 Cleartext 配置 +} + +// H2CConfig HTTP/2 Cleartext 配置 +type H2CConfig struct { + Enabled bool `mapstructure:"enabled"` // 是否启用 H2C + MaxConcurrentStreams uint32 `mapstructure:"max_concurrent_streams"` // 最大并发流数量 + IdleTimeout int `mapstructure:"idle_timeout"` // 空闲超时(秒) + MaxReadFrameSize int `mapstructure:"max_read_frame_size"` // 最大帧大小(字节) + MaxUploadBufferPerConnection int `mapstructure:"max_upload_buffer_per_connection"` // 每个连接的上传缓冲区(字节) + MaxUploadBufferPerStream int `mapstructure:"max_upload_buffer_per_stream"` // 每个流的上传缓冲区(字节) } type CORSConfig struct { @@ -688,7 +699,14 @@ func setDefaults() { viper.SetDefault("server.read_header_timeout", 30) // 30秒读取请求头 viper.SetDefault("server.idle_timeout", 120) // 120秒空闲超时 viper.SetDefault("server.trusted_proxies", []string{}) - viper.SetDefault("server.enable_h2c", false) // 默认关闭 h2c + viper.SetDefault("server.max_request_body_size", int64(100*1024*1024)) + // H2C 默认配置 + viper.SetDefault("server.h2c.enabled", false) + viper.SetDefault("server.h2c.max_concurrent_streams", uint32(50)) // 50 个并发流 + viper.SetDefault("server.h2c.idle_timeout", 75) // 75 秒 + viper.SetDefault("server.h2c.max_read_frame_size", 1<<20) // 1MB(够用) + viper.SetDefault("server.h2c.max_upload_buffer_per_connection", 2<<20) // 2MB + viper.SetDefault("server.h2c.max_upload_buffer_per_stream", 512<<10) // 512KB // CORS viper.SetDefault("cors.allowed_origins", []string{}) diff --git a/backend/internal/server/http.go b/backend/internal/server/http.go index f22445b8..d2d8ed40 100644 --- a/backend/internal/server/http.go +++ b/backend/internal/server/http.go @@ -60,16 +60,32 @@ func ProvideRouter( func ProvideHTTPServer(cfg *config.Config, router *gin.Engine) *http.Server { httpHandler := http.Handler(router) + globalMaxSize := cfg.Server.MaxRequestBodySize + if globalMaxSize <= 0 { + globalMaxSize = cfg.Gateway.MaxBodySize + } + if globalMaxSize > 0 { + httpHandler = http.MaxBytesHandler(httpHandler, globalMaxSize) + log.Printf("Global max request body size: %d bytes (%.2f MB)", globalMaxSize, float64(globalMaxSize)/(1<<20)) + } + // 根据配置决定是否启用 H2C - if cfg.Server.EnableH2C { + if cfg.Server.H2C.Enabled { + h2cConfig := cfg.Server.H2C httpHandler = h2c.NewHandler(router, &http2.Server{ - MaxConcurrentStreams: 250, // 最大并发流数量 - IdleTimeout: 300 * time.Second, - MaxReadFrameSize: 4 << 20, // 4MB - MaxUploadBufferPerConnection: 8 << 20, // 8MB - MaxUploadBufferPerStream: 2 << 20, // 2MB + MaxConcurrentStreams: h2cConfig.MaxConcurrentStreams, + IdleTimeout: time.Duration(h2cConfig.IdleTimeout) * time.Second, + MaxReadFrameSize: uint32(h2cConfig.MaxReadFrameSize), + MaxUploadBufferPerConnection: int32(h2cConfig.MaxUploadBufferPerConnection), + MaxUploadBufferPerStream: int32(h2cConfig.MaxUploadBufferPerStream), }) - log.Println("HTTP/2 Cleartext (h2c) enabled") + log.Printf("HTTP/2 Cleartext (h2c) enabled: max_concurrent_streams=%d, idle_timeout=%ds, max_read_frame_size=%d, max_upload_buffer_per_connection=%d, max_upload_buffer_per_stream=%d", + h2cConfig.MaxConcurrentStreams, + h2cConfig.IdleTimeout, + h2cConfig.MaxReadFrameSize, + h2cConfig.MaxUploadBufferPerConnection, + h2cConfig.MaxUploadBufferPerStream, + ) } return &http.Server{ diff --git a/config.yaml b/config.yaml index e79500b7..1cbd8c11 100644 --- a/config.yaml +++ b/config.yaml @@ -23,9 +23,32 @@ server: # Trusted proxies for X-Forwarded-For parsing (CIDR/IP). Empty disables trusted proxies. # 信任的代理地址(CIDR/IP 格式),用于解析 X-Forwarded-For 头。留空则禁用代理信任。 trusted_proxies: [] - # Enable HTTP/2 Cleartext (h2c) for client connections - # 启用 HTTP/2 Cleartext (h2c) 客户端连接 - enable_h2c: true + # Global max request body size in bytes (default: 100MB) + # 全局最大请求体大小(字节,默认 100MB) + # Applies to all requests, especially important for h2c first request memory protection + # 适用于所有请求,对 h2c 第一请求的内存保护尤为重要 + max_request_body_size: 104857600 + # HTTP/2 Cleartext (h2c) configuration + # HTTP/2 Cleartext (h2c) 配置 + h2c: + # Enable HTTP/2 Cleartext for client connections + # 启用 HTTP/2 Cleartext 客户端连接 + enabled: true + # Max concurrent streams per connection + # 每个连接的最大并发流数量 + max_concurrent_streams: 50 + # Idle timeout for connections (seconds) + # 连接空闲超时时间(秒) + idle_timeout: 75 + # Max frame size in bytes (default: 1MB) + # 最大帧大小(字节,默认 1MB) + max_read_frame_size: 1048576 + # Max upload buffer per connection in bytes (default: 2MB) + # 每个连接的最大上传缓冲区(字节,默认 2MB) + max_upload_buffer_per_connection: 2097152 + # Max upload buffer per stream in bytes (default: 512KB) + # 每个流的最大上传缓冲区(字节,默认 512KB) + max_upload_buffer_per_stream: 524288 # ============================================================================= # Run Mode Configuration diff --git a/deploy/.env.example b/deploy/.env.example index a0c98bec..c5e850ae 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -20,9 +20,30 @@ SERVER_PORT=8080 # Server mode: release or debug SERVER_MODE=release +# Global max request body size in bytes (default: 100MB) +# 全局最大请求体大小(字节,默认 100MB) +# Applies to all requests, especially important for h2c first request memory protection +# 适用于所有请求,对 h2c 第一请求的内存保护尤为重要 +SERVER_MAX_REQUEST_BODY_SIZE=104857600 + # Enable HTTP/2 Cleartext (h2c) for client connections # 启用 HTTP/2 Cleartext (h2c) 客户端连接 -SERVER_ENABLE_H2C=true +SERVER_H2C_ENABLED=true +# H2C max concurrent streams (default: 50) +# H2C 最大并发流数量(默认 50) +SERVER_H2C_MAX_CONCURRENT_STREAMS=50 +# H2C idle timeout in seconds (default: 75) +# H2C 空闲超时时间(秒,默认 75) +SERVER_H2C_IDLE_TIMEOUT=75 +# H2C max read frame size in bytes (default: 1048576 = 1MB) +# H2C 最大帧大小(字节,默认 1048576 = 1MB) +SERVER_H2C_MAX_READ_FRAME_SIZE=1048576 +# H2C max upload buffer per connection in bytes (default: 2097152 = 2MB) +# H2C 每个连接的最大上传缓冲区(字节,默认 2097152 = 2MB) +SERVER_H2C_MAX_UPLOAD_BUFFER_PER_CONNECTION=2097152 +# H2C max upload buffer per stream in bytes (default: 524288 = 512KB) +# H2C 每个流的最大上传缓冲区(字节,默认 524288 = 512KB) +SERVER_H2C_MAX_UPLOAD_BUFFER_PER_STREAM=524288 # 运行模式: standard (默认) 或 simple (内部自用) # standard: 完整 SaaS 功能,包含计费/余额校验;simple: 隐藏 SaaS 功能并跳过计费/余额校验 diff --git a/deploy/config.example.yaml b/deploy/config.example.yaml index 339b3d89..d9f5f2ab 100644 --- a/deploy/config.example.yaml +++ b/deploy/config.example.yaml @@ -23,9 +23,32 @@ server: # Trusted proxies for X-Forwarded-For parsing (CIDR/IP). Empty disables trusted proxies. # 信任的代理地址(CIDR/IP 格式),用于解析 X-Forwarded-For 头。留空则禁用代理信任。 trusted_proxies: [] - # Enable HTTP/2 Cleartext (h2c) for client connections - # 启用 HTTP/2 Cleartext (h2c) 客户端连接 - enable_h2c: true + # Global max request body size in bytes (default: 100MB) + # 全局最大请求体大小(字节,默认 100MB) + # Applies to all requests, especially important for h2c first request memory protection + # 适用于所有请求,对 h2c 第一请求的内存保护尤为重要 + max_request_body_size: 104857600 + # HTTP/2 Cleartext (h2c) configuration + # HTTP/2 Cleartext (h2c) 配置 + h2c: + # Enable HTTP/2 Cleartext for client connections + # 启用 HTTP/2 Cleartext 客户端连接 + enabled: true + # Max concurrent streams per connection + # 每个连接的最大并发流数量 + max_concurrent_streams: 50 + # Idle timeout for connections (seconds) + # 连接空闲超时时间(秒) + idle_timeout: 75 + # Max frame size in bytes (default: 1MB) + # 最大帧大小(字节,默认 1MB) + max_read_frame_size: 1048576 + # Max upload buffer per connection in bytes (default: 2MB) + # 每个连接的最大上传缓冲区(字节,默认 2MB) + max_upload_buffer_per_connection: 2097152 + # Max upload buffer per stream in bytes (default: 512KB) + # 每个流的最大上传缓冲区(字节,默认 512KB) + max_upload_buffer_per_stream: 524288 # ============================================================================= # Run Mode Configuration