diff --git a/internal/handler/proxy.go b/internal/handler/proxy.go index d7f7086..b3a25cc 100644 --- a/internal/handler/proxy.go +++ b/internal/handler/proxy.go @@ -104,21 +104,51 @@ func (h *ProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body) if err != nil { http.Error(w, "Error creating proxy request", http.StatusInternalServerError) - log.Printf("[%s] %s %s -> 500 (error: %v) [%v]", - utils.GetClientIP(r), r.Method, r.URL.Path, err, time.Since(startTime)) return } - // 复制原始请求的 header + // 复制所有原始请求头 copyHeader(proxyReq.Header, r.Header) - // 设置必要的头部,使用目标站点的 Host + // 特别确保这些重要的头部被正确传递 + if accept := r.Header.Get("Accept"); accept != "" { + proxyReq.Header.Set("Accept", accept) + } + // 其他可能影响图片优化的重要头部 + importantHeaders := []string{ + "Accept-Encoding", + "User-Agent", + "Viewport-Width", + "Width", + "DPR", + "Device-Memory", + "Save-Data", + "Sec-CH-DPR", + "Sec-CH-Width", + "Sec-CH-Viewport-Width", + "Sec-CH-Device-Memory", + } + for _, header := range importantHeaders { + if value := r.Header.Get(header); value != "" { + proxyReq.Header.Set(header, value) + } + } + + // 设置必要的代理头部 proxyReq.Host = parsedURL.Host proxyReq.Header.Set("Host", parsedURL.Host) proxyReq.Header.Set("X-Real-IP", utils.GetClientIP(r)) proxyReq.Header.Set("X-Forwarded-Host", r.Host) proxyReq.Header.Set("X-Forwarded-Proto", r.URL.Scheme) + // 如果是图片请求,添加 Cloudflare-specific 头部 + if utils.IsImageRequest(r.URL.Path) { + // 保持原始的 Accept 头部,让 Cloudflare 可以根据客户端支持的格式来优化 + if accept := r.Header.Get("Accept"); accept != "" { + proxyReq.Header.Set("Accept", accept) + } + } + // 添加或更新 X-Forwarded-For if clientIP := utils.GetClientIP(r); clientIP != "" { if prior := proxyReq.Header.Get("X-Forwarded-For"); prior != "" { diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 8984bc8..b5af158 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "net/http" + "path/filepath" "strings" ) @@ -44,3 +45,17 @@ func FormatBytes(bytes int64) string { return fmt.Sprintf("%d Bytes", bytes) } } + +// 判断是否是图片请求 +func IsImageRequest(path string) bool { + ext := strings.ToLower(filepath.Ext(path)) + imageExts := map[string]bool{ + ".jpg": true, + ".jpeg": true, + ".png": true, + ".gif": true, + ".webp": true, + ".avif": true, + } + return imageExts[ext] +} diff --git a/readme.md b/readme.md index f9a3776..6915bf1 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ A simple reverse proxy server written in Go. 2. 不同路径代理不同站点 3. 回源Host修改 4. 大文件使用流式传输, 小文件直接提供 +5. 可以按照文件后缀名代理不同站点, 方便图片处理等 ## TIPS