HTTP/3 是在 QUIC 基础上发展出来的,并于 2019 年发布。QUIC 存在两个版本,早期 Google 打头阵的 QUIC 称之为 gQUIC,IETF 标准化后称之为 IQUIC。gQUIC 使用 UDP 进行数据传输,但上层仍然使用HTTP/2, HTTP/2 与 UDP 之前存在一个 QUIC 层,TLS 加密过程在此层处理;而 IQUIC,直接将 TLS 集成到 QUIC 内部。
之前我写了QUIC相关文章,具体见如下链接:
【技术】QUIC的那些事 | QUIC为什么那么快
【技术】QUIC的那些事 | 包类型及格式
【技术】QUIC的那些事 | 帧类型及格式
【技术】QUIC的那些事 | 拥塞控制
当前主流的浏览器已经支持了HTTP/3,主流浏览器如何开启 HTTP/3见如下网站:
https://developers.cloudflare.com/http3/intro/
对于 Firefox
1. 更新浏览器,我当前版本是:
2. 在浏览器网址框输入:about:config,在弹出的界面中输入:network.http.http3.enabled,并使能
对于Chrome
切换到Chrome的安装目录,在此目录下通过命令行参数启动Chrome:
chrome.exe --enable-quic --quic-version=h3-25
可以通过 curl 体验如何使用 HTTP/3:
https://github.com/curl/curl/blob/master/docs/HTTP3.md#quiche-version
上述链接介绍了两种方式:ngtcp2以及quiche,下面进行一一介绍。
ngtcp2
编译ngtcp2也有两种方式,一是使用OpenSSL,一是使用GnuTLS。
OpenSSL方式
1. 编译OpenSSL
% git clone --depth 1 -b OpenSSL_1_1_1d-quic-draft-27 https://github.com/tatsuhiro-t/openssl% cd openssl% ./config enable-tls1_3 --prefix=% make% make install_sw
2. 编译nghttp3
% cd ..% git clone https://github.com/ngtcp2/nghttp3% cd nghttp3% autoreconf -i% ./configure --prefix= --enable-lib-only% make% make install
3. 编译ngtcp2
% cd ..% git clone https://github.com/ngtcp2/ngtcp2% cd ngtcp2% autoreconf -i% ./configure PKG_CONFIG_PATH=/lib/pkgconfig:/lib/pkgconfig LDFLAGS="-Wl,-rpath,/lib" --prefix=% make% make install
4. 编译curl
% cd ..% git clone https://github.com/curl/curl% cd curl% ./buildconf% LDFLAGS="-Wl,-rpath,/lib" ./configure --with-ssl= --with-nghttp3= --with-ngtcp2= --enable-alt-svc% make
使用GnuTLS
1. 编译GnuTLS
% git clone --depth 1 -b tmp-quic https://gitlab.com/gnutls/gnutls.git% cd gnutls% ./bootstrap% ./configure --disable-doc --prefix=% make% make install
2. 编译nghttp3
同OpenSSL方式
3. 编译ngtcp2
同OpenSSL方式
4. 编译curl
% cd ..% git clone https://github.com/curl/curl% cd curl% ./buildconf% ./configure --without-ssl --with-gnutls= --with-nghttp3= --with-ngtcp2= --enable-alt-svc% make
Quiche
1. 下载代码
% git clone --recursive https://github.com/cloudflare/quiche
2. 编译BoringSSL
% cd quiche/deps/boringssl% mkdir build% cd build% cmake -DCMAKE_POSITION_INDEPENDENT_CODE=on ..% make% cd ..% mkdir -p .openssl/lib% cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib% ln -s $PWD/include .openssl
3. 编译quiche
% cd ../..% QUICHE_BSSL_PATH=$PWD/deps/boringssl cargo build --release --features pkg-config-meta,qlog
4. 编译curl
% cd ..% git clone https://github.com/curl/curl% cd curl% ./buildconf% ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/.openssl --with-quiche=$PWD/../quiche/target/release --enable-alt-svc% make
我基于quiche版本编译curl,跟着上述步骤操作,在执行如下命令后:
./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-ssl=$PWD/../quiche/deps/boringssl/.openssl --with-quiche=$PWD/../quiche/target/release --enable-alt-svc
输出中有如下信息:
HTTP3: enabled (quiche)
同时有如下警告:
WARNING: HTTP3 alt-svc enabled but marked EXPERIMENTAL. Use with caution!
待编译完成,迫不及待进行操作,输入如下命令:
curl --http3 https://cloudflare-quic.com
却告诉我如下信息:
curl: option --http3: is unknown
按照步骤执行,不应该出错啊,难道 Github 上的大佬们会骗我?我仔细阅读编译说明,其中有如下的话:HTTP/3 and QUIC support in curl is considered EXPERIMENTAL until further notice. It needs to be enabled at build-time. 我一度怀疑是没有开启使能,然后看脚本,修改编译指令,加入 HTTP/3 的使能,发现输出没有变化,尝试很多方式解决这个问题,都无效。
备注:--enable-alt-svc 已经使能了HTTP/3
后来,删除系统本来就有的 curl:
apt-get remove curl
重新安装,然后发现找不到curl,看了脚本,发现默认安装位置为:/usr/local/bin,设置环境变量:
export PATH=/usr/local/bin:$PATH
运行,报错:
curl: undefined symbol: curl_multi_poll
curl_multi_poll 是 libcurl 库中的符号,默认安装在 /usr/local/lib 目录下,于是设置库加载路径:
export LD_LIBRARY_PATH=/usr/local/lib/
输入如下命令查看curl是否安装成功以及是否支持HTTP/3:
curl --help | grep http3
输出结果如下:
--http3 Use HTTP v3
OK,curl 安装成功,也支持 HTTP/3 了。
输入如下命令访问支持HTTP/3的网站:
curl -v --http3 https://quic.rocks:4433/
输出如下:
输出显示,确实已经走了 HTTP/3 的流程。
在Firefox浏览器中输入about:config ,然后输入:network.http.http3.enabled ,并使能,重启浏览器。
在 Firefox 浏览器中访问 https://quic.rocks:4433/,并通过 Wireshark 抓包:
对于普通的HTTPS,应该是TCP,但是这里抓的包却是UDP,从这里可以看出走的是HTTP/3。由于Wireshark不支持HTTP/3,因此不能解析出具体的交互协议信息。
浏览器界面:
关闭Firefox的HTTP/3使能,通过Firefox访问上述网站,通过Wireshark抓包,输出如下:
发现是HTTPS:HTTP1.1+TLS1.3, 浏览器界面也显示了这个信息:
那么如何查看网站是否支持HTTP/3呢,可以在如下网站进行查询:
https://www.http3check.net/
用于测试HTTP/3协议的服务器信息见如下网站:
https://bagder.github.io/HTTP3-test/
扩展阅读
1. https://http3.net/
2. https://kinsta.com/blog/http3/
3. https://github.com/curl/curl
4. https://http3-explained.haxx.se
5. https://ietf.org/blog/whats-happening-quic/
6. https://en.wikipedia.org/wiki/QUIC