go http2 开发

开发使用的https证书

https证书对开发人员不是很友好,安装开发环境的证书都相对麻烦了点。这边介绍一个小工具mkcert

安装 mkcert

本文以Ubuntu和Debian系统为例:

  • 安装依赖 sudo apt install libnss3-tools
  • 下载mkcert
  • 生产证书./mkcert -key-file key.pem -cert-file cert.pem example.com *.example.com localhost 127.0.0.1 ::1
  • 添加本地信任 mkcert -install

golang http2

go 官方的http2包在拓展网络库中,使用起来标准库中的http没啥区别。需要主要的是http2的包同时支持http2和http1当发现client端不支持http2的时候会使用http1。

我们新建一个项目http2test,同时把上面生成的cert.pemkey.pem拷贝到目录下面

$ tree
.
├── cert.pem
├── go.mod
├── go.sum
├── key.pem
└── main.go
package main

import (
	"log"
	"net/http"
	"time"

	"golang.org/x/net/http2"
)

const idleTimeout = 5 * time.Minute
const activeTimeout = 10 * time.Minute

func main() {
	var srv http.Server
	//http2.VerboseLogs = true
	srv.Addr = ":8972"
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello http2"))
	})
	http2.ConfigureServer(&srv, &http2.Server{})
	log.Fatal(srv.ListenAndServeTLS("cert.pem", "key.pem"))
}

运行程序

$ go run main.go

然后用chrome浏览器可以正常浏览 https://localhost:8972/

我们使用curl工具测试下http2和http1 client的情况:

$ curl --http2 https://localhost:8972/ -v
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8972 (#0)
...
> GET / HTTP/2
> Host: localhost:8972
> User-Agent: curl/7.60.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200 
< content-type: text/plain; charset=utf-8
< content-length: 11
< date: Thu, 12 Dec 2019 11:13:26 GMT
< 
* Connection #0 to host localhost left intact
hello http2

我们看到使用http2协议返回正常。

我们在看下使用http1的情况:

$curl  --http1.1 https://localhost:8972/ -v
*   Trying 127.0.0.1...
...
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: O=mkcert development certificate; OU=wida@wida
*  start date: Jun  1 00:00:00 2019 GMT
*  expire date: Dec 12 10:47:26 2029 GMT
*  subjectAltName: host "localhost" matched cert's "localhost"
*  issuer: O=mkcert development CA; OU=wida@wida; CN=mkcert wida@wida
*  SSL certificate verify ok.
> GET / HTTP/1.1
> Host: localhost:8972
> User-Agent: curl/7.60.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Thu, 12 Dec 2019 11:56:46 GMT
< Content-Length: 11
< Content-Type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
hello http2

正常返回内容hello http2但是我们看到的是走的http1.1的协议。