diff --git a/CHANGELOG.md b/CHANGELOG.md index 719ff85..08a9c5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,5 @@ # 更新日志 -4.1.4 - 2025-06-30 ---- -- CHANGE: 使用`touka`框架的内建httpc统一管理, 同时对httpc相关初始化进行改进 -- CHANGE: 更新`json/v2`版本 - -4.1.4-rc.0 - 2025-06-30 ---- -- PRE-RELEASE: v4.1.4-rc.0是v4.1.4预发布版本,请勿在生产环境中使用; -- CHANGE: 使用`touka`框架的内建httpc统一管理, 同时对httpc相关初始化进行改进 -- CHANGE: 更新`json/v2`版本 - 4.1.3 - 2025-06-25 --- - CHANGE: 更新`touka`版本, 使用新的方式配置slash重定向功能 diff --git a/DEV-VERSION b/DEV-VERSION index 4e32678..2be11c0 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -4.1.4-rc.0 \ No newline at end of file +4.1.3-rc.0 \ No newline at end of file diff --git a/VERSION b/VERSION index 9d086c6..8c7fafd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.4 \ No newline at end of file +4.1.3 \ No newline at end of file diff --git a/go.mod b/go.mod index d28869e..4019854 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,6 @@ require ( require ( github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 // indirect - github.com/go-json-experiment/json v0.0.0-20250626171732-1a886bd29d1b // indirect + github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 9986b6b..261f233 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/fenthope/reco v0.0.3 h1:RmnQ0D9a8PWtwOODawitTe4BztTnS9wYwrDbipISNq4= github.com/fenthope/reco v0.0.3/go.mod h1:mDkGLHte5udWTIcjQTxrABRcf56SSdxBOCLgrRDwI/Y= github.com/fenthope/record v0.0.3 h1:v5urgs5LAkLMlljAT/MjW8fWuRHXPnAraTem5ui7rm4= github.com/fenthope/record v0.0.3/go.mod h1:KFEkSc4TDZ3QIhP/wglD32uYVA6X1OUcripiao1DEE4= -github.com/go-json-experiment/json v0.0.0-20250626171732-1a886bd29d1b h1:ooF9/NzXkXL3OOLRwtPuQT/D7Kx2S5w/Kl1GnMF9h2s= -github.com/go-json-experiment/json v0.0.0-20250626171732-1a886bd29d1b/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 h1:o8UqXPI6SVwQt04RGsqKp3qqmbOfTNMqDrWsc4O47kk= +github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/infinite-iroha/touka v0.2.8 h1:PH4oR0fUjNr6t+Q3xkpqK+Q+kOFk7LN3xvy81xydu7Y= diff --git a/main.go b/main.go index 4fa4019..5910078 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,6 @@ import ( "ghproxy/config" "ghproxy/proxy" - "github.com/WJQSERVER-STUDIO/httpc" "github.com/fenthope/bauth" "ghproxy/weakcache" @@ -34,7 +33,7 @@ var ( cfg *config.Config r *touka.Engine configfile = "/data/ghproxy/config/config.toml" - httpClient *httpc.Client + hertZfile *os.File cfgfile string version string runMode string @@ -166,8 +165,7 @@ func setupApi(cfg *config.Config, r *touka.Engine, version string) { } func InitReq(cfg *config.Config) { - var err error - httpClient, err = proxy.InitReq(cfg) + err := proxy.InitReq(cfg) if err != nil { fmt.Printf("Failed to initialize request: %v\n", err) os.Exit(1) @@ -337,7 +335,6 @@ func main() { r.Use(touka.Recovery()) // Recovery中间件 r.SetLogger(logger) - r.SetHTTPClient(httpClient) r.Use(record.Middleware()) // log中间件 r.Use(viaHeader()) /* diff --git a/proxy/docker.go b/proxy/docker.go index cdcff70..44e4a72 100644 --- a/proxy/docker.go +++ b/proxy/docker.go @@ -119,7 +119,6 @@ func GhcrRequest(ctx context.Context, c *touka.Context, u string, image *imageIn }() method = c.Request.Method - ghcrclient := c.GetHTTPC() rb := ghcrclient.NewRequestBuilder(method, u) rb.NoDefaultHeaders() @@ -268,7 +267,6 @@ func ChallengeReq(target string, image *imageInfo, ctx context.Context, c *touka var resp401 *http.Response var req401 *http.Request var err error - ghcrclient := c.GetHTTPC() rb401 := ghcrclient.NewRequestBuilder("GET", "https://"+target+"/v2/") rb401.NoDefaultHeaders() diff --git a/proxy/gitreq.go b/proxy/gitreq.go index f007290..e4f0d95 100644 --- a/proxy/gitreq.go +++ b/proxy/gitreq.go @@ -17,12 +17,23 @@ func GitReq(ctx context.Context, c *touka.Context, u string, cfg *config.Config, resp *http.Response ) + /* + fullBody, err := c.GetReqBodyFull() + if err != nil { + HandleError(c, fmt.Sprintf("Failed to read request body: %v", err)) + return + } + reqBodyReader := bytes.NewBuffer(fullBody) + */ + reqBodyReader, err := c.GetReqBodyBuffer() if err != nil { HandleError(c, fmt.Sprintf("Failed to read request body: %v", err)) return } + //bodyReader := c.Request.BodyStream() // 不可替换为此实现 + if cfg.GitClone.Mode == "cache" { userPath, repoPath, remainingPath, queryParams, err := extractParts(u) if err != nil { @@ -92,6 +103,14 @@ func GitReq(ctx context.Context, c *touka.Context, u string, cfg *config.Config, } } + /* + for key, values := range resp.Header { + for _, value := range values { + c.Response.Header.Add(key, value) + } + } + */ + //copyHeader( resp.Header) c.SetHeaders(resp.Header) headersToRemove := map[string]struct{}{ @@ -124,6 +143,10 @@ func GitReq(ctx context.Context, c *touka.Context, u string, cfg *config.Config, bodyReader := resp.Body + // 读取body内容 + //bodyContent, _ := io.ReadAll(bodyReader) + // c.Infof("%s", bodyContent) + if cfg.RateLimit.BandwidthLimit.Enabled { bodyReader = limitreader.NewRateLimitedReader(bodyReader, bandwidthLimit, int(bandwidthBurst), ctx) } diff --git a/proxy/handler.go b/proxy/handler.go index b15f1b5..48d8c25 100644 --- a/proxy/handler.go +++ b/proxy/handler.go @@ -15,6 +15,10 @@ func NoRouteHandler(cfg *config.Config) touka.HandlerFunc { return func(c *touka.Context) { var ctx = c.Request.Context() var shoudBreak bool + // shoudBreak = rateCheck(cfg, c, limiter, iplimiter) + // if shoudBreak { + // return + // } var ( rawPath string diff --git a/proxy/httpc.go b/proxy/httpc.go index 857f3f0..1cd9100 100644 --- a/proxy/httpc.go +++ b/proxy/httpc.go @@ -1,6 +1,7 @@ package proxy import ( + "fmt" "ghproxy/config" "net/http" "time" @@ -11,40 +12,42 @@ import ( var BufferSize int = 32 * 1024 // 32KB var ( - tr *http.Transport - gittr *http.Transport - client *httpc.Client - gitclient *httpc.Client + tr *http.Transport + gittr *http.Transport + client *httpc.Client + gitclient *httpc.Client + ghcrtr *http.Transport + ghcrclient *httpc.Client ) -func InitReq(cfg *config.Config) (*httpc.Client, error) { - client := initHTTPClient(cfg) +func InitReq(cfg *config.Config) error { + initHTTPClient(cfg) if cfg.GitClone.Mode == "cache" { initGitHTTPClient(cfg) } + initGhcrHTTPClient(cfg) err := SetGlobalRateLimit(cfg) if err != nil { - return nil, err + return err } - return client, nil + return nil } -func initHTTPClient(cfg *config.Config) *httpc.Client { +func initHTTPClient(cfg *config.Config) { var proTolcols = new(http.Protocols) proTolcols.SetHTTP1(true) proTolcols.SetHTTP2(true) proTolcols.SetUnencryptedHTTP2(true) + if cfg.Httpc.Mode == "auto" || cfg.Httpc.Mode == "" { - switch cfg.Httpc.Mode { - case "auto", "": tr = &http.Transport{ IdleConnTimeout: 30 * time.Second, WriteBufferSize: 32 * 1024, // 32KB ReadBufferSize: 32 * 1024, // 32KB Protocols: proTolcols, } - case "advanced": + } else if cfg.Httpc.Mode == "advanced" { tr = &http.Transport{ MaxIdleConns: cfg.Httpc.MaxIdleConns, MaxConnsPerHost: cfg.Httpc.MaxConnsPerHost, @@ -53,10 +56,9 @@ func initHTTPClient(cfg *config.Config) *httpc.Client { ReadBufferSize: 32 * 1024, // 32KB Protocols: proTolcols, } - default: + } else { panic("unknown httpc mode: " + cfg.Httpc.Mode) } - if cfg.Outbound.Enabled { initTransport(cfg, tr) } @@ -70,18 +72,18 @@ func initHTTPClient(cfg *config.Config) *httpc.Client { httpc.WithTransport(tr), ) } - return client + } func initGitHTTPClient(cfg *config.Config) { - switch cfg.Httpc.Mode { - case "auto", "": + + if cfg.Httpc.Mode == "auto" || cfg.Httpc.Mode == "" { gittr = &http.Transport{ IdleConnTimeout: 30 * time.Second, WriteBufferSize: 32 * 1024, // 32KB ReadBufferSize: 32 * 1024, // 32KB } - case "advanced": + } else if cfg.Httpc.Mode == "advanced" { gittr = &http.Transport{ MaxIdleConns: cfg.Httpc.MaxIdleConns, MaxConnsPerHost: cfg.Httpc.MaxConnsPerHost, @@ -89,30 +91,84 @@ func initGitHTTPClient(cfg *config.Config) { WriteBufferSize: 32 * 1024, // 32KB ReadBufferSize: 32 * 1024, // 32KB } - default: + } else { panic("unknown httpc mode: " + cfg.Httpc.Mode) } - if cfg.Outbound.Enabled { initTransport(cfg, gittr) } - - var opts []httpc.Option // 使用切片来收集选项 - opts = append(opts, httpc.WithTransport(gittr)) - var protocolsConfig httpc.ProtocolsConfig - - if cfg.GitClone.ForceH2C { - protocolsConfig.ForceH2C = true + if cfg.Server.Debug && cfg.GitClone.ForceH2C { + gitclient = httpc.New( + httpc.WithTransport(gittr), + httpc.WithDumpLog(), + httpc.WithProtocols(httpc.ProtocolsConfig{ + ForceH2C: true, + }), + ) + } else if !cfg.Server.Debug && cfg.GitClone.ForceH2C { + gitclient = httpc.New( + httpc.WithTransport(gittr), + httpc.WithProtocols(httpc.ProtocolsConfig{ + ForceH2C: true, + }), + ) + } else if cfg.Server.Debug && !cfg.GitClone.ForceH2C { + gitclient = httpc.New( + httpc.WithTransport(gittr), + httpc.WithDumpLog(), + httpc.WithProtocols(httpc.ProtocolsConfig{ + Http1: true, + Http2: true, + Http2_Cleartext: true, + }), + ) } else { - protocolsConfig.Http1 = true - protocolsConfig.Http2 = true - protocolsConfig.Http2_Cleartext = true + gitclient = httpc.New( + httpc.WithTransport(gittr), + httpc.WithProtocols(httpc.ProtocolsConfig{ + Http1: true, + Http2: true, + Http2_Cleartext: true, + }), + ) + } +} + +func initGhcrHTTPClient(cfg *config.Config) { + var proTolcols = new(http.Protocols) + proTolcols.SetHTTP1(true) + proTolcols.SetHTTP2(true) + if cfg.Httpc.Mode == "auto" || cfg.Httpc.Mode == "" { + + ghcrtr = &http.Transport{ + IdleConnTimeout: 30 * time.Second, + WriteBufferSize: 32 * 1024, // 32KB + ReadBufferSize: 32 * 1024, // 32KB + Protocols: proTolcols, + } + } else if cfg.Httpc.Mode == "advanced" { + ghcrtr = &http.Transport{ + MaxIdleConns: cfg.Httpc.MaxIdleConns, + MaxConnsPerHost: cfg.Httpc.MaxConnsPerHost, + MaxIdleConnsPerHost: cfg.Httpc.MaxIdleConnsPerHost, + WriteBufferSize: 32 * 1024, // 32KB + ReadBufferSize: 32 * 1024, // 32KB + Protocols: proTolcols, + } + } else { + panic(fmt.Sprintf("unknown httpc mode: %s", cfg.Httpc.Mode)) + } + if cfg.Outbound.Enabled { + initTransport(cfg, ghcrtr) + } + if cfg.Server.Debug { + ghcrclient = httpc.New( + httpc.WithTransport(ghcrtr), + httpc.WithDumpLog(), + ) + } else { + ghcrclient = httpc.New( + httpc.WithTransport(ghcrtr), + ) } - opts = append(opts, httpc.WithProtocols(protocolsConfig)) - - if cfg.Server.Debug { - opts = append(opts, httpc.WithDumpLog()) - } - - gitclient = httpc.New(opts...) } diff --git a/proxy/routing.go b/proxy/routing.go index 7a5748f..6c68b9c 100644 --- a/proxy/routing.go +++ b/proxy/routing.go @@ -12,6 +12,11 @@ func RoutingHandler(cfg *config.Config) touka.HandlerFunc { var shoudBreak bool + // shoudBreak = rateCheck(cfg, c, limiter, iplimiter) + // if shoudBreak { + // return + //} + var ( rawPath string )