V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
mekingname
V2EX  ›  Go 编程语言

同一个 HTTP/2 网址,用 Python 的 httpx 请求直接成功,用 Golang 的 net/http 请求立刻 5 秒盾,大家有遇到过吗?

  •  
  •   mekingname ·
    kingname · 2021-08-18 10:38:39 +08:00 · 2989 次点击
    这是一个创建于 1198 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网址是: https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series

    用 HTTPX 请求的代码如下,请求成功,状态码 200:

    用 Golang 的 net/http 请求如下,请求失败,状态码 403:

    如果你查看 httpx 返回的源代码和 net/http 的源代码,你会发现,用 httpx 返回的就是这个页面的源代码。而使用 net/http,返回的就是 CloudFlare 的 5 秒盾页面。

    19 条回复    2023-03-09 17:53:46 +08:00
    abersheeran
        1
    abersheeran  
       2021-08-18 10:40:59 +08:00
    之前偶然看到过,golang 标准库的 TLS 好像实现有点特殊,大概 cf 是针对这个特殊的实现做了检测吧
    ericls
        2
    ericls  
       2021-08-18 10:43:07 +08:00 via iPhone
    抓包看看?
    mekingname
        4
    mekingname  
    OP
       2021-08-18 10:47:34 +08:00
    @ericls 抓过了。我发现用 net/http 请求的报里面,有一些 pseudo-header,就是冒号开头的几个字段。而 httpx 的请求没有。

    net/http 请求的包如下图所示:![]( https://kingname-1257411235.cos.ap-chengdu.myqcloud.com/20210818104656.png)

    httpx 请求的包如下图所示:![]( https://kingname-1257411235.cos.ap-chengdu.myqcloud.com/20210818104725.png)
    mekingname
        5
    mekingname  
    OP
       2021-08-18 11:04:41 +08:00
    @popstk 它这个方案我也试过了。单纯改 CipherSuites 还过不了。
    des
        6
    des  
       2021-08-18 11:11:27 +08:00
    cf 检测机制的问题吧,建议你再重新用 httpx 试试,我这边两个都 403
    mekingname
        7
    mekingname  
    OP
       2021-08-18 11:15:33 +08:00
    @des 我又测试了很多次,只设置 User-Agent 就能得到正确的返回。
    2kCS5c0b0ITXE5k2
        8
    2kCS5c0b0ITXE5k2  
       2021-08-18 11:15:45 +08:00
    @mekingname golang 的 TLS1.3 请求好像不能改 CipherSuites
    des
        9
    des  
       2021-08-18 11:19:02 +08:00
    @mekingname 建议用 curl 测试
    mekingname
        10
    mekingname  
    OP
       2021-08-18 11:21:00 +08:00
    @emeab 那还有救吗
    2kCS5c0b0ITXE5k2
        11
    2kCS5c0b0ITXE5k2  
       2021-08-18 11:23:54 +08:00
    @mekingname 把他锁到 1.2 看看. 1.3 不支持配置 CipherSuites
    mekingname
        12
    mekingname  
    OP
       2021-08-18 11:24:03 +08:00
    @des curl 是会失败。
    mekingname
        13
    mekingname  
    OP
       2021-08-18 11:39:45 +08:00
    @emeab 锁定不住。我试过了两种锁定 TLS 版本的办法,但是它总是自动使用 1.3
    wothard
        14
    wothard  
       2021-08-18 17:06:53 +08:00
    net/http 不支持 http2 吧,试试用这个包 https://pkg.go.dev/golang.org/x/net/http2
    Kisesy
        15
    Kisesy  
       2021-08-18 18:52:50 +08:00
    试了一下,可以跳过,首先设置 UA,然后设置 tls 版本到 1.2,再设置 http.Transport 的 ForceAttemptHTTP2 为假
    强制 http1 访问,就可以了
    humxman
        16
    humxman  
       2021-08-18 19:53:52 +08:00 via Android
    @Kisesy 你这样对设置了 Minimum TLS1.2 的网站不行的吧。
    yin1999
        17
    yin1999  
       2021-08-19 06:58:46 +08:00 via Android
    @wothard 支持的:The http package's Transport and Server both automatically enable HTTP/2 support for simple configurations.
    mekingname
        18
    mekingname  
    OP
       2021-08-19 10:26:42 +08:00
    @wothard net/http2 Overview 的第二段就写明白了:

    > This package is low-level and intended to be used directly by very few people. Most users will use it indirectly through the automatic use by the net/http package (from Go 1.6 and later)

    直接使用 net/http 就可以了。它遇到 http2 页面自动会在底层调用 net/http2,常规请求不需要开发者手动使用。
    forrestshuang
        19
    forrestshuang  
       2023-03-09 17:53:46 +08:00
    // 我成功了,代码在这里
    package main

    import (
    "crypto/tls"
    "fmt"
    "net/http"
    )

    func main() {
    defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
    0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
    client := http.Client{
    Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
    CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
    MaxVersion: tls.VersionTLS12,
    },
    ForceAttemptHTTP2: false,
    },
    }
    req, err := http.NewRequest("GET", "", nil)

    req.Header.Add("authority", "api.nftgo.io")
    req.Header.Add("pragma", "no-cache")
    req.Header.Add("User-Agent", "Apifox/1.0.0 ( https://www.apifox.cn)")

    resp, err := client.Do(req)
    if err != nil {
    fmt.Println(err)
    return
    }
    defer resp.Body.Close()
    fmt.Println(resp.Status)
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5539 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 336ms · UTC 08:55 · PVG 16:55 · LAX 00:55 · JFK 03:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.