🎉

【Go】quic-go/http3 で HTTP/3 サーバーを立てる

2024/05/05に公開

quic-go/http3 は Caddy や FrankenPHP で採用されている HTTP/3 モジュールである。asdf で導入した Go 1.22 で動作確認をした。

まず go mod でプロジェクトをつくる。

mkdir myproject
cd myproject
go mod init myproject

サーバーのプログラムを用意する

server.go
package main
// https://future-architect.github.io/articles/20230927a/

import (
   "fmt"
   "log"
   "net/http"
   "github.com/quic-go/quic-go/http3"
)

func main() {
   mux := http.NewServeMux()
   mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
       fmt.Fprintf(w, "Hello, %s\n", r.Proto)
   })

   log.Println("start at https://localhost:5000")
   log.Println(http3.ListenAndServe("0.0.0.0:5000", "localhost.pem", "localhost-key.pem", mux))
}

SSL/TLS 証明書ファイルは mkcert で生成した

mkcert localhost

モジュールをダウンロードする

go mod tidy

サーバーを起動させる

go run server.go

Chromebook の Chrome ブラウザーでアクセスしたところ HTTP/2 で接続となった。HTTP/3 対応の curl で GET リクエストを送ると次のようなログが表示される

./curl --http3 -v https://localhost:8443
* Host localhost:8443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* Server certificate:
*  subject: O=mkcert development certificate; OU=masakielastic@penguin
*  start date: May  4 22:46:47 2024 GMT
*  expire date: Aug  4 22:46:47 2026 GMT
*  subjectAltName: host "localhost" matched cert's "localhost"
*  issuer: O=mkcert development CA; OU=masakielastic@penguin; CN=mkcert masakielastic@penguin
*  SSL certificate verify ok.
*   Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 1: Public key type RSA (3072/128 Bits/secBits), signed using sha256WithRSAEncryption
* Connected to localhost (::1) port 8443
* using HTTP/3
* [HTTP/3] [0] OPENED stream for https://localhost:8443/
* [HTTP/3] [0] [:method: GET]
* [HTTP/3] [0] [:scheme: https]
* [HTTP/3] [0] [:authority: localhost:8443]
* [HTTP/3] [0] [:path: /]
* [HTTP/3] [0] [user-agent: curl/8.8.0-DEV]
* [HTTP/3] [0] [accept: */*]
> GET / HTTP/3
> Host: localhost:8443
> User-Agent: curl/8.8.0-DEV
> Accept: */*
> 
* Request completely sent off
< HTTP/3 200 
< date: Sat, 04 May 2024 22:53:53 GMT
< content-length: 15
< content-type: text/plain; charset=utf-8
< 
* Connection #0 to host localhost left intact
Hello, 

Discussion