Go语言打造HTTP/2服务:一步步指南
发表时间: 2024-05-20 17:51
整个golang实现http2服务的步骤
HTTP/2强制使用TLS。为了实现这一点, 我们首先需要一个私钥和一个证书。
1 生成公钥私钥文件
openssl req -newkey rsa:2048 -nodes -keyout private.pem -x509 -days 365 -out certificate.pem
private.pem:服务端私钥
certificate.pem:证书文件
2 实现server端代码如下:
package mainimport ( "fmt" "log" "net/http" "os" "path" "time" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c")func main() { currentPath, _ := os.Getwd() handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello world") fmt.Fprintf(w, "Protocol: %s\n", r.Proto) }) h2s := &http2.Server{ IdleTimeout: 60 * time.Second, } h1s := &http.Server{ Addr: ":8080", Handler: h2c.NewHandler(handler, h2s), } // path.Join() 方法能够兼容不同的操作系统 log.Fatal(h1s.ListenAndServeTLS(path.Join(currentPath, "certificate.pem"), path.Join(currentPath, "private.pem")))}
3 实现客户端代码如下:
package mainimport ( "crypto/tls" "crypto/x509" "fmt" "io/ioutil" "log" "net/http" "os" "path" "time" "golang.org/x/net/http2")var url = "https://localhost:8080"func main() { requestByHttp2()}// 几种请求方式// HTTP2请求方式func requestByHttp2() { currentPath, _ := os.Getwd() client := &http.Client{ Timeout: 100 * time.Millisecond, } //读取证书文件,正式环境无读取证书文件,因为本地测试是无法认证证书 caCert, err := ioutil.ReadFile(path.Join(currentPath, "certificate.pem")) if err != nil { log.Fatalf("Reading server certificate: %s", err) return } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) //tls协议配置,InsecureSkipVerify认证证书是否跳过 tlsConfig := &tls.Config{ RootCAs: caCertPool, //设置安全跳跃认证 InsecureSkipVerify: true, } client.Transport = &http2.Transport{ TLSClientConfig: tlsConfig, } resp, err := client.Get(url) if err != nil { fmt.Printf("Failed get: err:%s \n", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Failed reading response body: %s\n", err) return } fmt.Printf("Get requestByHttp2 response %d: %s %s\n", resp.StatusCode, resp.Proto, string(body))}//普通的HTTP请求func requestByHTTP() { //http1 _, err := http.Get(url) fmt.Println(err)}// HTTP + SSL 证书请求func requestByHTTPSSL() { currentPath, _ := os.Getwd() client := &http.Client{} //证书文件 caCert, err := ioutil.ReadFile(path.Join(currentPath, "certificate.pem")) if err != nil { log.Fatalf("Reading server certificate: %s", err) return } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) // Create TLS configuration with the certificate of the server tlsConfig := &tls.Config{ RootCAs: caCertPool, //设置安全跳跃认证 InsecureSkipVerify: true, } client.Transport = &http.Transport{ TLSClientConfig: tlsConfig, } resp, err := client.Get(url) if err != nil { log.Fatalf("Failed get: %s", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatalf("Failed reading response body: %s", err) return } fmt.Printf("Get response %d: %s %s\n", resp.StatusCode, resp.Proto, string(body))}
> # go run server.go> # go run client.goGet requestByHttp2 response 200: HTTP/2.0 Hello worldProtocol: HTTP/2.0
问题总结:
报错: x509: certificate is not valid for any names, but wanted to match localhost
原因: 是http2请求安全认证不过, 通过设置如下参数来实现:
//设置安全跳跃认证
InsecureSkipVerify: true,