即使强制尝试设置为 false,Go http 请求也会回落到 http2

Go http request falls back to http2 even when force attempt is set to false

在 Go 的 http 包抛出以下错误的情况下,每隔几个请求就会发生这种奇怪的事情:

http2: server sent GOAWAY and closed the connection; LastStreamID=19999, ErrCode=NO_ERROR, debug=""

所以我意识到默认传输已将 ForceAttemptHTTP2 设置为 truehttps://golang.org/src/net/http/transport.go 第 48 行),因此我手动将其设置为 false,如下所示:

    transport := &http.Transport{
        ForceAttemptHTTP2: false,
    }
    httpClient := &http.Client{Transport: transport}

但即使这样做之后,我仍然得到相同的 http2 错误而不是 http1,这对我来说没有意义?

我是网络新手,所以我觉得我遗漏了一些应该很明显的东西?

我想问题是如何强制 http 包只使用 http 而不是 http2

这似乎可以做到:

package main

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

func main() {
   client := &http.Client{
      Transport: &http.Transport{
         TLSNextProto: map[string]func(string, *tls.Conn)http.RoundTripper{},
      },
   }
   req, e := http.NewRequest("HEAD", "https://whosebug.com", nil)
   if e != nil {
      panic(e)
   }
   res, e := client.Do(req)
   if e != nil {
      panic(e)
   }
   println(res.Proto == "HTTP/1.1")
}

Programs that must disable HTTP/2 can do so by setting Transport.TLSNextProto (for clients) or Server.TLSNextProto (for servers) to a non-nil, empty map.

https://golang.org/pkg/net/http#pkg-overview

不可否认,这是一种非常笨拙的语法,因此您可能更喜欢类似 改为:

package main

import (
   "net/http"
   "os"
)

func main() {
   os.Setenv("GODEBUG", "http2client=0")
   req, e := http.NewRequest("HEAD", "https://whosebug.com", nil)
   if e != nil {
      panic(e)
   }
   res, e := new(http.Client).Do(req)
   if e != nil {
      panic(e)
   }
   println(res.Proto == "HTTP/1.1")
}