ghproxy/proxy/reqheader.go
wjqserver e9e48fcefd fix(proxy): restore header filtering and API matcher consistency
- Canonicalize filtered header deny-lists so Cloudflare and CDN headers are still removed

- Normalize incomplete API repo paths to stable owner-level matcher output regardless of trailing slash or query

- Add regression tests covering header canonicalization and incomplete API repo path parsing
2026-04-12 07:17:59 +08:00

105 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package proxy
import (
"ghproxy/config"
"net/http"
"github.com/infinite-iroha/touka"
)
var (
respHeadersToRemove = map[string]struct{}{
"Content-Security-Policy": {},
"Referrer-Policy": {},
"Strict-Transport-Security": {},
"X-Github-Request-Id": {},
"X-Timer": {},
"X-Served-By": {},
"X-Fastly-Request-Id": {},
}
reqHeadersToRemove = map[string]struct{}{
"CF-IPCountry": {},
"CF-RAY": {},
"CF-Visitor": {},
"CF-Connecting-IP": {},
"CF-EW-Via": {},
"CDN-Loop": {},
"Upgrade": {},
"Connection": {},
"Accept-Encoding": {},
}
cloneHeadersToRemove = map[string]struct{}{
"CF-IPCountry": {},
"CF-RAY": {},
"CF-Visitor": {},
"CF-Connecting-IP": {},
"CF-EW-Via": {},
"CDN-Loop": {},
}
)
// 预定义headers
var (
defaultHeaders = map[string]string{
"Accept": "*/*",
"Accept-Encoding": "",
"Transfer-Encoding": "chunked",
"User-Agent": "GHProxy/1.0",
}
)
// copyHeader 将所有头部从 src 复制到 dst。
// 对于多值头部,它会为每个值调用 Add从而保留所有值。
func copyHeader(dst, src http.Header) {
for k, vv := range src {
for _, v := range vv {
dst.Add(k, v)
}
}
}
func canonicalizeHeaderSet(headers map[string]struct{}) map[string]struct{} {
canonicalized := make(map[string]struct{}, len(headers))
for key := range headers {
canonicalized[http.CanonicalHeaderKey(key)] = struct{}{}
}
return canonicalized
}
func init() {
reqHeadersToRemove = canonicalizeHeaderSet(reqHeadersToRemove)
cloneHeadersToRemove = canonicalizeHeaderSet(cloneHeadersToRemove)
respHeadersToRemove = canonicalizeHeaderSet(respHeadersToRemove)
defaultHeaders = map[string]string{
"Accept": "*/*",
"Accept-Encoding": "",
"Transfer-Encoding": "chunked",
"User-Agent": "GHProxy/1.0",
}
}
func copyHeaderFiltered(dst, src http.Header, denylist map[string]struct{}) {
for k, vv := range src {
if _, denied := denylist[k]; denied {
continue
}
for _, v := range vv {
dst.Add(k, v)
}
}
}
func setRequestHeaders(c *touka.Context, req *http.Request, cfg *config.Config, matcher string) {
if matcher == "raw" && cfg.Httpc.UseCustomRawHeaders {
// 使用预定义Header
for key, value := range defaultHeaders {
req.Header.Set(key, value)
}
} else if matcher == "clone" {
copyHeaderFiltered(req.Header, c.Request.Header, cloneHeadersToRemove)
} else {
copyHeaderFiltered(req.Header, c.Request.Header, reqHeadersToRemove)
}
}