How do I adjust Go's http Client (or Transport) to mimic curls –http2-prior-knowledge flag?

huangapple go评论83阅读模式
英文:

How do I adjust Go's http Client (or Transport) to mimic curls --http2-prior-knowledge flag?

问题

我正在与一个我无法控制的服务器进行交互,该服务器在请求包含内容(带有有效负载的POST、PUT、PATCH请求)时不执行协议升级。目前还不清楚服务器的问题是什么,但我注意到当我使用--http2-prior-knowledge查询时,协议会升级:

❯ curl -i -PUT --http2-prior-knowledge  http://localhost:8081/document/v1/foo -d '{\"fields\": {\"docid\": \"123\"}}'
HTTP/2 200 
date: Tue, 08 Nov 2022 13:26:50 GMT
content-type: application/json;charset=utf-8
vary: Accept-Encoding
content-length: 78

而没有使用--http2-prior-knowledge的相同请求会停留在HTTP/1.1。这似乎更接近Go的HTTP客户端的默认行为:

❯ curl -i -PUT --http2 http://localhost:8081/document/v1/foo -d '{\"fields\": {\"docid\": \"123\"}}'
HTTP/1.1 200 OK
Date: Tue, 08 Nov 2022 01:37:17 GMT
Content-Type: application/json;charset=utf-8
Vary: Accept-Encoding
Content-Length: 78

当我使用Go的默认客户端调用相同的API时,协议不会升级。我尝试在传输中设置ForceAttemptHTTP2: true,但每个http.Response.Proto都是HTTP/1.1

我认为我需要了解的是如何在Go中模拟curl的prior-knowledge标志。这可能吗?

英文:

I'm interacting with a server (that is out of my control) in which protocol upgrade is not performed by the server if a request contains content (POST, PUT, PATCH with payload). It's unclear exactly what the issue with the server is, but I noticed that when I query with --http2-prior-knowledge, the protocol is upgraded:

❯ curl -i -PUT --http2-prior-knowledge  http://localhost:8081/document/v1/foo -d '{"fields": {"docid": "123"}}'
HTTP/2 200 
date: Tue, 08 Nov 2022 13:26:50 GMT
content-type: application/json;charset=utf-8
vary: Accept-Encoding
content-length: 78

The same request without --http2-prior-knowledge is stuck at HTTP/1.1. This seems closer to the default behaviour of Go's HTTP client

❯ curl -i -PUT --http2 http://localhost:8081/document/v1/foo -d '{"fields": {"docid": "123"}}'
HTTP/1.1 200 OK
Date: Tue, 08 Nov 2022 01:37:17 GMT
Content-Type: application/json;charset=utf-8
Vary: Accept-Encoding
Content-Length: 78

When I call this same API using Go's default client, the protocol is not upgraded. I've tried setting ForceAttemptHTTP2: true on the transport, but each http.Response contains a .Proto of HTTP/1.1

I think what I need to understand is how I can mimic curl's prior-knowledge flag in Go. Is this possible?

答案1

得分: 1

我通过指定一个自定义的http2.Transport来解决了这个问题,跳过了TLS拨号。回顾起来,理想的解决方案是使用一个SSL证书(自签名即可),这样可以更好地保证使用HTTP2。以下是一些相关链接:

c := &http.Client{
        // 跳过TLS拨号
        Transport: &http2.Transport{
           AllowHTTP: true,
           DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {
              return net.Dial(netw, addr)
           },
        },
}

链接:

英文:

I solved this issue by specifying a custom http2.Transport which skipped TLS dial. The ideal solution, in retrospect, is to use an SSL certificate (self-signed is sufficient) which would better guarantee the use of HTTP2. Leaving some links for posterity

c := &http.Client{
        // Skip TLS Dial
        Transport: &http2.Transport{
           AllowHTTP: true,
           DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) {
              return net.Dial(netw, addr)
           },
        },
}

And links:

huangapple
  • 本文由 发表于 2022年11月8日 22:49:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/74362684.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定