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

Golang使用utls搭配fhttp时出现http2握手失败该如何解决?

修复方案

错误根因

报错是因为TLS协商阶段没有正确声明支持HTTP2协议,导致HTTP/1.x传输层收到了HTTP2的二进制帧无法解析,最终触发握手失败。utls配置不需要放到HTTP2传输层t2中,保留在t1的DialTLSContext中即可,原有代码的问题在于缺少ALPN协议声明和存在冗余配置。

核心修改点

  • 给utls的Config新增NextProtos字段,显式声明支持h2(HTTP2)和http/1.1协议,保证服务端返回对应协议的响应
  • 移除手动赋值t1.H2transport = t2的冗余代码,http2.ConfigureTransports方法会自动完成HTTP2传输层的注入,重复赋值会导致逻辑冲突

修改后完整代码

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"
    "net"

    tls "github.com/refraction-networking/utls"
    http "github.com/useflyent/fhttp"
    "github.com/useflyent/fhttp/http2"
)

func main() {
    // 创建fhttp传输层
    t1 := &http.Transport{
        DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
            tcpConn, err := (&net.Dialer{}).DialContext(ctx, network, addr)
            if err != nil {
                return nil, err
            }
            // 新增NextProtos字段,显式声明支持的协议
            config := tls.Config{
                ServerName: "google.com",
                NextProtos: []string{"h2", "http/1.1"},
            }
            tlsConn := tls.UClient(tcpConn, &config, tls.HelloChrome_Auto)

            err = tlsConn.Handshake()
            if err != nil {
                return nil, fmt.Errorf("uTlsConn.Handshake() error: %w", err)
            }

            return tlsConn, nil
        },
        ForceAttemptHTTP2: true,
    }

    // 配置HTTP2传输层,方法会自动将生成的t2注入到t1中,无需手动赋值
    _, err := http2.ConfigureTransports(t1)
    if err != nil {
        log.Fatalf(err.Error())
    }

    client := &http.Client{
        Transport: t1,
    }

    req, err := http.NewRequest("GET", "https://www.google.com/", nil)
    req.Header = http.Header{
        "sec-ch-ua":                 {"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"90\", \"Google Chrome\";v=\"90\""},
        "sec-ch-ua-mobile":          {"?0"},
        "upgrade-insecure-requests": {"1"},
        "user-agent":                {"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"},
        "accept":                    {"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"},
        "sec-fetch-site":            {"none"},
        "sec-fetch-mode":            {"navigate"},
        "sec-fetch-user":            {"?1"},
        "sec-fetch-dest":            {"document"},
        "accept-encoding":           {"gzip, deflate, br"},
    }

    resp, err := client.Do(req)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(resp.StatusCode)
        body, _ := ioutil.ReadAll(resp.Body)
        fmt.Println(string(body))
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:30:00