From 26ed83b5cd184f3d76ea5f1adc81e7ea21d273be Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Tue, 20 Jan 2026 19:43:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(proxy):=20=E4=BF=AE=E5=A4=8D=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E6=B7=B1=E5=BA=A6=E9=AA=8C=E8=AF=81=E7=9A=84=E8=8B=A5?= =?UTF-8?q?=E5=B9=B2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - detector.go: 修复 AutoConfigureProxy 覆盖探测结果的问题 只有未探测过时才设置默认 proxyReliable 值 - port_scan.go: 改进深度验证机制 - 使用带 Host header 的 HTTP GET 请求替代 OPTIONS - 延长响应等待超时至 2s 以适配慢速服务器 - 正确重置连接 deadline 避免影响后续操作 --- common/proxy/detector.go | 5 ++++- core/port_scan.go | 26 +++++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/common/proxy/detector.go b/common/proxy/detector.go index fe6e7c6..aab86f1 100644 --- a/common/proxy/detector.go +++ b/common/proxy/detector.go @@ -88,7 +88,10 @@ func AutoConfigureProxy(config *ProxyConfig) { // SOCKS5代理默认假设非标准(后续由探测函数验证) if config.Type == ProxyTypeSOCKS5 { SetSOCKS5Standard(false) - SetProxyReliable(true) // 默认可靠,后续由 ProbeProxyBehavior 更新 + // 只有未探测过时才设置默认值,避免覆盖探测结果 + if !IsProxyProbed() { + SetProxyReliable(true) // 默认可靠,后续由 ProbeProxyBehavior 更新 + } } // HTTP/HTTPS代理视为标准且可靠 diff --git a/core/port_scan.go b/core/port_scan.go index 984beec..51e2925 100644 --- a/core/port_scan.go +++ b/core/port_scan.go @@ -401,6 +401,7 @@ func verifyProxyConnectionDeep(conn net.Conn, addr string) (bool, string) { _ = conn.SetReadDeadline(time.Now().Add(200 * time.Millisecond)) buf := make([]byte, 256) n, _ := conn.Read(buf) + _ = conn.SetReadDeadline(time.Time{}) // 重置 deadline if n > 0 { // 收到数据,检查是否为代理错误响应 @@ -412,10 +413,17 @@ func verifyProxyConnectionDeep(conn net.Conn, addr string) (bool, string) { return true, "banner" } - // 阶段2: 发送探测数据 (HTTP OPTIONS) - // OPTIONS 是安全的 HTTP 方法,不会修改服务器状态 + // 阶段2: 发送探测数据 (HTTP GET with Host header) + // 使用完整的 HTTP 请求以获得服务器响应 + // 从 addr 提取主机名作为 Host 头(HTTP 服务器需要正确的 Host 才会响应) + host := addr + if colonIdx := strings.LastIndex(addr, ":"); colonIdx > 0 { + host = addr[:colonIdx] + } + probeReq := fmt.Sprintf("GET / HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", host) _ = conn.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)) - _, writeErr := conn.Write([]byte("OPTIONS / HTTP/1.0\r\n\r\n")) + _, writeErr := conn.Write([]byte(probeReq)) + _ = conn.SetWriteDeadline(time.Time{}) // 重置 deadline if writeErr != nil && isConnectionClosed(writeErr) { // 写入失败(broken pipe/reset)= 连接已被拒绝 @@ -423,9 +431,9 @@ func verifyProxyConnectionDeep(conn net.Conn, addr string) (bool, string) { return false, "write_failed" } - // 阶段3: 等待探测响应 (500ms) - _ = conn.SetReadDeadline(time.Now().Add(500 * time.Millisecond)) - n, err := conn.Read(buf) + // 阶段3: 等待探测响应 (2s - 需要足够时间让 HTTP 服务器响应) + _ = conn.SetReadDeadline(time.Now().Add(2 * time.Second)) + n, readErr := conn.Read(buf) _ = conn.SetReadDeadline(time.Time{}) if n > 0 { @@ -439,11 +447,11 @@ func verifyProxyConnectionDeep(conn net.Conn, addr string) (bool, string) { } // 阶段4: 最终判断 - if err != nil { - errLower := strings.ToLower(err.Error()) + if readErr != nil { + errLower := strings.ToLower(readErr.Error()) for _, pattern := range proxyFailurePatterns { if strings.Contains(errLower, pattern) { - common.LogDebug(fmt.Sprintf("代理连接被拒绝 %s: %v", addr, err)) + common.LogDebug(fmt.Sprintf("代理连接被拒绝 %s: %v", addr, readErr)) return false, "proxy_reject" } }