diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b7cf74..8fe1170 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # 更新日志 +3.0.2 - 2025-03-21 +--- +- RELEASE: 在此表达对各位的歉意, v3迁移到HertZ带来了许多问题; 此版本完善v3的同时, 修正已知问题; v3会与v2.4.0及以上版本保证兼容关系, 可平顺升级; +- FIX: 使用等效`c.Writer()`, 回归v2.5.0 func以修正问题 +- CHANGE: 更新相关依赖 + +25w22a - 2025-03-21 +--- +- PRE-RELEASE: 此版本是v3.0.1的预发布版本,请勿在生产环境中使用; +- FIX: 使用等效`c.Writer()`, 回归v2.5.0 func以修正问题 + 3.0.1 - 2025-03-21 --- - RELEASE: Next Step; 下一步; 完善v3的同时, 修正已知问题; v3会与v2.4.0及以上版本保证兼容关系, 可平顺升级; diff --git a/DEV-VERSION b/DEV-VERSION index 34cebe9..62cff45 100644 --- a/DEV-VERSION +++ b/DEV-VERSION @@ -1 +1 @@ -25w21e \ No newline at end of file +25w22a \ No newline at end of file diff --git a/VERSION b/VERSION index 13d683c..d9c62ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.1 \ No newline at end of file +3.0.2 \ No newline at end of file diff --git a/go.mod b/go.mod index 8527184..8b44303 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.24.1 require ( github.com/BurntSushi/toml v1.5.0 - github.com/WJQSERVER-STUDIO/go-utils/hwriter v0.0.3 + github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 github.com/WJQSERVER-STUDIO/go-utils/logger v1.5.0 github.com/cloudwego/hertz v0.9.6 github.com/hertz-contrib/http2 v0.1.8 @@ -15,18 +15,17 @@ require ( ) require ( - github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 // indirect github.com/WJQSERVER-STUDIO/go-utils/log v0.0.1 // indirect github.com/bytedance/gopkg v0.1.1 // indirect - github.com/bytedance/sonic v1.13.1 // indirect + github.com/bytedance/sonic v1.13.2 // indirect github.com/bytedance/sonic/loader v0.2.4 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/netpoll v0.6.5 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect - github.com/nyaruka/phonenumbers v1.5.0 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/nyaruka/phonenumbers v1.6.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect diff --git a/go.sum b/go.sum index 5174ab3..6ce4816 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4 h1:JLtFd00AdFg/TP+dtvIzLkdHwKUGPOAijN1sMtEYoFg= github.com/WJQSERVER-STUDIO/go-utils/copyb v0.0.4/go.mod h1:FZ6XE+4TKy4MOfX1xWKe6Rwsg0ucYFCdNh1KLvyKTfc= -github.com/WJQSERVER-STUDIO/go-utils/hwriter v0.0.3 h1:4kZH8GauRDR2R3ywgyob2Clyh3o1o/DPZCxknzi9HUU= -github.com/WJQSERVER-STUDIO/go-utils/hwriter v0.0.3/go.mod h1:U3dVP2MzKJfK6dPiobxmSdynibqCOn1mxQEVLylESWA= github.com/WJQSERVER-STUDIO/go-utils/log v0.0.1 h1:gJEQspQPB527Vp2FPcdOrynQEj3YYtrg1ixVSB/JvZM= github.com/WJQSERVER-STUDIO/go-utils/log v0.0.1/go.mod h1:j9Q+xnwpOfve7/uJnZ2izRQw6NNoXjvJHz7vUQAaLZE= github.com/WJQSERVER-STUDIO/go-utils/logger v1.5.0 h1:Uk4N7Sh4OPth3am3xVv17JlAm7tsna97ZLQRpQj7r5c= @@ -13,8 +11,8 @@ github.com/bytedance/gopkg v0.1.1 h1:3azzgSkiaw79u24a+w9arfH8OfnQQ4MHUt9lJFREEaE github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= github.com/bytedance/mockey v1.2.12 h1:aeszOmGw8CPX8CRx1DZ/Glzb1yXvhjDh6jdFBNZjsU4= github.com/bytedance/mockey v1.2.12/go.mod h1:3ZA4MQasmqC87Tw0w7Ygdy7eHIc2xgpZ8Pona5rsYIk= -github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g= -github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= @@ -42,8 +40,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/nyaruka/phonenumbers v1.5.0 h1:0M+Gd9zl53QC4Nl5z1Yj1O/zPk2XXBUwR/vlzdXSJv4= -github.com/nyaruka/phonenumbers v1.5.0/go.mod h1:gv+CtldaFz+G3vHHnasBSirAi3O2XLqZzVWz4V1pl2E= +github.com/nyaruka/phonenumbers v1.6.0 h1:r9ax45fFg+YLUs2X4bNXm5RAxWl00hYjFgNlv32vtHk= +github.com/nyaruka/phonenumbers v1.6.0/go.mod h1:7gjs+Lchqm49adhAKB5cdcng5ZXgt6x7Jgvi0ZorUtU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/satomitouka/touka-httpc v0.3.3 h1:Th0uJ5do3oqqZgdUDtqD1SH11x8TcJmrwHMJQlEIKCg= diff --git a/proxy/chunkreq.go b/proxy/chunkreq.go index 819d5c0..fb78762 100644 --- a/proxy/chunkreq.go +++ b/proxy/chunkreq.go @@ -9,7 +9,7 @@ import ( "net/http" "strconv" - "github.com/WJQSERVER-STUDIO/go-utils/hwriter" + "github.com/WJQSERVER-STUDIO/go-utils/copyb" "github.com/cloudwego/hertz/pkg/app" hresp "github.com/cloudwego/hertz/pkg/protocol/http1/resp" ) @@ -130,7 +130,8 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c logInfo("Is Shell: %s %s %s %s %s", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Header.GetProtocol()) c.Header("Content-Length", "") - err := ProcessLinksAndWriteChunked(resp.Body, compress, string(c.Request.Host()), cfg, c) + //err := ProcessLinksAndWriteChunked(resp.Body, compress, string(c.Request.Host()), cfg, c) + _, err := processLinks(resp.Body, c.Response.BodyWriter(), compress, string(c.Request.Host()), cfg) if err != nil { logError("%s %s %s %s %s Failed to copy response body: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Header.GetProtocol(), err) @@ -139,7 +140,9 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c c.Flush() // 确保刷入 } } else { - err = hwriter.Writer(resp.Body, c) + //err = hwriter.Writer(resp.Body, c) + //writer := c.Response.BodyWriter() + _, err := copyb.Copy(c.Response.BodyWriter(), resp.Body) if err != nil { logError("%s %s %s %s %s Failed to copy response body: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Header.GetProtocol(), err) return diff --git a/proxy/gitreq.go b/proxy/gitreq.go index f1330de..0405a0f 100644 --- a/proxy/gitreq.go +++ b/proxy/gitreq.go @@ -9,7 +9,7 @@ import ( "net/http" "strconv" - "github.com/WJQSERVER-STUDIO/go-utils/hwriter" + "github.com/WJQSERVER-STUDIO/go-utils/copyb" "github.com/cloudwego/hertz/pkg/app" ) @@ -118,7 +118,8 @@ func GitReq(ctx context.Context, c *app.RequestContext, u string, cfg *config.Co } c.Status(resp.StatusCode) - err = hwriter.Writer(resp.Body, c) + //err = hwriter.Writer(resp.Body, c) + _, err = copyb.Copy(c.Response.BodyWriter(), resp.Body) if err != nil { logError("%s %s %s %s %s Failed to copy response body: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Header.GetProtocol(), err) diff --git a/proxy/match.go b/proxy/match.go index 7a6e818..5f1f40f 100644 --- a/proxy/match.go +++ b/proxy/match.go @@ -373,3 +373,83 @@ func extractParts(rawURL string) (string, string, string, url.Values, error) { return repoOwner, repoName, remainingPath, queryParams, nil } + +// processLinks 处理链接并将结果写入输出流 +func processLinks(input io.Reader, output io.Writer, compress string, host string, cfg *config.Config) (written int64, err error) { + var reader *bufio.Reader + + if compress == "gzip" { + // 解压gzip + gzipReader, err := gzip.NewReader(input) + if err != nil { + return 0, fmt.Errorf("gzip解压错误: %v", err) + } + defer gzipReader.Close() + reader = bufio.NewReader(gzipReader) + } else { + reader = bufio.NewReader(input) + } + + var writer *bufio.Writer + var gzipWriter *gzip.Writer + + // 根据是否gzip确定 writer 的创建 + if compress == "gzip" { + gzipWriter = gzip.NewWriter(output) + writer = bufio.NewWriterSize(gzipWriter, 4096) //设置缓冲区大小 + } else { + writer = bufio.NewWriterSize(output, 4096) + } + + //确保writer关闭 + defer func() { + var closeErr error // 局部变量,用于保存defer中可能发生的错误 + + if gzipWriter != nil { + if closeErr = gzipWriter.Close(); closeErr != nil { + logError("gzipWriter close failed %v", closeErr) + // 如果已经存在错误,则保留。否则,记录此错误。 + if err == nil { + err = closeErr + } + } + } + if flushErr := writer.Flush(); flushErr != nil { + logError("writer flush failed %v", flushErr) + // 如果已经存在错误,则保留。否则,记录此错误。 + if err == nil { + err = flushErr + } + } + }() + + // 使用正则表达式匹配 http 和 https 链接 + urlPattern := regexp.MustCompile(`https?://[^\s'"]+`) + for { + line, err := reader.ReadString('\n') + if err != nil { + if err == io.EOF { + break // 文件结束 + } + return written, fmt.Errorf("读取行错误: %v", err) // 传递错误 + } + + // 替换所有匹配的 URL + modifiedLine := urlPattern.ReplaceAllStringFunc(line, func(originalURL string) string { + return modifyURL(originalURL, host, cfg) + }) + + n, werr := writer.WriteString(modifiedLine) + written += int64(n) // 更新写入的字节数 + if werr != nil { + return written, fmt.Errorf("写入文件错误: %v", werr) // 传递错误 + } + } + + // 在返回之前,再刷新一次 + if fErr := writer.Flush(); fErr != nil { + return written, fErr + } + + return written, nil +}