mirror of
https://github.com/WJQSERVER-STUDIO/ghproxy.git
synced 2026-02-03 08:11:11 +08:00
v2 (#33)
- CHANGE: 优化`proxy`核心模块, 使用Chuncked Buffer传输数据, 减少内存占用 - REMOVE: caddy - REMOVE: nocache - CHANGE: 优化前端页面
This commit is contained in:
parent
beb441f0b0
commit
c393191b93
27 changed files with 596 additions and 559 deletions
109
proxy/chunkreq.go
Normal file
109
proxy/chunkreq.go
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"ghproxy/config"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var chunkedBufferSize int
|
||||
|
||||
func InitChunkedBufferSize(cfgBufferSize int) {
|
||||
if cfgBufferSize == 0 {
|
||||
chunkedBufferSize = 4096 // 默认缓冲区大小
|
||||
} else {
|
||||
chunkedBufferSize = cfgBufferSize
|
||||
}
|
||||
}
|
||||
|
||||
func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode string, runMode string) {
|
||||
method := c.Request.Method
|
||||
logInfo("%s %s %s %s %s", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto)
|
||||
|
||||
// 创建HTTP客户端
|
||||
client := &http.Client{}
|
||||
|
||||
// 发送HEAD请求, 预获取Content-Length
|
||||
headReq, err := http.NewRequest("HEAD", u, nil)
|
||||
if err != nil {
|
||||
HandleError(c, fmt.Sprintf("创建HEAD请求失败: %v", err))
|
||||
return
|
||||
}
|
||||
setRequestHeaders(c, headReq)
|
||||
AuthPassThrough(c, cfg, headReq)
|
||||
|
||||
headResp, err := client.Do(headReq)
|
||||
if err != nil {
|
||||
HandleError(c, fmt.Sprintf("Failed to send request: %v", err))
|
||||
return
|
||||
}
|
||||
defer headResp.Body.Close()
|
||||
|
||||
if err := HandleResponseSize(headResp, cfg, c); err != nil {
|
||||
logWarning("%s %s %s %s %s Response-Size-Error: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := readRequestBody(c)
|
||||
if err != nil {
|
||||
HandleError(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
bodyReader := bytes.NewBuffer(body)
|
||||
|
||||
// 创建请求
|
||||
req, err := http.NewRequest(method, u, bodyReader)
|
||||
if err != nil {
|
||||
HandleError(c, fmt.Sprintf("创建请求失败: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Set("Transfer-Encoding", "chunked") // 确保设置分块传输编码
|
||||
setRequestHeaders(c, req)
|
||||
AuthPassThrough(c, cfg, req)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
HandleError(c, fmt.Sprintf("发送请求失败: %v", err))
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := HandleResponseSize(resp, cfg, c); err != nil {
|
||||
logWarning("%s %s %s %s %s Response-Size-Error: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err)
|
||||
return
|
||||
}
|
||||
|
||||
CopyResponseHeaders(resp, c, cfg)
|
||||
|
||||
c.Status(resp.StatusCode)
|
||||
if err := chunkedCopyResponseBody(c, resp.Body); err != nil {
|
||||
logError("%s %s %s %s %s 响应复制错误: %v", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制响应体
|
||||
func chunkedCopyResponseBody(c *gin.Context, respBody io.Reader) error {
|
||||
buf := make([]byte, chunkedBufferSize)
|
||||
for {
|
||||
n, err := respBody.Read(buf)
|
||||
if n > 0 {
|
||||
if _, err := c.Writer.Write(buf[:n]); err != nil {
|
||||
return err
|
||||
}
|
||||
c.Writer.Flush() // 确保每次写入后刷新
|
||||
}
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue