diff --git a/pkg/webserver/apache/proxy.go b/pkg/webserver/apache/proxy.go index 2a624c96..108d5fba 100644 --- a/pkg/webserver/apache/proxy.go +++ b/pkg/webserver/apache/proxy.go @@ -66,6 +66,7 @@ func parseProxyFile(filePath string) (*types.Proxy, error) { contentStr := string(content) proxy := &types.Proxy{ Resolver: []string{}, + Headers: make(map[string]string), Replaces: make(map[string]string), } @@ -114,6 +115,17 @@ func parseProxyFile(filePath string) (*types.Proxy, error) { proxy.Replaces[sm[1]] = sm[2] } + // 解析自定义请求头 (排除 Host) + headerPattern := regexp.MustCompile(`RequestHeader\s+set\s+(\S+)\s+"([^"]+)"`) + headerMatches := headerPattern.FindAllStringSubmatch(contentStr, -1) + for _, hm := range headerMatches { + headerName := hm[1] + headerValue := hm[2] + if headerName != "Host" { + proxy.Headers[headerName] = headerValue + } + } + return proxy, nil } @@ -241,6 +253,15 @@ func generateProxyConfig(proxy types.Proxy) string { sb.WriteString(" \n") } + // 自定义请求头 + if len(proxy.Headers) > 0 { + sb.WriteString(" \n") + for name, value := range proxy.Headers { + sb.WriteString(fmt.Sprintf(" RequestHeader set %s \"%s\"\n", name, value)) + } + sb.WriteString(" \n") + } + // 响应内容替换 if len(proxy.Replaces) > 0 { sb.WriteString(" \n") diff --git a/pkg/webserver/nginx/proxy.go b/pkg/webserver/nginx/proxy.go index 7f5d5143..eecdac0e 100644 --- a/pkg/webserver/nginx/proxy.go +++ b/pkg/webserver/nginx/proxy.go @@ -77,6 +77,7 @@ func parseProxyFile(filePath string) (*types.Proxy, error) { proxy := &types.Proxy{ Location: strings.TrimSpace(matches[1]), Resolver: []string{}, + Headers: make(map[string]string), Replaces: make(map[string]string), } @@ -146,6 +147,23 @@ func parseProxyFile(filePath string) (*types.Proxy, error) { proxy.Replaces[sfm[1]] = sfm[2] } + // 解析自定义请求头 + standardHeaders := map[string]bool{ + "Host": true, "X-Real-IP": true, "X-Forwarded-For": true, + "X-Forwarded-Proto": true, "Upgrade": true, "Connection": true, + "Early-Data": true, "Accept-Encoding": true, + } + headerPattern := regexp.MustCompile(`proxy_set_header\s+(\S+)\s+"?([^";]+)"?;`) + headerMatches := headerPattern.FindAllStringSubmatch(blockContent, -1) + for _, hm := range headerMatches { + headerName := strings.TrimSpace(hm[1]) + headerValue := strings.TrimSpace(hm[2]) + // 排除标准头 + if !standardHeaders[headerName] { + proxy.Headers[headerName] = headerValue + } + } + return proxy, nil } @@ -269,6 +287,18 @@ func generateProxyConfig(proxy types.Proxy) string { sb.WriteString(" proxy_cache_valid 404 1m;\n") } + // 自定义请求头 + if len(proxy.Headers) > 0 { + for name, value := range proxy.Headers { + // 变量值不加引号 + if strings.HasPrefix(value, "$") { + sb.WriteString(fmt.Sprintf(" proxy_set_header %s %s;\n", name, value)) + } else { + sb.WriteString(fmt.Sprintf(" proxy_set_header %s \"%s\";\n", name, value)) + } + } + } + // 响应内容替换 if len(proxy.Replaces) > 0 { sb.WriteString(" proxy_set_header Accept-Encoding \"\";\n") diff --git a/pkg/webserver/types/proxy.go b/pkg/webserver/types/proxy.go index 9002207c..2c621bb5 100644 --- a/pkg/webserver/types/proxy.go +++ b/pkg/webserver/types/proxy.go @@ -12,6 +12,7 @@ type Proxy struct { Buffering bool `form:"buffering" json:"buffering"` // 是否启用缓冲 Resolver []string `form:"resolver" json:"resolver"` // 自定义 DNS 解析器配置,如: ["8.8.8.8", "ipv6=off"] ResolverTimeout time.Duration `form:"resolver_timeout" json:"resolver_timeout"` // DNS 解析超时时间,如: 5 * time.Second + Headers map[string]string `form:"headers" json:"headers"` // 自定义请求头,如: map["X-Custom-Header"] = "value" Replaces map[string]string `form:"replaces" json:"replaces"` // 响应内容替换,如: map["/old"] = "/new" } diff --git a/web/src/views/website/EditView.vue b/web/src/views/website/EditView.vue index 67c9c426..249cb3b1 100644 --- a/web/src/views/website/EditView.vue +++ b/web/src/views/website/EditView.vue @@ -303,6 +303,7 @@ const addProxy = () => { buffering: true, resolver: [], resolver_timeout: 5 * 1000000000, // 5秒,以纳秒为单位 + headers: {}, replaces: {} }) } @@ -845,6 +846,59 @@ const removeCustomConfig = (index: number) => { + {{ $gettext('Custom Request Headers') }} + + + + : + + + {{ $gettext('Remove') }} + + + + {{ $gettext('Add Request Header') }} + + {{ $gettext('Response Content Replacement') }}