我制作了两个 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/