package main import ( "flag" "log" "net/http" "time" "github.com/darkit/goproxy/internal/config" "github.com/darkit/goproxy/internal/dns" "github.com/darkit/goproxy/internal/proxy" ) // CustomPortDelegate 自定义端口委托 type CustomPortDelegate struct { proxy.DefaultDelegate targetHost string targetPort string resolver dns.Resolver } // ModifyRequest 修改请求头 func (d *CustomPortDelegate) ModifyRequest(req *http.Request) { log.Printf("收到请求: %s %s", req.Method, req.URL.String()) // 设置标准浏览器请求头 req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/122.0.0.0 Safari/537.36") req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8") req.Header.Set("Connection", "keep-alive") // 设置Host头 req.Host = d.targetHost // 设置请求的URL方案为HTTPS req.URL.Scheme = "https" log.Printf("修改后的请求: %s %s", req.Method, req.URL.String()) } // ModifyResponse 修改响应头 func (d *CustomPortDelegate) ModifyResponse(resp *http.Response) error { log.Printf("收到响应: %d %s", resp.StatusCode, resp.Status) // 添加CORS头和代理标识 resp.Header.Set("Access-Control-Allow-Origin", "*") resp.Header.Set("X-Proxied-By", "GoProxy-CustomPort") return nil } // ResolveBackend 解析后端服务器 func (d *CustomPortDelegate) ResolveBackend(req *http.Request) (string, error) { // 从自定义端口解析获取目标地址 endpoint, err := d.resolver.ResolveWithPort(d.targetHost, 0) if err != nil { log.Printf("解析目标主机失败: %v, 使用默认端口: %s", err, d.targetPort) return d.targetHost + ":" + d.targetPort, nil } // 优先使用解析得到的端口 if endpoint.Port > 0 { address := endpoint.GetAddressWithDefaultPort(0) log.Printf("连接到目标服务器(自定义端口): %s", address) return address, nil } // 使用默认端口 address := endpoint.GetAddressWithDefaultPort(443) log.Printf("连接到目标服务器(默认端口): %s", address) return address, nil } func main() { // 命令行参数 listenAddr := flag.String("listen", ":8080", "监听地址") targetHost := flag.String("target", "example.com", "目标站点主机名") targetPort := flag.String("port", "443", "默认目标端口") dnsFile := flag.String("dns", "", "DNS配置文件路径 (JSON格式)") hostsFile := flag.String("hosts", "", "Hosts文件路径") flag.Parse() // 创建DNS解析器 var resolver dns.Resolver var err error if *dnsFile != "" { // 从JSON文件加载DNS配置 dnsConfig, err := dns.LoadFromJSON(*dnsFile) if err != nil { log.Printf("加载DNS配置文件失败: %v,将使用默认DNS解析器", err) resolver = dns.NewResolver() } else { resolver = dns.NewResolverFromConfig(dnsConfig) log.Printf("已加载DNS配置,包含 %d 条记录", len(dnsConfig.Records)) } } else if *hostsFile != "" { // 从hosts文件加载DNS配置 dnsConfig, err := dns.LoadFromHostsFile(*hostsFile) if err != nil { log.Printf("加载hosts文件失败: %v,将使用默认DNS解析器", err) resolver = dns.NewResolver() } else { resolver = dns.NewResolverFromConfig(dnsConfig) log.Printf("已加载hosts文件,包含 %d 条记录", len(dnsConfig.Records)) } } else { // 创建默认解析器 resolver = dns.NewResolver() // 添加一些测试记录(带端口) resolver.AddWithPort("example.com", "93.184.216.34", 443) resolver.AddWithPort("api.example.com", "93.184.216.34", 8443) resolver.AddWithPort("dev.example.com", "127.0.0.1", 3000) resolver.AddWithPort("api.dev.example.com", "127.0.0.1", 3001) } // 创建自定义DNS拨号器 dnsDialer := dns.NewDialer(resolver) // 创建配置 cfg := config.DefaultConfig() cfg.ReverseProxy = true // 启用反向代理模式 cfg.DecryptHTTPS = false // 不解密HTTPS流量,避免TLS问题 cfg.IdleTimeout = 30 * time.Second // 连接空闲超时 cfg.AddXForwardedFor = true // 添加X-Forwarded-For头 cfg.AddXRealIP = true // 添加X-Real-IP头 cfg.SupportWebSocketUpgrade = true // 支持WebSocket升级 cfg.EnableCompression = false // 不启用压缩 cfg.EnableCORS = true // 启用CORS cfg.EnableRetry = false // 关闭重试功能 cfg.EnableConnectionPool = false // 禁用连接池 // 创建自定义委托 delegate := &CustomPortDelegate{ targetHost: *targetHost, targetPort: *targetPort, resolver: resolver, } // 创建代理实例 p := proxy.New(&proxy.Options{ Config: cfg, Delegate: delegate, }) // 设置自定义拨号器 p.SetDialContext(dnsDialer.DialContext) // 创建HTTP服务器 server := &http.Server{ Addr: *listenAddr, Handler: p, } // 获取目标主机的端口信息(如果有) endpoint, err := resolver.ResolveWithPort(*targetHost, 443) if err != nil { log.Printf("获取目标主机端口信息失败,将使用默认端口: %s", *targetPort) } else if endpoint.Port > 0 { log.Printf("目标主机 %s 使用自定义端口: %d", *targetHost, endpoint.Port) } else { log.Printf("目标主机 %s 使用默认端口: %s", *targetHost, *targetPort) } // 启动HTTP服务器 log.Printf("自定义端口代理启动,监听地址: %s,目标: %s", *listenAddr, *targetHost) log.Printf("提示: 尝试访问 http://localhost%s 将被代理到 %s 的自定义端口", *listenAddr, *targetHost) err = server.ListenAndServe() if err != nil { log.Fatalf("服务器启动失败: %v", err) } }