mirror of
https://github.com/WJQSERVER-STUDIO/ghproxy.git
synced 2026-02-03 00:01:10 +08:00
commit
542fffb289
12 changed files with 76 additions and 25 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
|
@ -1,5 +1,26 @@
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
3.5.6 - 2025-06-15
|
||||||
|
---
|
||||||
|
- FIX: 修正blob重写的生成问题
|
||||||
|
- CHANGE: 改进302重定向逻辑
|
||||||
|
|
||||||
|
25w48c - 2025-06-15
|
||||||
|
---
|
||||||
|
- PRE-RELEASE: 此版本是v3.5.6预发布版本,请勿在生产环境中使用;
|
||||||
|
- CHANGE: 加入内部301处理
|
||||||
|
|
||||||
|
25w48b - 2025-06-15
|
||||||
|
---
|
||||||
|
- PRE-RELEASE: 此版本是v3.5.6预发布版本,请勿在生产环境中使用;
|
||||||
|
- FIX: 修正blob重写的生成问题
|
||||||
|
- CHANGE: 验证与连接释放相关的修正
|
||||||
|
|
||||||
|
25w48a - 2025-06-14
|
||||||
|
---
|
||||||
|
- PRE-RELEASE: 此版本是v3.5.6预发布版本,请勿在生产环境中使用;
|
||||||
|
- CHANGE: 测试302重定向逻辑
|
||||||
|
|
||||||
3.5.5 - 2025-06-14
|
3.5.5 - 2025-06-14
|
||||||
---
|
---
|
||||||
- CHANGE: 修正新匹配器的覆盖问题, 同时增加test的覆盖
|
- CHANGE: 修正新匹配器的覆盖问题, 同时增加test的覆盖
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
25w47a
|
25w48c
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
3.5.5
|
3.5.6
|
||||||
|
|
@ -26,6 +26,7 @@ type Config struct {
|
||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
port = 8080
|
port = 8080
|
||||||
netlib = "netpoll" # "netpoll" / "std" "standard" "net/http" "net"
|
netlib = "netpoll" # "netpoll" / "std" "standard" "net/http" "net"
|
||||||
|
goPoolSize = 1024
|
||||||
sizeLimit = 125 # MB
|
sizeLimit = 125 # MB
|
||||||
memLimit = 0 # MB
|
memLimit = 0 # MB
|
||||||
H2C = true
|
H2C = true
|
||||||
|
|
@ -38,6 +39,7 @@ type ServerConfig struct {
|
||||||
Host string `toml:"host"`
|
Host string `toml:"host"`
|
||||||
NetLib string `toml:"netlib"`
|
NetLib string `toml:"netlib"`
|
||||||
SenseClientDisconnection bool `toml:"senseClientDisconnection"`
|
SenseClientDisconnection bool `toml:"senseClientDisconnection"`
|
||||||
|
GoPoolSize int `toml:"goPoolSize"`
|
||||||
SizeLimit int `toml:"sizeLimit"`
|
SizeLimit int `toml:"sizeLimit"`
|
||||||
MemLimit int64 `toml:"memLimit"`
|
MemLimit int64 `toml:"memLimit"`
|
||||||
H2C bool `toml:"H2C"`
|
H2C bool `toml:"H2C"`
|
||||||
|
|
@ -227,6 +229,7 @@ func DefaultConfig() *Config {
|
||||||
Port: 8080,
|
Port: 8080,
|
||||||
Host: "0.0.0.0",
|
Host: "0.0.0.0",
|
||||||
NetLib: "netpoll",
|
NetLib: "netpoll",
|
||||||
|
GoPoolSize: 1024,
|
||||||
SizeLimit: 125,
|
SizeLimit: 125,
|
||||||
MemLimit: 0,
|
MemLimit: 0,
|
||||||
H2C: true,
|
H2C: true,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ host = "0.0.0.0"
|
||||||
port = 8080
|
port = 8080
|
||||||
netlib = "netpoll" # "netpoll" / "std" "standard" "net/http" "net"
|
netlib = "netpoll" # "netpoll" / "std" "standard" "net/http" "net"
|
||||||
senseClientDisconnection = false
|
senseClientDisconnection = false
|
||||||
|
goPoolSize = 1024
|
||||||
sizeLimit = 125 # MB
|
sizeLimit = 125 # MB
|
||||||
memLimit = 0 # MB
|
memLimit = 0 # MB
|
||||||
H2C = true
|
H2C = true
|
||||||
|
|
|
||||||
5
go.mod
5
go.mod
|
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/BurntSushi/toml v1.5.0
|
github.com/BurntSushi/toml v1.5.0
|
||||||
github.com/WJQSERVER-STUDIO/httpc v0.7.0
|
github.com/WJQSERVER-STUDIO/httpc v0.7.0
|
||||||
github.com/WJQSERVER-STUDIO/logger v1.8.0
|
github.com/WJQSERVER-STUDIO/logger v1.8.0
|
||||||
github.com/cloudwego/hertz v0.10.0
|
github.com/cloudwego/hertz v0.10.1-0.20250611091639-3dde619f5598
|
||||||
github.com/hertz-contrib/http2 v0.1.8
|
github.com/hertz-contrib/http2 v0.1.8
|
||||||
golang.org/x/net v0.41.0
|
golang.org/x/net v0.41.0
|
||||||
golang.org/x/time v0.12.0
|
golang.org/x/time v0.12.0
|
||||||
|
|
@ -44,6 +44,3 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/nyaruka/phonenumbers => github.com/nyaruka/phonenumbers v1.6.1 // 1.6.3 has reflect leaking
|
replace github.com/nyaruka/phonenumbers => github.com/nyaruka/phonenumbers v1.6.1 // 1.6.3 has reflect leaking
|
||||||
|
|
||||||
//replace github.com/WJQSERVER-STUDIO/httpc v0.5.1 => /data/github/WJQSERVER-STUDIO/httpc
|
|
||||||
//replace github.com/WJQSERVER-STUDIO/logger v1.6.0 => /data/github/WJQSERVER-STUDIO/logger
|
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -24,8 +24,8 @@ github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCy
|
||||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/gopkg v0.1.4 h1:EoQiCG4sTonTPHxOGE0VlQs+sQR+Hsi2uN0qqwu8O50=
|
github.com/cloudwego/gopkg v0.1.4 h1:EoQiCG4sTonTPHxOGE0VlQs+sQR+Hsi2uN0qqwu8O50=
|
||||||
github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
|
github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
|
||||||
github.com/cloudwego/hertz v0.10.0 h1:V0vmBaLdQPlgL6w2TA6PZL1g6SGgQznFx6vqxWdCcKw=
|
github.com/cloudwego/hertz v0.10.1-0.20250611091639-3dde619f5598 h1:8tVol3hNJS7+7f7yQIkP57tZMzUV3fOhn6pQ7t4R06k=
|
||||||
github.com/cloudwego/hertz v0.10.0/go.mod h1:lRBohmcDkGx5TLK6QKFGdzJ6n3IXqGueHsOiXcYgXA4=
|
github.com/cloudwego/hertz v0.10.1-0.20250611091639-3dde619f5598/go.mod h1:lRBohmcDkGx5TLK6QKFGdzJ6n3IXqGueHsOiXcYgXA4=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
github.com/cloudwego/netpoll v0.7.0 h1:bDrxQaNfijRI1zyGgXHQoE/nYegL0nr+ijO1Norelc4=
|
github.com/cloudwego/netpoll v0.7.0 h1:bDrxQaNfijRI1zyGgXHQoE/nYegL0nr+ijO1Norelc4=
|
||||||
github.com/cloudwego/netpoll v0.7.0/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU=
|
github.com/cloudwego/netpoll v0.7.0/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU=
|
||||||
|
|
|
||||||
12
main.go
12
main.go
|
|
@ -431,6 +431,7 @@ func main() {
|
||||||
server.WithHostPorts(addr),
|
server.WithHostPorts(addr),
|
||||||
server.WithTransport(standard.NewTransporter),
|
server.WithTransport(standard.NewTransporter),
|
||||||
server.WithStreamBody(true),
|
server.WithStreamBody(true),
|
||||||
|
server.WithIdleTimeout(30*time.Second),
|
||||||
)
|
)
|
||||||
r.AddProtocol("h2", factory.NewServerFactory())
|
r.AddProtocol("h2", factory.NewServerFactory())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -438,6 +439,7 @@ func main() {
|
||||||
server.WithHostPorts(addr),
|
server.WithHostPorts(addr),
|
||||||
server.WithTransport(standard.NewTransporter),
|
server.WithTransport(standard.NewTransporter),
|
||||||
server.WithStreamBody(true),
|
server.WithStreamBody(true),
|
||||||
|
server.WithIdleTimeout(30*time.Second),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if cfg.Server.NetLib == "netpoll" || cfg.Server.NetLib == "" {
|
} else if cfg.Server.NetLib == "netpoll" || cfg.Server.NetLib == "" {
|
||||||
|
|
@ -447,6 +449,7 @@ func main() {
|
||||||
server.WithHostPorts(addr),
|
server.WithHostPorts(addr),
|
||||||
server.WithSenseClientDisconnection(cfg.Server.SenseClientDisconnection),
|
server.WithSenseClientDisconnection(cfg.Server.SenseClientDisconnection),
|
||||||
server.WithStreamBody(true),
|
server.WithStreamBody(true),
|
||||||
|
server.WithIdleTimeout(30*time.Second),
|
||||||
)
|
)
|
||||||
r.AddProtocol("h2", factory.NewServerFactory())
|
r.AddProtocol("h2", factory.NewServerFactory())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -454,6 +457,7 @@ func main() {
|
||||||
server.WithHostPorts(addr),
|
server.WithHostPorts(addr),
|
||||||
server.WithSenseClientDisconnection(cfg.Server.SenseClientDisconnection),
|
server.WithSenseClientDisconnection(cfg.Server.SenseClientDisconnection),
|
||||||
server.WithStreamBody(true),
|
server.WithStreamBody(true),
|
||||||
|
server.WithIdleTimeout(30*time.Second),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -462,6 +466,14 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if cfg.Server.GoPoolSize > 0 {
|
||||||
|
gopool.SetCap(int32(cfg.Server.GoPoolSize))
|
||||||
|
} else {
|
||||||
|
gopool.SetCap(1024)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
r.Use(recovery.Recovery()) // Recovery中间件
|
r.Use(recovery.Recovery()) // Recovery中间件
|
||||||
r.Use(loggin.Middleware()) // log中间件
|
r.Use(loggin.Middleware()) // log中间件
|
||||||
r.Use(viaHeader())
|
r.Use(viaHeader())
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c
|
||||||
logError("Failed to close response body: %v", err)
|
logError("Failed to close response body: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.Abort()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rb := client.NewRequestBuilder(string(c.Request.Method()), u)
|
rb := client.NewRequestBuilder(string(c.Request.Method()), u)
|
||||||
|
|
@ -58,7 +59,7 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理302情况
|
// 处理302情况
|
||||||
if resp.StatusCode == 302 {
|
if resp.StatusCode == 302 || resp.StatusCode == 301 {
|
||||||
finalURL := resp.Header.Get("Location")
|
finalURL := resp.Header.Get("Location")
|
||||||
if finalURL != "" {
|
if finalURL != "" {
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
|
@ -68,6 +69,7 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c
|
||||||
c.Request.Header.Del("Referer")
|
c.Request.Header.Del("Referer")
|
||||||
logInfo("Internal Redirecting to %s", finalURL)
|
logInfo("Internal Redirecting to %s", finalURL)
|
||||||
ChunkedProxyRequest(ctx, c, finalURL, cfg, matcher)
|
ChunkedProxyRequest(ctx, c, finalURL, cfg, matcher)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,6 +153,7 @@ func ChunkedProxyRequest(ctx context.Context, c *app.RequestContext, u string, c
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.SetBodyStream(bodyReader, -1)
|
c.SetBodyStream(bodyReader, -1)
|
||||||
|
bodyReader.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -144,4 +144,5 @@ func GitReq(ctx context.Context, c *app.RequestContext, u string, cfg *config.Co
|
||||||
}
|
}
|
||||||
|
|
||||||
c.SetBodyStream(bodyReader, -1)
|
c.SetBodyStream(bodyReader, -1)
|
||||||
|
bodyReader.Close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ func NoRouteHandler(cfg *config.Config, limiter *rate.RateLimiter, iplimiter *ra
|
||||||
|
|
||||||
// 处理blob/raw路径
|
// 处理blob/raw路径
|
||||||
if matcher == "blob" {
|
if matcher == "blob" {
|
||||||
rawPath = rawPath[10:]
|
rawPath = rawPath[18:]
|
||||||
rawPath = "raw.githubusercontent.com" + rawPath
|
rawPath = "https://raw.githubusercontent.com" + rawPath
|
||||||
rawPath = strings.Replace(rawPath, "/blob/", "/", 1)
|
rawPath = strings.Replace(rawPath, "/blob/", "/", 1)
|
||||||
matcher = "raw"
|
matcher = "raw"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,16 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// copyHeader 将所有头部从 src 复制到 dst。
|
||||||
|
// 对于多值头部,它会为每个值调用 Add,从而保留所有值。
|
||||||
|
func copyHeader(dst, src http.Header) {
|
||||||
|
for k, vv := range src {
|
||||||
|
for _, v := range vv {
|
||||||
|
dst.Add(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setRequestHeaders(c *app.RequestContext, req *http.Request, cfg *config.Config, matcher string) {
|
func setRequestHeaders(c *app.RequestContext, req *http.Request, cfg *config.Config, matcher string) {
|
||||||
if matcher == "raw" && cfg.Httpc.UseCustomRawHeaders {
|
if matcher == "raw" && cfg.Httpc.UseCustomRawHeaders {
|
||||||
// 使用预定义Header
|
// 使用预定义Header
|
||||||
|
|
@ -56,20 +66,23 @@ func setRequestHeaders(c *app.RequestContext, req *http.Request, cfg *config.Con
|
||||||
req.Header.Set(key, value)
|
req.Header.Set(key, value)
|
||||||
}
|
}
|
||||||
} else if matcher == "clone" {
|
} else if matcher == "clone" {
|
||||||
|
|
||||||
c.Request.Header.VisitAll(func(key, value []byte) {
|
c.Request.Header.VisitAll(func(key, value []byte) {
|
||||||
headerKey := string(key)
|
headerKey := string(key)
|
||||||
headerValue := string(value)
|
headerValue := string(value)
|
||||||
if _, shouldRemove := cloneHeadersToRemove[headerKey]; !shouldRemove {
|
|
||||||
req.Header.Set(headerKey, headerValue)
|
req.Header.Set(headerKey, headerValue)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
for key := range cloneHeadersToRemove {
|
||||||
|
req.Header.Del(key)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c.Request.Header.VisitAll(func(key, value []byte) {
|
c.Request.Header.VisitAll(func(key, value []byte) {
|
||||||
headerKey := string(key)
|
headerKey := string(key)
|
||||||
headerValue := string(value)
|
headerValue := string(value)
|
||||||
if _, shouldRemove := reqHeadersToRemove[headerKey]; !shouldRemove {
|
|
||||||
req.Header.Set(headerKey, headerValue)
|
req.Header.Set(headerKey, headerValue)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
for key := range reqHeadersToRemove {
|
||||||
|
req.Header.Del(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue