From 74280e215e6ff4c4d1d41fd0522ca729b1a7d0ef Mon Sep 17 00:00:00 2001 From: wood chen Date: Sun, 17 Nov 2024 08:12:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81:=20?= =?UTF-8?q?=E6=8C=89=E4=B8=8D=E5=90=8C=E6=96=87=E4=BB=B6=E5=9B=9E=E6=BA=90?= =?UTF-8?q?=E4=B8=8D=E5=90=8C=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/config.json | 33 +++++++++++++++++----------- internal/config/types.go | 37 +++++++++++++++++++++++++++++--- internal/handler/mirror_proxy.go | 1 - internal/handler/proxy.go | 35 ++++++++++++++++++++++++------ 4 files changed, 84 insertions(+), 22 deletions(-) diff --git a/data/config.json b/data/config.json index 03920f7..3fee8d0 100644 --- a/data/config.json +++ b/data/config.json @@ -1,7 +1,16 @@ { "MAP": { - "/path1": "https://path1.com/path/path/path", - "/path2": "https://path2.com" + "/path1": { + "DefaultTarget": "https://path1.com/path/path/path", + "ExtensionMap": { + "jpg": "https://path1-img.com/path/path/path", + "png": "https://path1-img.com/path/path/path" + } + }, + "/path2": "https://path2.com", + "/path3": { + "DefaultTarget": "https://path3.com" + } }, "Compression": { "Gzip": { @@ -14,15 +23,15 @@ } }, "FixedPaths": [ - { - "Path": "/cdnjs", - "TargetHost": "cdnjs.cloudflare.com", - "TargetURL": "https://cdnjs.cloudflare.com" - }, - { - "Path": "/jsdelivr", - "TargetHost": "cdn.jsdelivr.net", - "TargetURL": "https://cdn.jsdelivr.net" - } + { + "Path": "/cdnjs", + "TargetHost": "cdnjs.cloudflare.com", + "TargetURL": "https://cdnjs.cloudflare.com" + }, + { + "Path": "/jsdelivr", + "TargetHost": "cdn.jsdelivr.net", + "TargetURL": "https://cdn.jsdelivr.net" + } ] } \ No newline at end of file diff --git a/internal/config/types.go b/internal/config/types.go index 9f68271..f3ed8ca 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -1,9 +1,14 @@ package config type Config struct { - MAP map[string]string `json:"MAP"` - Compression CompressionConfig `json:"Compression"` - FixedPaths []FixedPathConfig `json:"FixedPaths"` // 新增 + MAP map[string]PathConfig `json:"MAP"` // 改为使用PathConfig + Compression CompressionConfig `json:"Compression"` + FixedPaths []FixedPathConfig `json:"FixedPaths"` +} + +type PathConfig struct { + DefaultTarget string `json:"DefaultTarget"` // 默认回源地址 + ExtensionMap map[string]string `json:"ExtensionMap"` // 特定后缀的回源地址 } type CompressionConfig struct { @@ -21,3 +26,29 @@ type FixedPathConfig struct { TargetHost string `json:"TargetHost"` TargetURL string `json:"TargetURL"` } + +// 添加一个辅助方法来处理字符串到 PathConfig 的转换 +func NewPathConfig(target interface{}) PathConfig { + switch v := target.(type) { + case string: + // 简单字符串格式 + return PathConfig{ + DefaultTarget: v, + } + case map[string]interface{}: + // 完整配置格式 + config := PathConfig{ + DefaultTarget: v["DefaultTarget"].(string), + } + if extMap, ok := v["ExtensionMap"].(map[string]interface{}); ok { + config.ExtensionMap = make(map[string]string) + for ext, target := range extMap { + config.ExtensionMap[ext] = target.(string) + } + } + return config + default: + // 处理异常情况 + return PathConfig{} + } +} diff --git a/internal/handler/mirror_proxy.go b/internal/handler/mirror_proxy.go index 22a80a8..16aa8aa 100644 --- a/internal/handler/mirror_proxy.go +++ b/internal/handler/mirror_proxy.go @@ -1,4 +1,3 @@ -// handler/mirror_proxy.go package handler import ( diff --git a/internal/handler/proxy.go b/internal/handler/proxy.go index bb3f94d..d869ce3 100644 --- a/internal/handler/proxy.go +++ b/internal/handler/proxy.go @@ -6,6 +6,8 @@ import ( "log" "net/http" "net/url" + "path" + "proxy-go/internal/config" "proxy-go/internal/utils" "strings" "time" @@ -16,12 +18,18 @@ const ( ) type ProxyHandler struct { - pathMap map[string]string + pathMap map[string]config.PathConfig } -func NewProxyHandler(pathMap map[string]string) *ProxyHandler { +func NewProxyHandler(pathMap map[string]interface{}) *ProxyHandler { + convertedMap := make(map[string]config.PathConfig) + + for path, target := range pathMap { + convertedMap[path] = config.NewPathConfig(target) + } + return &ProxyHandler{ - pathMap: pathMap, + pathMap: convertedMap, } } @@ -39,11 +47,11 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 查找匹配的代理路径 var matchedPrefix string - var targetBase string - for prefix, target := range h.pathMap { + var pathConfig config.PathConfig + for prefix, cfg := range h.pathMap { if strings.HasPrefix(r.URL.Path, prefix) { matchedPrefix = prefix - targetBase = target + pathConfig = cfg break } } @@ -58,6 +66,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 构建目标 URL targetPath := strings.TrimPrefix(r.URL.Path, matchedPrefix) + // URL 解码,然后重新编码,确保特殊字符被正确处理 decodedPath, err := url.QueryUnescape(targetPath) if err != nil { @@ -67,6 +76,20 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + // 确定目标基础URL + targetBase := pathConfig.DefaultTarget + + // 检查文件扩展名 + if pathConfig.ExtensionMap != nil { + ext := strings.ToLower(path.Ext(decodedPath)) + if ext != "" { + ext = ext[1:] // 移除开头的点 + if alternativeTarget, exists := pathConfig.ExtensionMap[ext]; exists { + targetBase = alternativeTarget + } + } + } + // 重新编码路径,保留 '/' parts := strings.Split(decodedPath, "/") for i, part := range parts {