go - 是什么让 http.server 使用 HTTP/2?

标签 go tls1.2 http2 goroutine

我制作了两个 Go 程序,每个程序都尝试通过 TLS 向对方发送请求。换句话说,两个程序既充当客户端又充当服务器。但是,第一个客户端主机尝试使用 HTTP/1.1 连接到服务器主机,而服务器主机使用 HTTP/2 进行监听,这会导致错误。

程序A

client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: tlsConfig,
    },
}
mux := httprouter.New()
mux.GET("/test", test)
serverTLS := &http.Server{
    Addr:      "127.0.0.1:8081",
    Handler:   mux,
    TLSConfig: tlsConfig,
}

go func() {
    serverTLS.ListenAndServeTLS("", "")
}()

fmt.Println("test")
r, err := client.Get("https://127.0.0.1:8080/test")
if err != nil {
    log.Fatalln("Failed to connect testService over TLS : ", err)
}
defer r.Body.Close()
b, _ := ioutil.ReadAll(r.Body)
fmt.Println(string(b))

time.Sleep(time.Second * 15)

程序B

client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: tlsConfig,
    },
}

mux := httprouter.New()
mux.GET("/test", test)
serverTLS := &http.Server{
    Addr:      "127.0.0.1:8080",
    Handler:   mux,
    TLSConfig: tlsConfig,
}

go func() {
    serverTLS.ListenAndServeTLS("", "")
}()

time.Sleep(time.Second * 10)

r, err := client.Get("https://127.0.0.1:8081/test")
if err != nil {
    log.Fatalln("Failed to connect testService over TLS : ", err)
}
defer r.Body.Close()
b, _ := ioutil.ReadAll(r.Body)
fmt.Println(string(b))

来自程序B(服务器)的错误信息

http2: server: error reading preface from client 127.0.0.1:34854: bogus greeting "GET /test HTTP/1.1\r\nHost"

然后,为了指定错误,我通过将它们的工作限制在客户端或服务器中来缩短两个程序。

程序 A'(服务器)

//setup server
mux := httprouter.New()
mux.GET("/test", test)
serverTLS := &http.Server{
    Addr:      "127.0.0.1:8080",
    Handler:   mux,
    TLSConfig: tlsConfig,
}

go func() {
    serverTLS.ListenAndServeTLS("", "")
}()

time.Sleep(time.Second * 10)

程序 B'(客户端)

//setup client
client := &http.Client{
    Transport: &http.Transport{
        TLSClientConfig: tlsConfig,
    },
}

fmt.Println("test")
r, err := client.Get("https://127.0.0.1:8080/test")
if err != nil {
    log.Fatalln("Failed to connect testService over TLS : ", err)
}
defer r.Body.Close()
b, _ := ioutil.ReadAll(r.Body)
fmt.Println(string(b))

这一次,他们没有出错。两台主机之间的通信是通过 HTTP/1.1 完成的。 有人可以解释是什么改变了这种情况吗?是什么迫使程序 B 使用 HTTP/2?

最佳答案

根据 net/http :

Starting with Go 1.6, the http package has transparent support for the HTTP/2 protocol when using HTTPS. 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. Alternatively, the following GODEBUG environment variables are currently supported:

关于go - 是什么让 http.server 使用 HTTP/2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57318533/

相关文章:

Go-Sublime-build 配置

android - 如何确认 Android 应用程序和服务器是否确实使用 TLS 1.2

android - 从服务器获取支持的 TLS 版本

google-cloud-platform - 配置 Cloud Run on Anthos 以转发 HTTP2

go - 是否有从 ios 日志中出现的字符的术语,如 `\M-C\M-6` 或 `\134`

security - 如何为我的 golang 应用程序获取 SSL 证书?

bash - 在 PATH 中转到 bin,但 "go version"失败

certificate - 正在配置 TLS 证书。这最多可能需要 15 分钟才能完成

nginx - HTTP2和NGINX-什么时候使用keepalive指令?

在 URL 查询参数中使用某些字符时出现 Java 9 HttpClient 异常