This commit is contained in:
wjqserver 2025-03-11 18:07:17 +08:00
parent e2faa497ab
commit 498266e08e
12 changed files with 207 additions and 166 deletions

View file

@ -6,7 +6,9 @@ import (
"ghproxy/config"
"io"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/gin-gonic/gin"
)
@ -15,38 +17,15 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
method := c.Request.Method
logInfo("%s %s %s %s %s", c.ClientIP(), method, u, c.Request.Header.Get("User-Agent"), c.Request.Proto)
// 发送HEAD请求, 预获取Content-Length
headReq, err := client.NewRequest("HEAD", u, nil)
if err != nil {
HandleError(c, fmt.Sprintf("Failed to create request: %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()
defer func(Body io.ReadCloser) {
if err := Body.Close(); err != nil {
logError("Failed to close response body: %v", err)
}
}(headResp.Body)
contentLength := headResp.Header.Get("Content-Length")
sizelimit := cfg.Server.SizeLimit * 1024 * 1024
if contentLength != "" {
size, err := strconv.Atoi(contentLength)
if err == nil && size > sizelimit {
finalURL := headResp.Request.URL.String()
c.Redirect(http.StatusMovedPermanently, finalURL)
logWarning("%s %s %s %s %s Final-URL: %s Size-Limit-Exceeded: %d", c.ClientIP(), c.Request.Method, c.Request.URL.String(), c.Request.Header.Get("User-Agent"), c.Request.Proto, finalURL, size)
logInfo("U:%s", u)
if cfg.GitClone.Mode == "cache" {
userPath, repoPath, remainingPath, err := extractParts(u)
if err != nil {
HandleError(c, fmt.Sprintf("Failed to extract parts from URL: %v", err))
return
}
// 构建新url
u = cfg.GitClone.SmartGitAddr + userPath + repoPath + remainingPath
}
body, err := readRequestBody(c)
@ -77,9 +56,10 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
}
}(resp.Body)
contentLength = resp.Header.Get("Content-Length")
contentLength := resp.Header.Get("Content-Length")
if contentLength != "" {
size, err := strconv.Atoi(contentLength)
sizelimit := cfg.Server.SizeLimit * 1024 * 1024
if err == nil && size > sizelimit {
finalURL := resp.Request.URL.String()
c.Redirect(http.StatusMovedPermanently, finalURL)
@ -104,14 +84,6 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
resp.Header.Del(header)
}
/*
if cfg.CORS.Enabled {
c.Header("Access-Control-Allow-Origin", "*")
} else {
c.Header("Access-Control-Allow-Origin", "")
}
*/
switch cfg.Server.Cors {
case "*":
c.Header("Access-Control-Allow-Origin", "*")
@ -136,4 +108,43 @@ func GitReq(c *gin.Context, u string, cfg *config.Config, mode string, runMode s
} else {
c.Writer.Flush() // 确保刷入
}
/*
_, err = copyb.CopyBuffer(c.Writer, resp.Body, 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.Proto, err)
return
} else {
c.Writer.Flush() // 确保刷入
}
*/
}
// extractParts 从给定的 URL 中提取所需的部分
func extractParts(rawURL string) (string, string, string, error) {
// 解析 URL
parsedURL, err := url.Parse(rawURL)
if err != nil {
return "", "", "", err
}
// 获取路径部分并分割
pathParts := strings.Split(parsedURL.Path, "/")
// 提取所需的部分
if len(pathParts) < 3 {
return "", "", "", fmt.Errorf("URL path is too short")
}
// 提取 /WJQSERVER-STUDIO 和 /go-utils.git
repoOwner := "/" + pathParts[1]
repoName := "/" + pathParts[2]
// 剩余部分
remainingPath := strings.Join(pathParts[3:], "/")
if remainingPath != "" {
remainingPath = "/" + remainingPath
}
return repoOwner, repoName, remainingPath, nil
}