This commit is contained in:
wjqserver 2025-03-21 18:53:08 +08:00
parent 026039e0bc
commit 5501cd3e3c
7 changed files with 96 additions and 10 deletions

View file

@ -1,5 +1,10 @@
# 更新日志 # 更新日志
25w22a - 2025-03-21
---
- PRE-RELEASE: 此版本是v3.0.1的预发布版本,请勿在生产环境中使用;
- FIX: 使用等效`c.Writer()`, 回归v2.5.0 func以修正问题
3.0.1 - 2025-03-21 3.0.1 - 2025-03-21
--- ---
- RELEASE: Next Step; 下一步; 完善v3的同时, 修正已知问题; v3会与v2.4.0及以上版本保证兼容关系, 可平顺升级; - RELEASE: Next Step; 下一步; 完善v3的同时, 修正已知问题; v3会与v2.4.0及以上版本保证兼容关系, 可平顺升级;

View file

@ -1 +1 @@
25w21e 25w22a

3
go.mod
View file

@ -4,7 +4,7 @@ go 1.24.1
require ( require (
github.com/BurntSushi/toml v1.5.0 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/WJQSERVER-STUDIO/go-utils/logger v1.5.0
github.com/cloudwego/hertz v0.9.6 github.com/cloudwego/hertz v0.9.6
github.com/hertz-contrib/http2 v0.1.8 github.com/hertz-contrib/http2 v0.1.8
@ -15,7 +15,6 @@ require (
) )
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/WJQSERVER-STUDIO/go-utils/log v0.0.1 // indirect
github.com/bytedance/gopkg v0.1.1 // indirect github.com/bytedance/gopkg v0.1.1 // indirect
github.com/bytedance/sonic v1.13.1 // indirect github.com/bytedance/sonic v1.13.1 // indirect

2
go.sum
View file

@ -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/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 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/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 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/log v0.0.1/go.mod h1:j9Q+xnwpOfve7/uJnZ2izRQw6NNoXjvJHz7vUQAaLZE=
github.com/WJQSERVER-STUDIO/go-utils/logger v1.5.0 h1:Uk4N7Sh4OPth3am3xVv17JlAm7tsna97ZLQRpQj7r5c= github.com/WJQSERVER-STUDIO/go-utils/logger v1.5.0 h1:Uk4N7Sh4OPth3am3xVv17JlAm7tsna97ZLQRpQj7r5c=

View file

@ -9,7 +9,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"github.com/WJQSERVER-STUDIO/go-utils/hwriter" "github.com/WJQSERVER-STUDIO/go-utils/copyb"
"github.com/cloudwego/hertz/pkg/app" "github.com/cloudwego/hertz/pkg/app"
hresp "github.com/cloudwego/hertz/pkg/protocol/http1/resp" 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()) 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", "") 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 { 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) 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() // 确保刷入 c.Flush() // 确保刷入
} }
} else { } 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 { 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) 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 return

View file

@ -9,7 +9,7 @@ import (
"net/http" "net/http"
"strconv" "strconv"
"github.com/WJQSERVER-STUDIO/go-utils/hwriter" "github.com/WJQSERVER-STUDIO/go-utils/copyb"
"github.com/cloudwego/hertz/pkg/app" "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) 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 { 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) 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)

View file

@ -373,3 +373,83 @@ func extractParts(rawURL string) (string, string, string, url.Values, error) {
return repoOwner, repoName, remainingPath, queryParams, nil 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
}