You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang如何在SetupClient函数else分支内修改返回的*http.Client值?

Go语言SetupClient函数返回代理客户端不生效问题修复

问题根因

你现在的代码无法在else分支返回代理客户端,核心原因有3个:

  1. http.Request是一次性对象,直连请求已经消费过req实例,直接复用给代理客户端发起第二次请求会直接报错,触发err != nil的分支,自然走不到内部的return逻辑
  2. 所有响应的resp.Body都没有主动关闭,多次循环后会占用大量系统资源,引发后续请求异常
  3. 代理请求失败后没有任何兜底逻辑,会直接进入下一轮循环,看起来就像返回值没有更新

修复代码

func SetupClient() *http.Client {
    // 正则和固定配置提出来,不用每次循环重复构造
    re := regexp.MustCompile(`:"(.*)`)
    tlsConfig := &tls.Config{InsecureSkipVerify: true}
    PTransport := &http.Transport{TLSClientConfig: tlsConfig, Proxy: http.ProxyFromEnvironment}
    directTransport := &http.Transport{TLSClientConfig: tlsConfig}
    
    for {
        fmt.Printf(" trying direct connection \n")
        // 每次请求重新构造req,不要复用
        req, err := http.NewRequest("GET", "https://192.168.1.98:4443/api/endpointx", nil)
        if err != nil {
            fmt.Println("构造请求失败:", err)
            time.Sleep(5 * time.Second)
            continue
        }
        // 统一设置请求头
        req.Header.Set("Cookie", "JSESSIONID=shszrhdrhdrhjdhdr")
        req.Header.Set("Referer", "https://aaegesgsegesgegeg")
        req.Header.Set("Upgrade-Insecure-Requests", "1")
        req.Header.Set("Connection", "close")
        req.Header.Set("Accept-Language", "it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3")
        req.Header.Set("Accept", "*/*")
        req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0")

        time.Sleep(5 * time.Second)
        // 先尝试直连
        directClient := &http.Client{Transport: directTransport}
        resp, err := directClient.Do(req)
        if err == nil {
            body, _ := ioutil.ReadAll(resp.Body)
            _ = resp.Body.Close() // 用完立即关闭body

            match := re.FindStringSubmatch(string(body))
            if len(match) < 2 { // 加匹配校验,避免索引越界panic
                fmt.Println("正则匹配失败")
                continue
            }
            fmt.Println("quello che viene matchato è:", match[1])

            if strings.Contains(string(body), "aaaaaaaa") {
                fmt.Printf(" inside IF\n ")
                return directClient
            } else {
                fmt.Printf(" inside else\n ")
                // 代理请求重新构造req
                proxyReq, _ := http.NewRequest("GET", "https://192.168.1.98:4443/api/endpointx", nil)
                proxyReq.Header = req.Header.Clone() // 复用之前的请求头
                proxyClient := &http.Client{Transport: PTransport}
                proxyResp, err := proxyClient.Do(proxyReq)
                if err == nil {
                    proxyBody, _ := ioutil.ReadAll(proxyResp.Body)
                    _ = proxyResp.Body.Close()
                    if strings.Contains(string(proxyBody), match[1]) {
                        return proxyClient
                    }
                } else {
                    fmt.Println("代理请求失败:", err)
                }
            }
        } else {
            fmt.Println("直连请求失败:", err)
        }
    }
}

关键修改说明

  • 把正则、TLS配置、传输层实例提到循环外,避免每次循环重复创建,减少不必要的性能开销
  • 每次发起新请求都重新构造Request实例,不要复用已经被消费过的请求对象
  • 所有resp.Body使用完后立即关闭,避免资源泄漏
  • 增加正则匹配结果校验,避免匹配失败后索引越界panic
  • 补充各环节错误日志打印,方便排查问题

内容的提问来源于stack exchange,提问作者ryout

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 08:09:02