といっても
ほぼ、curl のページをなぞっただけですが……。
https://github.com/curl/curl/blob/master/docs/HTTP3.md
※ Docker 使えます
その前に。
Docker でお手軽に試せます。
https://hub.docker.com/r/keioni/curl-http3
docker run --rm keioni/curl-http3 curl -v -L -s --http3 https://quic.tech:8443
HTTP/3 に対応させた nginx もあるので、併せて使えば HTTP/3 のテストが簡単にできます。
build
ここでは、nghttp3 + ngtcp2 版 と quiche 版 の二つを紹介します。
現時点(2020年7月27日現在)では、どちらがいいとか悪いとかはない、と感じています1。
quiche2 は、CDNプロバイダの Cloudflare が作った実装で、エッジサーバで実際に使っているそうです。
nghttp3, ngtcp2 は、あまり詳しくないのですが、HTTP/2 の実装である nghttp2 に携わった方々によって作られている、もののようです。(違っていたらごめんなさい)
build するにあたっても、
- quiche 版 は手順は少ないですが、BoringSSL や cargo のような、人によっては不慣れでトラブルに対応するのが難しいかもしれません
- nghttp3 + ngtcp2 版 は OpenSSL ですし、おなじみの make を使うので単純ですが、手順が少し増えます
ぐらいの違いしかないので、好みで選んでいいのではないかなーと思います。
nghttp3 + ngtcp2 版
パッケージのインストール
まず、git と、gcc などおなじみの build 用パッケージも入れます。環境によってはすでに入ってたりすると思いますが、参考までに Amazon Linux 2 の Docker イメージで私が入れたパッケージをリストアップしました。
yum install git unzip gcc gcc-c++ make autoconf automake libtool \
pkgconfig
次に、build 対象が依存している開発用パッケージもを入れます。
yum install CUnit-devel libev-devel libnghttp2-devel
その他、build する curl で通信の圧縮ができるように zlib も入れておくといいかなーと。
yum install zlib-devel
ビルド
URLは2020年7月20日時点の最新のものです。必要に応じて新しいものを確認してください。
インストール先は、ここでは /opt/http3
にします。
extern PREFIX="/opt/http3"
openssl (+ QUIC patch)
git clone --depth 1 -b OpenSSL_1_1_1g-quic-draft-29 https://github.com/tatsuhiro-t/openssl
cd openssl
./config --prefix=$PREFIX
make
make install_sw
nghttp3
git clone https://github.com/ngtcp2/nghttp3
cd nghttp3
autoreconf -i -v
./configure --prefix=$PREFIX --enable-lib-only
make
make install
ngtcp2
git clone https://github.com/ngtcp2/ngtcp2
cd ngtcp2
autoreconf -i -v
./configure --prefix=$PREFIX PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig
make
make install
curl
git clone https://github.com/curl/curl
cd curl
./buildconf
./configure \
LDFLAGS="-Wl,-rpath,$PREFIX/lib" \
PKG_CONFIG_PATH="$PREFIX/lib/pkgconfig" \
--prefix="$PREFIX" \
--enable-alt-svc
make
make install
確認
できあがりました。中身を確かめてみます。
# /opt/http3/bin/curl -V
curl 7.72.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.72.0-DEV OpenSSL/1.1.1g zlib/1.2.7 nghttp2/1.41.0 ngtcp2/0.1.0-DEV nghttp3/0.1.0-DEV
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets
ちゃんと nghttp3
と ngtcp2
を使ってますね。
quiche 版
パッケージのインストール
まず、Rust が入っていない場合は rustup などを使って入れます。
次に、git と、gcc などおなじみの build 用パッケージも入れます。環境によってはすでに入ってたりすると思いますが、参考までに Amazon Linux 2 の Docker イメージで私が入れたパッケージをリストアップしました。
yum install git gcc gcc-c++ make automake autoconf libtool pkgconfig cmake3
通信の圧縮を有効にするときは zlib-devel
を、HTTP/3 だけでなく HTTP/2 も有効にしたいときは libnghttp2-devel
も導入します。
yum install zlib-devel
yum install libnghttp2-devel
ビルド
cmake パッケージのバイナリが cmake3
になっている場合は cmake
にシンボリックリンクを張ります。
ln -s /usr/bin/cmake3 /usr/bin/cmake
quiche + BoringSSL
BoringSSL を含んだ quiche を build します。
以下は、先に示したURLの中身をまるまるコピーしただけです。
git clone --recursive https://github.com/cloudflare/quiche
cd quiche
cargo build --release --features pkg-config-meta,qlog
mkdir deps/boringssl/src/lib
ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) deps/boringssl/src/lib/
curl
curl 本体を build します。
cd ..
git clone https://github.com/curl/curl
cd curl
./buildconf
./configure \
LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" \
--prefix="/opt/http3" \
--with-ssl="$PWD/../quiche/deps/boringssl/src" \
--with-quiche="$PWD/../quiche/target/release" \
--enable-alt-svc
make
確認
できあがりました。中身を確かめてみます。
# /opt/http3/bin/curl -V
curl 7.72.0-DEV (x86_64-unknown-linux-gnu) libcurl/7.72.0-DEV BoringSSL zlib/1.2.7 nghttp2/1.41.0 quiche/0.5.1
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS HTTP2 HTTP3 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL UnixSockets
quiche
が使われていることが分かります。
実行
実際に動作を試してみましょう。
/opt/http3/bin/curl -v --http3 https://quic.tech:8443
nghttp3 + ngtcp2 版と quiche 版では若干表示が違っています。
nghttp3 + ngtcp2 版
こんな感じになるはずです。
* Trying 45.77.96.66:8443...
* Connect socket 5 over QUIC to 45.77.96.66:8443
* Trying 2001:19f0:5:c21:5400:1ff:fe33:3b96:8443...
* Immediate connect fail for 2001:19f0:5:c21:5400:1ff:fe33:3b96: Cannot assign requested address
* QUIC handshake is completed
* Connected to quic.tech () port 8443 (#0)
* Using HTTP/3 Stream ID: 0 (easy handle 0xaaaa00)
> GET / HTTP/3
> Host: quic.tech:8443
> user-agent: curl/7.72.0-DEV
> accept: */*
>
< HTTP/3 200
< server: quiche
< content-length: 462
< priority:
<!DOCTYPE html>
<html>
<head>
:
(省略)
:
</head>
<body>
<div class="cont">
<img src="/quic.svg" />
</div>
</body>
</html>
* Connection #0 to host quic.tech left intact
quiche 版
quiche 版だとこんな感じです。
* Trying 45.77.96.66:8443...
* Sent QUIC client Initial, ALPN: h3-29,h3-28,h3-27
* Trying 2001:19f0:5:c21:5400:1ff:fe33:3b96:8443...
* Immediate connect fail for 2001:19f0:5:c21:5400:1ff:fe33:3b96: Cannot assign requested address
* Connected to quic.tech (45.77.96.66) port 8443 (#0)
* h3 [:method: GET]
* h3 [:path: /]
* h3 [:scheme: https]
* h3 [:authority: quic.tech:8443]
* h3 [user-agent: curl/7.72.0-DEV]
* h3 [accept: */*]
* Using HTTP/3 Stream ID: 0 (easy handle 0x23969d0)
> GET / HTTP/3
> Host: quic.tech:8443
> user-agent: curl/7.72.0-DEV
> accept: */*
>
< HTTP/3 200
< server: quiche
< content-length: 462
< priority:
<
<!DOCTYPE html>
<html>
<head>
:
(省略)
:
</head>
<body>
<div class="cont">
<img src="/quic.svg" />
</div>
</body>
</html>
* Connection #0 to host quic.tech left intact
リクエストの “GET / HTTP/3
” と、レスポンスの “HTTP/3 200
” が出ていれば成功です! いえい!
Alt-Svc
詳細は省きますが、Alternate service (Alt-Svc) にも対応しているので、その挙動を見るのにも使えます。
/opt/http3/bin/curl -v --alt-svc altsvc.cache https://quic.aiortc.org/
さいごに
HTTP/3 対応のサイトは2020年7月27日現在、ほとんどありません。
今この curl を使うとしたら、自分で HTTP/3 サーバを建てるときでしょう。というわけで、HTTP/3 対応の nginx を作る方法も書きました。よろしければぜひ。
あと、既存のテストサイトもあります。お手軽に試してみてくださいー!
https://bagder.github.io/HTTP3-test/
(あと、こっそり私のサイトも対応させています。いつ止めるか分からないですが……)