mirror of
https://github.com/woodchen-ink/proxy-go.git
synced 2025-07-18 08:31:55 +08:00
refactor(handler): enhance mirror proxy handler with URL parsing and CORS headers
This commit is contained in:
parent
a7753f90d5
commit
2653014c89
@ -2,9 +2,11 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"proxy-go/internal/utils"
|
"proxy-go/internal/utils"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -23,10 +25,8 @@ func (h *MirrorProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH")
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH")
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "*")
|
w.Header().Set("Access-Control-Allow-Headers", "*")
|
||||||
// 如果需要允许发送凭证(cookies等),可以设置:
|
|
||||||
// w.Header().Set("Access-Control-Allow-Credentials", "true")
|
|
||||||
|
|
||||||
// 处理 OPTIONS 请求(预检请求)
|
// 处理 OPTIONS 请求
|
||||||
if r.Method == "OPTIONS" {
|
if r.Method == "OPTIONS" {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
log.Printf("| %-6s | %3d | %12s | %15s | %10s | %-30s | CORS Preflight",
|
log.Printf("| %-6s | %3d | %12s | %15s | %10s | %-30s | CORS Preflight",
|
||||||
@ -36,18 +36,37 @@ func (h *MirrorProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 从路径中提取实际URL
|
// 从路径中提取实际URL
|
||||||
// 例如:/mirror/https://example.com/path 变成 https://example.com/path
|
|
||||||
actualURL := strings.TrimPrefix(r.URL.Path, "/mirror/")
|
actualURL := strings.TrimPrefix(r.URL.Path, "/mirror/")
|
||||||
if actualURL == "" || actualURL == r.URL.Path {
|
if actualURL == "" || actualURL == r.URL.Path {
|
||||||
http.Error(w, "Invalid URL", http.StatusBadRequest)
|
http.Error(w, "Invalid URL", http.StatusBadRequest)
|
||||||
|
log.Printf("| %-6s | %3d | %12s | %15s | %10s | %-30s | Invalid URL",
|
||||||
|
r.Method, http.StatusBadRequest, time.Since(startTime),
|
||||||
|
utils.GetClientIP(r), "-", r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加原始请求中的查询参数和片段
|
|
||||||
if r.URL.RawQuery != "" {
|
if r.URL.RawQuery != "" {
|
||||||
actualURL += "?" + r.URL.RawQuery
|
actualURL += "?" + r.URL.RawQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析目标 URL 以获取 host
|
||||||
|
parsedURL, err := url.Parse(actualURL)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Invalid URL", http.StatusBadRequest)
|
||||||
|
log.Printf("| %-6s | %3d | %12s | %15s | %10s | %-30s | Parse URL error: %v",
|
||||||
|
r.Method, http.StatusBadRequest, time.Since(startTime),
|
||||||
|
utils.GetClientIP(r), "-", actualURL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保有 scheme
|
||||||
|
scheme := parsedURL.Scheme
|
||||||
|
if scheme == "" {
|
||||||
|
scheme = "https"
|
||||||
|
actualURL = "https://" + actualURL
|
||||||
|
parsedURL, _ = url.Parse(actualURL)
|
||||||
|
}
|
||||||
|
|
||||||
// 创建新的请求
|
// 创建新的请求
|
||||||
proxyReq, err := http.NewRequest(r.Method, actualURL, r.Body)
|
proxyReq, err := http.NewRequest(r.Method, actualURL, r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -61,11 +80,24 @@ func (h *MirrorProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
// 复制原始请求的header
|
// 复制原始请求的header
|
||||||
copyHeader(proxyReq.Header, r.Header)
|
copyHeader(proxyReq.Header, r.Header)
|
||||||
|
|
||||||
|
// 设置必要的请求头
|
||||||
|
proxyReq.Header.Set("Origin", fmt.Sprintf("%s://%s", scheme, parsedURL.Host))
|
||||||
|
proxyReq.Header.Set("Referer", fmt.Sprintf("%s://%s/", scheme, parsedURL.Host))
|
||||||
|
if ua := r.Header.Get("User-Agent"); ua != "" {
|
||||||
|
proxyReq.Header.Set("User-Agent", ua)
|
||||||
|
} else {
|
||||||
|
proxyReq.Header.Set("User-Agent", "Mozilla/5.0")
|
||||||
|
}
|
||||||
|
proxyReq.Header.Set("Host", parsedURL.Host)
|
||||||
|
proxyReq.Host = parsedURL.Host
|
||||||
|
|
||||||
// 发送请求
|
// 发送请求
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Transport: &http.Transport{
|
Transport: &http.Transport{
|
||||||
DisableCompression: true,
|
DisableCompression: true,
|
||||||
|
// 可以添加其他传输设置,如TLS配置等
|
||||||
},
|
},
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
}
|
}
|
||||||
resp, err := client.Do(proxyReq)
|
resp, err := client.Do(proxyReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -77,9 +109,6 @@ func (h *MirrorProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// 设置CORS头
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
|
|
||||||
// 复制响应头
|
// 复制响应头
|
||||||
copyHeader(w.Header(), resp.Header)
|
copyHeader(w.Header(), resp.Header)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user