新增支持: 按不同文件回源不同地址

This commit is contained in:
wood chen 2024-11-17 08:12:04 +08:00
parent 2653014c89
commit 74280e215e
4 changed files with 84 additions and 22 deletions

View File

@ -1,7 +1,16 @@
{ {
"MAP": { "MAP": {
"/path1": "https://path1.com/path/path/path", "/path1": {
"/path2": "https://path2.com" "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": { "Compression": {
"Gzip": { "Gzip": {

View File

@ -1,9 +1,14 @@
package config package config
type Config struct { type Config struct {
MAP map[string]string `json:"MAP"` MAP map[string]PathConfig `json:"MAP"` // 改为使用PathConfig
Compression CompressionConfig `json:"Compression"` Compression CompressionConfig `json:"Compression"`
FixedPaths []FixedPathConfig `json:"FixedPaths"` // 新增 FixedPaths []FixedPathConfig `json:"FixedPaths"`
}
type PathConfig struct {
DefaultTarget string `json:"DefaultTarget"` // 默认回源地址
ExtensionMap map[string]string `json:"ExtensionMap"` // 特定后缀的回源地址
} }
type CompressionConfig struct { type CompressionConfig struct {
@ -21,3 +26,29 @@ type FixedPathConfig struct {
TargetHost string `json:"TargetHost"` TargetHost string `json:"TargetHost"`
TargetURL string `json:"TargetURL"` 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{}
}
}

View File

@ -1,4 +1,3 @@
// handler/mirror_proxy.go
package handler package handler
import ( import (

View File

@ -6,6 +6,8 @@ import (
"log" "log"
"net/http" "net/http"
"net/url" "net/url"
"path"
"proxy-go/internal/config"
"proxy-go/internal/utils" "proxy-go/internal/utils"
"strings" "strings"
"time" "time"
@ -16,12 +18,18 @@ const (
) )
type ProxyHandler struct { type ProxyHandler struct {
pathMap map[string]string pathMap map[string]config.PathConfig
}
func NewProxyHandler(pathMap map[string]interface{}) *ProxyHandler {
convertedMap := make(map[string]config.PathConfig)
for path, target := range pathMap {
convertedMap[path] = config.NewPathConfig(target)
} }
func NewProxyHandler(pathMap map[string]string) *ProxyHandler {
return &ProxyHandler{ return &ProxyHandler{
pathMap: pathMap, pathMap: convertedMap,
} }
} }
@ -39,11 +47,11 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 查找匹配的代理路径 // 查找匹配的代理路径
var matchedPrefix string var matchedPrefix string
var targetBase string var pathConfig config.PathConfig
for prefix, target := range h.pathMap { for prefix, cfg := range h.pathMap {
if strings.HasPrefix(r.URL.Path, prefix) { if strings.HasPrefix(r.URL.Path, prefix) {
matchedPrefix = prefix matchedPrefix = prefix
targetBase = target pathConfig = cfg
break break
} }
} }
@ -58,6 +66,7 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 构建目标 URL // 构建目标 URL
targetPath := strings.TrimPrefix(r.URL.Path, matchedPrefix) targetPath := strings.TrimPrefix(r.URL.Path, matchedPrefix)
// URL 解码,然后重新编码,确保特殊字符被正确处理 // URL 解码,然后重新编码,确保特殊字符被正确处理
decodedPath, err := url.QueryUnescape(targetPath) decodedPath, err := url.QueryUnescape(targetPath)
if err != nil { if err != nil {
@ -67,6 +76,20 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return 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, "/") parts := strings.Split(decodedPath, "/")
for i, part := range parts { for i, part := range parts {