diff --git a/README.md b/README.md index d1bdf2d..61d62e0 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ host = "0.0.0.0" port = 5000 # Github文件大小限制(字节),默认2GB fileSize = 2147483648 +# HTTP/2 多路复用 +enableH2C = false [rateLimit] # 每个IP每小时允许的请求数(注意Docker镜像会有多个层,会消耗多个次数) diff --git a/src/config.toml b/src/config.toml index af993d8..f7d4c08 100644 --- a/src/config.toml +++ b/src/config.toml @@ -4,6 +4,8 @@ host = "0.0.0.0" port = 5000 # Github文件大小限制(字节),默认2GB fileSize = 2147483648 +# HTTP/2 多路复用 +enableH2C = false [rateLimit] # 每个IP每小时允许的请求数(注意Docker镜像会有多个层,会消耗多个次数) diff --git a/src/config/config.go b/src/config/config.go index d063648..1973d3a 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -22,9 +22,10 @@ type RegistryMapping struct { // AppConfig 应用配置结构体 type AppConfig struct { Server struct { - Host string `toml:"host"` - Port int `toml:"port"` - FileSize int64 `toml:"fileSize"` + Host string `toml:"host"` + Port int `toml:"port"` + FileSize int64 `toml:"fileSize"` + EnableH2C bool `toml:"enableH2C"` } `toml:"server"` RateLimit struct { @@ -69,13 +70,15 @@ var ( func DefaultConfig() *AppConfig { return &AppConfig{ Server: struct { - Host string `toml:"host"` - Port int `toml:"port"` - FileSize int64 `toml:"fileSize"` + Host string `toml:"host"` + Port int `toml:"port"` + FileSize int64 `toml:"fileSize"` + EnableH2C bool `toml:"enableH2C"` }{ - Host: "0.0.0.0", - Port: 5000, - FileSize: 2 * 1024 * 1024 * 1024, // 2GB + Host: "0.0.0.0", + Port: 5000, + FileSize: 2 * 1024 * 1024 * 1024, // 2GB + EnableH2C: false, // 默认关闭H2C }, RateLimit: struct { RequestLimit int `toml:"requestLimit"` @@ -219,6 +222,11 @@ func overrideFromEnv(cfg *AppConfig) { cfg.Server.Port = port } } + if val := os.Getenv("ENABLE_H2C"); val != "" { + if enable, err := strconv.ParseBool(val); err == nil { + cfg.Server.EnableH2C = enable + } + } if val := os.Getenv("MAX_FILE_SIZE"); val != "" { if size, err := strconv.ParseInt(val, 10, 64); err == nil && size > 0 { cfg.Server.FileSize = size diff --git a/src/go.mod b/src/go.mod index 7c2806d..0eca90c 100644 --- a/src/go.mod +++ b/src/go.mod @@ -6,6 +6,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/google/go-containerregistry v0.20.5 github.com/pelletier/go-toml/v2 v2.2.3 + golang.org/x/net v0.33.0 golang.org/x/time v0.11.0 ) diff --git a/src/main.go b/src/main.go index 1b30bde..ff0d8bf 100644 --- a/src/main.go +++ b/src/main.go @@ -9,6 +9,8 @@ import ( "time" "github.com/gin-gonic/gin" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" "hubproxy/config" "hubproxy/handlers" "hubproxy/utils" @@ -117,9 +119,37 @@ func main() { fmt.Printf("🚀 HubProxy 启动成功\n") fmt.Printf("📡 监听地址: %s:%d\n", cfg.Server.Host, cfg.Server.Port) fmt.Printf("⚡ 限流配置: %d请求/%g小时\n", cfg.RateLimit.RequestLimit, cfg.RateLimit.PeriodHours) + + // 显示HTTP/2支持状态 + if cfg.Server.EnableH2C { + fmt.Printf("H2c: 已启用\n") + } + fmt.Printf("🔗 项目地址: https://github.com/sky22333/hubproxy\n") - err := router.Run(fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)) + // 创建HTTP2服务器 + server := &http.Server{ + Addr: fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port), + ReadTimeout: 60 * time.Second, + WriteTimeout: 300 * time.Second, + IdleTimeout: 120 * time.Second, + } + + // 根据配置决定是否启用H2C + if cfg.Server.EnableH2C { + h2cHandler := h2c.NewHandler(router, &http2.Server{ + MaxConcurrentStreams: 250, + IdleTimeout: 300 * time.Second, + MaxReadFrameSize: 4 << 20, + MaxUploadBufferPerConnection: 8 << 20, + MaxUploadBufferPerStream: 2 << 20, + }) + server.Handler = h2cHandler + } else { + server.Handler = router + } + + err := server.ListenAndServe() if err != nil { fmt.Printf("启动服务失败: %v\n", err) } @@ -173,4 +203,3 @@ func initHealthRoutes(router *gin.Engine) { }) }) } -