feat(internal/handler/proxy): enhance proxy handler to handle image requests and important headers

feat(internal/utils): add IsImageRequest function to identify image requests
This commit is contained in:
wood chen 2024-11-17 09:01:19 +08:00
parent 17f9692ce6
commit fe6d604600
3 changed files with 50 additions and 4 deletions

View File

@ -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 != "" {

View File

@ -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]
}

View File

@ -10,6 +10,7 @@ A simple reverse proxy server written in Go.
2. 不同路径代理不同站点
3. 回源Host修改
4. 大文件使用流式传输, 小文件直接提供
5. 可以按照文件后缀名代理不同站点, 方便图片处理等
## TIPS