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

发布于 1周前 作者 h691938207 来自 Go语言

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

网址是: 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 秒盾页面。


更多关于Golang Go语言:同一个 HTTP/2 网址,用 Python 的 httpx 请求直接成功,用 Golang 的 net/http 请求立刻 5 秒盾,大家有遇到过吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

20 回复

之前偶然看到过,golang 标准库的 TLS 好像实现有点特殊,大概 cf 是针对这个特殊的实现做了检测吧

更多关于Golang Go语言:同一个 HTTP/2 网址,用 Python 的 httpx 请求直接成功,用 Golang 的 net/http 请求立刻 5 秒盾,大家有遇到过吗?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


抓包看看?

抓过了。我发现用 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)

它这个方案我也试过了。单纯改 CipherSuites 还过不了。

cf 检测机制的问题吧,建议你再重新用 httpx 试试,我这边两个都 403

我又测试了很多次,只设置 User-Agent 就能得到正确的返回。

golang 的 TLS1.3 请求好像不能改 CipherSuites

建议用 curl 测试

把他锁到 1.2 看看. 1.3 不支持配置 CipherSuites

curl 是会失败。

锁定不住。我试过了两种锁定 TLS 版本的办法,但是它总是自动使用 1.3

net/http 不支持 http2 吧,试试用这个包 https://pkg.go.dev/golang.org/x/net/http2

试了一下,可以跳过,首先设置 UA,然后设置 tls 版本到 1.2,再设置 http.Transport 的 ForceAttemptHTTP2 为假
强制 http1 访问,就可以了

你这样对设置了 Minimum TLS1.2 的网站不行的吧。

支持的:The http package’s Transport and Server both automatically enable HTTP/2 support for simple configurations.

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,常规请求不需要开发者手动使用。

// 我成功了,代码在这里
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)
}

您好!在 Golang 使用 net/http 包请求 HTTP/2 网站时遇到请求延迟(如 5 秒超时)而 Python 的 httpx 请求成功的情况,确实比较罕见,但可能由几个因素引起。以下是一些可能的原因和解决方案:

  1. HTTP/2 配置

    • 确保 Golang 客户端正确配置为使用 HTTP/2。虽然 net/http 从 Go 1.6 开始默认支持 HTTP/2,但服务器可能需要特定的头部或设置。
    • 检查服务器是否支持 HTTP/2,并查看是否有关于 Golang 客户端的特定限制。
  2. 超时设置

    • 检查 Golang 请求中的超时设置。使用 http.ClientTimeoutTransportIdleConnTimeoutDialContext 等超时参数。
    • 可能需要调整这些超时以适应网络延迟或服务器响应速度。
  3. TLS/SSL 配置

    • 确保 Golang 客户端的 TLS 配置正确。使用 http.TransportTLSClientConfig 自定义 TLS 设置。
    • 检查是否有任何证书验证问题或中间人攻击(MITM)可能导致连接延迟。
  4. 网络问题

    • 排除网络问题,如 DNS 解析延迟、防火墙或代理设置等。
  5. 调试和日志

    • 使用 http.ClientCheckRedirectTransportDialContext(用于日志记录)来调试请求流程。
    • 检查服务器日志以获取更多关于请求失败的信息。

如果问题仍然存在,建议进一步分析网络抓包数据或使用 Golang 的调试工具进行深入调查。

回到顶部