Update chunkreq.go

This commit is contained in:
里見 灯花 2025-01-28 11:28:02 +08:00 committed by GitHub
parent e9953946a4
commit af86ccf482
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5,7 +5,9 @@ import (
"fmt" "fmt"
"ghproxy/config" "ghproxy/config"
"io" "io"
"net"
"net/http" "net/http"
"strconv"
"sync" "sync"
"time" "time"
@ -37,6 +39,13 @@ func initChunkedHTTPClient() {
MaxIdleConns: 100, MaxIdleConns: 100,
MaxConnsPerHost: 60, MaxConnsPerHost: 60,
IdleConnTimeout: 20 * time.Second, IdleConnTimeout: 20 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
} }
cclient = &http.Client{ cclient = &http.Client{
Transport: ctr, Transport: ctr,
@ -62,12 +71,31 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
HandleError(c, fmt.Sprintf("Failed to send request: %v", err)) HandleError(c, fmt.Sprintf("Failed to send request: %v", err))
return return
} }
defer headResp.Body.Close() //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)
return
}
}
/*
if err := HandleResponseSize(headResp, cfg, c); err != nil { 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) 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 return
} }
*/
body, err := readRequestBody(c) body, err := readRequestBody(c)
if err != nil { if err != nil {
@ -84,7 +112,6 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
return return
} }
req.Header.Set("Transfer-Encoding", "chunked") // 确保设置分块传输编码
setRequestHeaders(c, req) setRequestHeaders(c, req)
removeWSHeader(req) // 删除Conection Upgrade头, 避免与HTTP/2冲突(检查是否存在Upgrade头) removeWSHeader(req) // 删除Conection Upgrade头, 避免与HTTP/2冲突(检查是否存在Upgrade头)
AuthPassThrough(c, cfg, req) AuthPassThrough(c, cfg, req)
@ -96,12 +123,45 @@ func ChunkedProxyRequest(c *gin.Context, u string, cfg *config.Config, mode stri
} }
defer resp.Body.Close() defer resp.Body.Close()
/*
if err := HandleResponseSize(resp, cfg, c); err != nil { 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) 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 return
} }
*/
CopyResponseHeaders(resp, c, cfg) contentLength = resp.Header.Get("Content-Length")
if contentLength != "" {
size, err := strconv.Atoi(contentLength)
if err == nil && size > sizelimit {
finalURL := resp.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)
return
}
}
for key, values := range resp.Header {
for _, value := range values {
c.Header(key, value)
}
}
headersToRemove := map[string]struct{}{
"Content-Security-Policy": {},
"Referrer-Policy": {},
"Strict-Transport-Security": {},
}
for header := range headersToRemove {
resp.Header.Del(header)
}
if cfg.CORS.Enabled {
c.Header("Access-Control-Allow-Origin", "*")
} else {
c.Header("Access-Control-Allow-Origin", "")
}
c.Status(resp.StatusCode) c.Status(resp.StatusCode)