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

Cha*_*tya 5 http go http2

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

http2: server sent GOAWAY and closed the connection; LastStreamID=19999, ErrCode=NO_ERROR, debug=""
Run Code Online (Sandbox Code Playgroud)

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

    transport := &http.Transport{
        ForceAttemptHTTP2: false,
    }
    httpClient := &http.Client{Transport: transport}
Run Code Online (Sandbox Code Playgroud)

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

我是网络新手,所以我感觉我错过了一些在这里应该很明显的东西?

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

小智 6

这似乎可以做到:

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://stackoverflow.com", nil)
   if e != nil {
      panic(e)
   }
   res, e := client.Do(req)
   if e != nil {
      panic(e)
   }
   println(res.Proto == "HTTP/1.1")
}
Run Code Online (Sandbox Code Playgroud)

Transport.TLSNextProto 必须禁用 HTTP/2 的程序可以通过将(对于客户端)或Server.TLSNextProto(对于服务器)设置为非零的空映射来实现。

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://stackoverflow.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")
}
Run Code Online (Sandbox Code Playgroud)