113498266Sopenharmony_ci# HTTP3 (and QUIC) 213498266Sopenharmony_ci 313498266Sopenharmony_ci## Resources 413498266Sopenharmony_ci 513498266Sopenharmony_ci[HTTP/3 Explained](https://http3-explained.haxx.se/en/) - the online free 613498266Sopenharmony_cibook describing the protocols involved. 713498266Sopenharmony_ci 813498266Sopenharmony_ci[quicwg.org](https://quicwg.org/) - home of the official protocol drafts 913498266Sopenharmony_ci 1013498266Sopenharmony_ci## QUIC libraries 1113498266Sopenharmony_ci 1213498266Sopenharmony_ciQUIC libraries we are using: 1313498266Sopenharmony_ci 1413498266Sopenharmony_ci[ngtcp2](https://github.com/ngtcp2/ngtcp2) 1513498266Sopenharmony_ci 1613498266Sopenharmony_ci[quiche](https://github.com/cloudflare/quiche) - **EXPERIMENTAL** 1713498266Sopenharmony_ci 1813498266Sopenharmony_ci[OpenSSL 3.2+ QUIC](https://github.com/openssl/openssl) - **EXPERIMENTAL** 1913498266Sopenharmony_ci 2013498266Sopenharmony_ci[msh3](https://github.com/nibanks/msh3) (with [msquic](https://github.com/microsoft/msquic)) - **EXPERIMENTAL** 2113498266Sopenharmony_ci 2213498266Sopenharmony_ci## Experimental 2313498266Sopenharmony_ci 2413498266Sopenharmony_ciHTTP/3 support in curl is considered **EXPERIMENTAL** until further notice 2513498266Sopenharmony_ciwhen built to use *quiche* or *msh3*. Only the *ngtcp2* backend is not 2613498266Sopenharmony_ciexperimental. 2713498266Sopenharmony_ci 2813498266Sopenharmony_ciFurther development and tweaking of the HTTP/3 support in curl will happen in 2913498266Sopenharmony_cithe master branch using pull-requests, just like ordinary changes. 3013498266Sopenharmony_ci 3113498266Sopenharmony_ciTo fix before we remove the experimental label: 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci - the used QUIC library needs to consider itself non-beta 3413498266Sopenharmony_ci - it is fine to "leave" individual backends as experimental if necessary 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci# ngtcp2 version 3713498266Sopenharmony_ci 3813498266Sopenharmony_ciBuilding curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3` and a QUIC supporting TLS library. The supported TLS libraries are covered below. 3913498266Sopenharmony_ci 4013498266Sopenharmony_ci * `ngtcp2`: v1.2.0 4113498266Sopenharmony_ci * `nghttp3`: v1.1.0 4213498266Sopenharmony_ci 4313498266Sopenharmony_ci## Build with quictls 4413498266Sopenharmony_ci 4513498266Sopenharmony_ciOpenSSL does not offer the required APIs for building a QUIC client. You need 4613498266Sopenharmony_cito use a TLS library that has such APIs and that works with *ngtcp2*. 4713498266Sopenharmony_ci 4813498266Sopenharmony_ciBuild quictls 4913498266Sopenharmony_ci 5013498266Sopenharmony_ci % git clone --depth 1 -b openssl-3.1.4+quic https://github.com/quictls/openssl 5113498266Sopenharmony_ci % cd openssl 5213498266Sopenharmony_ci % ./config enable-tls1_3 --prefix=<somewhere1> 5313498266Sopenharmony_ci % make 5413498266Sopenharmony_ci % make install 5513498266Sopenharmony_ci 5613498266Sopenharmony_ciBuild nghttp3 5713498266Sopenharmony_ci 5813498266Sopenharmony_ci % cd .. 5913498266Sopenharmony_ci % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 6013498266Sopenharmony_ci % cd nghttp3 6113498266Sopenharmony_ci % autoreconf -fi 6213498266Sopenharmony_ci % ./configure --prefix=<somewhere2> --enable-lib-only 6313498266Sopenharmony_ci % make 6413498266Sopenharmony_ci % make install 6513498266Sopenharmony_ci 6613498266Sopenharmony_ciBuild ngtcp2 6713498266Sopenharmony_ci 6813498266Sopenharmony_ci % cd .. 6913498266Sopenharmony_ci % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 7013498266Sopenharmony_ci % cd ngtcp2 7113498266Sopenharmony_ci % autoreconf -fi 7213498266Sopenharmony_ci % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3> --enable-lib-only 7313498266Sopenharmony_ci % make 7413498266Sopenharmony_ci % make install 7513498266Sopenharmony_ci 7613498266Sopenharmony_ciBuild curl 7713498266Sopenharmony_ci 7813498266Sopenharmony_ci % cd .. 7913498266Sopenharmony_ci % git clone https://github.com/curl/curl 8013498266Sopenharmony_ci % cd curl 8113498266Sopenharmony_ci % autoreconf -fi 8213498266Sopenharmony_ci % LDFLAGS="-Wl,-rpath,<somewhere1>/lib" ./configure --with-openssl=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> 8313498266Sopenharmony_ci % make 8413498266Sopenharmony_ci % make install 8513498266Sopenharmony_ci 8613498266Sopenharmony_ciFor OpenSSL 3.0.0 or later builds on Linux for x86_64 architecture, substitute all occurrences of "/lib" with "/lib64" 8713498266Sopenharmony_ci 8813498266Sopenharmony_ci## Build with GnuTLS 8913498266Sopenharmony_ci 9013498266Sopenharmony_ciBuild GnuTLS 9113498266Sopenharmony_ci 9213498266Sopenharmony_ci % git clone --depth 1 https://gitlab.com/gnutls/gnutls.git 9313498266Sopenharmony_ci % cd gnutls 9413498266Sopenharmony_ci % ./bootstrap 9513498266Sopenharmony_ci % ./configure --prefix=<somewhere1> 9613498266Sopenharmony_ci % make 9713498266Sopenharmony_ci % make install 9813498266Sopenharmony_ci 9913498266Sopenharmony_ciBuild nghttp3 10013498266Sopenharmony_ci 10113498266Sopenharmony_ci % cd .. 10213498266Sopenharmony_ci % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 10313498266Sopenharmony_ci % cd nghttp3 10413498266Sopenharmony_ci % autoreconf -fi 10513498266Sopenharmony_ci % ./configure --prefix=<somewhere2> --enable-lib-only 10613498266Sopenharmony_ci % make 10713498266Sopenharmony_ci % make install 10813498266Sopenharmony_ci 10913498266Sopenharmony_ciBuild ngtcp2 11013498266Sopenharmony_ci 11113498266Sopenharmony_ci % cd .. 11213498266Sopenharmony_ci % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 11313498266Sopenharmony_ci % cd ngtcp2 11413498266Sopenharmony_ci % autoreconf -fi 11513498266Sopenharmony_ci % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3> --enable-lib-only --with-gnutls 11613498266Sopenharmony_ci % make 11713498266Sopenharmony_ci % make install 11813498266Sopenharmony_ci 11913498266Sopenharmony_ciBuild curl 12013498266Sopenharmony_ci 12113498266Sopenharmony_ci % cd .. 12213498266Sopenharmony_ci % git clone https://github.com/curl/curl 12313498266Sopenharmony_ci % cd curl 12413498266Sopenharmony_ci % autoreconf -fi 12513498266Sopenharmony_ci % ./configure --with-gnutls=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> 12613498266Sopenharmony_ci % make 12713498266Sopenharmony_ci % make install 12813498266Sopenharmony_ci 12913498266Sopenharmony_ci## Build with wolfSSL 13013498266Sopenharmony_ci 13113498266Sopenharmony_ciBuild wolfSSL 13213498266Sopenharmony_ci 13313498266Sopenharmony_ci % git clone https://github.com/wolfSSL/wolfssl.git 13413498266Sopenharmony_ci % cd wolfssl 13513498266Sopenharmony_ci % autoreconf -fi 13613498266Sopenharmony_ci % ./configure --prefix=<somewhere1> --enable-quic --enable-session-ticket --enable-earlydata --enable-psk --enable-harden --enable-altcertchains 13713498266Sopenharmony_ci % make 13813498266Sopenharmony_ci % make install 13913498266Sopenharmony_ci 14013498266Sopenharmony_ciBuild nghttp3 14113498266Sopenharmony_ci 14213498266Sopenharmony_ci % cd .. 14313498266Sopenharmony_ci % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 14413498266Sopenharmony_ci % cd nghttp3 14513498266Sopenharmony_ci % autoreconf -fi 14613498266Sopenharmony_ci % ./configure --prefix=<somewhere2> --enable-lib-only 14713498266Sopenharmony_ci % make 14813498266Sopenharmony_ci % make install 14913498266Sopenharmony_ci 15013498266Sopenharmony_ciBuild ngtcp2 15113498266Sopenharmony_ci 15213498266Sopenharmony_ci % cd .. 15313498266Sopenharmony_ci % git clone -b v1.2.0 https://github.com/ngtcp2/ngtcp2 15413498266Sopenharmony_ci % cd ngtcp2 15513498266Sopenharmony_ci % autoreconf -fi 15613498266Sopenharmony_ci % ./configure PKG_CONFIG_PATH=<somewhere1>/lib/pkgconfig:<somewhere2>/lib/pkgconfig LDFLAGS="-Wl,-rpath,<somewhere1>/lib" --prefix=<somewhere3> --enable-lib-only --with-wolfssl 15713498266Sopenharmony_ci % make 15813498266Sopenharmony_ci % make install 15913498266Sopenharmony_ci 16013498266Sopenharmony_ciBuild curl 16113498266Sopenharmony_ci 16213498266Sopenharmony_ci % cd .. 16313498266Sopenharmony_ci % git clone https://github.com/curl/curl 16413498266Sopenharmony_ci % cd curl 16513498266Sopenharmony_ci % autoreconf -fi 16613498266Sopenharmony_ci % ./configure --with-wolfssl=<somewhere1> --with-nghttp3=<somewhere2> --with-ngtcp2=<somewhere3> 16713498266Sopenharmony_ci % make 16813498266Sopenharmony_ci % make install 16913498266Sopenharmony_ci 17013498266Sopenharmony_ci# quiche version 17113498266Sopenharmony_ci 17213498266Sopenharmony_ciquiche support is **EXPERIMENTAL** 17313498266Sopenharmony_ci 17413498266Sopenharmony_ciSince the quiche build manages its dependencies, curl can be built against the latest version. You are *probably* able to build against their main branch, but in case of problems, we recommend their latest release tag. 17513498266Sopenharmony_ci 17613498266Sopenharmony_ci## build 17713498266Sopenharmony_ci 17813498266Sopenharmony_ciBuild quiche and BoringSSL: 17913498266Sopenharmony_ci 18013498266Sopenharmony_ci % git clone --recursive -b 0.20.0 https://github.com/cloudflare/quiche 18113498266Sopenharmony_ci % cd quiche 18213498266Sopenharmony_ci % cargo build --package quiche --release --features ffi,pkg-config-meta,qlog 18313498266Sopenharmony_ci % mkdir quiche/deps/boringssl/src/lib 18413498266Sopenharmony_ci % ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) quiche/deps/boringssl/src/lib/ 18513498266Sopenharmony_ci 18613498266Sopenharmony_ciBuild curl: 18713498266Sopenharmony_ci 18813498266Sopenharmony_ci % cd .. 18913498266Sopenharmony_ci % git clone https://github.com/curl/curl 19013498266Sopenharmony_ci % cd curl 19113498266Sopenharmony_ci % autoreconf -fi 19213498266Sopenharmony_ci % ./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-openssl=$PWD/../quiche/quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release 19313498266Sopenharmony_ci % make 19413498266Sopenharmony_ci % make install 19513498266Sopenharmony_ci 19613498266Sopenharmony_ci If `make install` results in `Permission denied` error, you will need to prepend it with `sudo`. 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci# OpenSSL version 19913498266Sopenharmony_ci 20013498266Sopenharmony_ciquiche QUIC support is **EXPERIMENTAL** 20113498266Sopenharmony_ci 20213498266Sopenharmony_ciBuild OpenSSL 3.2.0 20313498266Sopenharmony_ci 20413498266Sopenharmony_ci % cd .. 20513498266Sopenharmony_ci % git clone -b openssl-3.2.0 https://github.com/openssl/openssl 20613498266Sopenharmony_ci % cd openssl 20713498266Sopenharmony_ci % ./config enable-tls1_3 --prefix=<somewhere> --libdir=<somewhere>/lib 20813498266Sopenharmony_ci % make install 20913498266Sopenharmony_ci 21013498266Sopenharmony_ciBuild nghttp3 21113498266Sopenharmony_ci 21213498266Sopenharmony_ci % cd .. 21313498266Sopenharmony_ci % git clone -b v1.1.0 https://github.com/ngtcp2/nghttp3 21413498266Sopenharmony_ci % cd nghttp3 21513498266Sopenharmony_ci % autoreconf -fi 21613498266Sopenharmony_ci % ./configure --prefix=<somewhere2> --enable-lib-only 21713498266Sopenharmony_ci % make 21813498266Sopenharmony_ci % make install 21913498266Sopenharmony_ci 22013498266Sopenharmony_ciBuild curl: 22113498266Sopenharmony_ci 22213498266Sopenharmony_ci % cd .. 22313498266Sopenharmony_ci % git clone https://github.com/curl/curl 22413498266Sopenharmony_ci % cd curl 22513498266Sopenharmony_ci % autoreconf -fi 22613498266Sopenharmony_ci % ./configure --with-openssl=<somewhere> --with-openssl-quic --with-nghttp3=<somewhere2> 22713498266Sopenharmony_ci % make 22813498266Sopenharmony_ci % make install 22913498266Sopenharmony_ci 23013498266Sopenharmony_ci If `make install` results in `Permission denied` error, you will need to prepend it with `sudo`. 23113498266Sopenharmony_ci 23213498266Sopenharmony_ci# msh3 (msquic) version 23313498266Sopenharmony_ci 23413498266Sopenharmony_ci**Note**: The msquic HTTP/3 backend is immature and is not properly functional 23513498266Sopenharmony_cione as of September 2023. Feel free to help us test it and improve it, but 23613498266Sopenharmony_cithere is no point in filing bugs about it just yet. 23713498266Sopenharmony_ci 23813498266Sopenharmony_cimsh3 support is **EXPERIMENTAL** 23913498266Sopenharmony_ci 24013498266Sopenharmony_ci## Build Linux (with quictls fork of OpenSSL) 24113498266Sopenharmony_ci 24213498266Sopenharmony_ciBuild msh3: 24313498266Sopenharmony_ci 24413498266Sopenharmony_ci % git clone -b v0.6.0 --depth 1 --recursive https://github.com/nibanks/msh3 24513498266Sopenharmony_ci % cd msh3 && mkdir build && cd build 24613498266Sopenharmony_ci % cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=RelWithDebInfo .. 24713498266Sopenharmony_ci % cmake --build . 24813498266Sopenharmony_ci % cmake --install . 24913498266Sopenharmony_ci 25013498266Sopenharmony_ciBuild curl: 25113498266Sopenharmony_ci 25213498266Sopenharmony_ci % git clone https://github.com/curl/curl 25313498266Sopenharmony_ci % cd curl 25413498266Sopenharmony_ci % autoreconf -fi 25513498266Sopenharmony_ci % ./configure LDFLAGS="-Wl,-rpath,/usr/local/lib" --with-msh3=/usr/local --with-openssl 25613498266Sopenharmony_ci % make 25713498266Sopenharmony_ci % make install 25813498266Sopenharmony_ci 25913498266Sopenharmony_ciRun from `/usr/local/bin/curl`. 26013498266Sopenharmony_ci 26113498266Sopenharmony_ci## Build Windows 26213498266Sopenharmony_ci 26313498266Sopenharmony_ciBuild msh3: 26413498266Sopenharmony_ci 26513498266Sopenharmony_ci % git clone -b v0.6.0 --depth 1 --recursive https://github.com/nibanks/msh3 26613498266Sopenharmony_ci % cd msh3 && mkdir build && cd build 26713498266Sopenharmony_ci % cmake -G 'Visual Studio 17 2022' -DCMAKE_BUILD_TYPE=RelWithDebInfo .. 26813498266Sopenharmony_ci % cmake --build . --config Release 26913498266Sopenharmony_ci % cmake --install . --config Release 27013498266Sopenharmony_ci 27113498266Sopenharmony_ci**Note** - On Windows, Schannel will be used for TLS support by default. If 27213498266Sopenharmony_ciyou with to use (the quictls fork of) OpenSSL, specify the 27313498266Sopenharmony_ci`-DQUIC_TLS=openssl` option to the generate command above. Also note that 27413498266Sopenharmony_ciOpenSSL brings with it an additional set of build dependencies not specified 27513498266Sopenharmony_cihere. 27613498266Sopenharmony_ci 27713498266Sopenharmony_ciBuild curl (in [Visual Studio Command 27813498266Sopenharmony_ciprompt](../winbuild/README.md#open-a-command-prompt)): 27913498266Sopenharmony_ci 28013498266Sopenharmony_ci % git clone https://github.com/curl/curl 28113498266Sopenharmony_ci % cd curl/winbuild 28213498266Sopenharmony_ci % nmake /f Makefile.vc mode=dll WITH_MSH3=dll MSH3_PATH="C:/Program Files/msh3" MACHINE=x64 28313498266Sopenharmony_ci 28413498266Sopenharmony_ci**Note** - If you encounter a build error with `tool_hugehelp.c` being 28513498266Sopenharmony_cimissing, rename `tool_hugehelp.c.cvs` in the same directory to 28613498266Sopenharmony_ci`tool_hugehelp.c` and then run `nmake` again. 28713498266Sopenharmony_ci 28813498266Sopenharmony_ciRun in the `C:/Program Files/msh3/lib` directory, copy `curl.exe` to that 28913498266Sopenharmony_cidirectory, or copy `msquic.dll` and `msh3.dll` from that directory to the 29013498266Sopenharmony_ci`curl.exe` directory. For example: 29113498266Sopenharmony_ci 29213498266Sopenharmony_ci % C:\Program Files\msh3\lib> F:\curl\builds\libcurl-vc-x64-release-dll-ipv6-sspi-schannel-msh3\bin\curl.exe --http3 https://curl.se/ 29313498266Sopenharmony_ci 29413498266Sopenharmony_ci# `--http3` 29513498266Sopenharmony_ci 29613498266Sopenharmony_ciUse only HTTP/3: 29713498266Sopenharmony_ci 29813498266Sopenharmony_ci curl --http3-only https://example.org:4433/ 29913498266Sopenharmony_ci 30013498266Sopenharmony_ciUse HTTP/3 with fallback to HTTP/2 or HTTP/1.1 (see "HTTPS eyeballing" below): 30113498266Sopenharmony_ci 30213498266Sopenharmony_ci curl --http3 https://example.org:4433/ 30313498266Sopenharmony_ci 30413498266Sopenharmony_ciUpgrade via Alt-Svc: 30513498266Sopenharmony_ci 30613498266Sopenharmony_ci curl --alt-svc altsvc.cache https://curl.se/ 30713498266Sopenharmony_ci 30813498266Sopenharmony_ciSee this [list of public HTTP/3 servers](https://bagder.github.io/HTTP3-test/) 30913498266Sopenharmony_ci 31013498266Sopenharmony_ci### HTTPS eyeballing 31113498266Sopenharmony_ci 31213498266Sopenharmony_ciWith option `--http3` curl will attempt earlier HTTP versions as well should 31313498266Sopenharmony_cithe connect attempt via HTTP/3 not succeed "fast enough". This strategy is 31413498266Sopenharmony_cisimilar to IPv4/6 happy eyeballing where the alternate address family is used 31513498266Sopenharmony_ciin parallel after a short delay. 31613498266Sopenharmony_ci 31713498266Sopenharmony_ciThe IPv4/6 eyeballing has a default of 200ms and you may override that via 31813498266Sopenharmony_ci`--happy-eyeballs-timeout-ms value`. Since HTTP/3 is still relatively new, we 31913498266Sopenharmony_cidecided to use this timeout also for the HTTP eyeballing - with a slight 32013498266Sopenharmony_citwist. 32113498266Sopenharmony_ci 32213498266Sopenharmony_ciThe `happy-eyeballs-timeout-ms` value is the **hard** timeout, meaning after 32313498266Sopenharmony_cithat time expired, a TLS connection is opened in addition to negotiate HTTP/2 32413498266Sopenharmony_cior HTTP/1.1. At half of that value - currently - is the **soft** timeout. The 32513498266Sopenharmony_cisoft timeout fires, when there has been **no data at all** seen from the 32613498266Sopenharmony_ciserver on the HTTP/3 connection. 32713498266Sopenharmony_ci 32813498266Sopenharmony_ciSo, without you specifying anything, the hard timeout is 200ms and the soft is 100ms: 32913498266Sopenharmony_ci 33013498266Sopenharmony_ci * Ideally, the whole QUIC handshake happens and curl has an HTTP/3 connection 33113498266Sopenharmony_ci in less than 100ms. 33213498266Sopenharmony_ci * When QUIC is not supported (or UDP does not work for this network path), no 33313498266Sopenharmony_ci reply is seen and the HTTP/2 TLS+TCP connection starts 100ms later. 33413498266Sopenharmony_ci * In the worst case, UDP replies start before 100ms, but drag on. This will 33513498266Sopenharmony_ci start the TLS+TCP connection after 200ms. 33613498266Sopenharmony_ci * When the QUIC handshake fails, the TLS+TCP connection is attempted right 33713498266Sopenharmony_ci away. For example, when the QUIC server presents the wrong certificate. 33813498266Sopenharmony_ci 33913498266Sopenharmony_ciThe whole transfer only fails, when **both** QUIC and TLS+TCP fail to 34013498266Sopenharmony_cihandshake or time out. 34113498266Sopenharmony_ci 34213498266Sopenharmony_ciNote that all this happens in addition to IP version happy eyeballing. If the 34313498266Sopenharmony_ciname resolution for the server gives more than one IP address, curl will try 34413498266Sopenharmony_ciall those until one succeeds - just as with all other protocols. If those IP 34513498266Sopenharmony_ciaddresses contain both IPv6 and IPv4, those attempts will happen, delayed, in 34613498266Sopenharmony_ciparallel (the actual eyeballing). 34713498266Sopenharmony_ci 34813498266Sopenharmony_ci## Known Bugs 34913498266Sopenharmony_ci 35013498266Sopenharmony_ciCheck out the [list of known HTTP3 bugs](https://curl.se/docs/knownbugs.html#HTTP3). 35113498266Sopenharmony_ci 35213498266Sopenharmony_ci# HTTP/3 Test server 35313498266Sopenharmony_ci 35413498266Sopenharmony_ciThis is not advice on how to run anything in production. This is for 35513498266Sopenharmony_cidevelopment and experimenting. 35613498266Sopenharmony_ci 35713498266Sopenharmony_ci## Prerequisite(s) 35813498266Sopenharmony_ci 35913498266Sopenharmony_ciAn existing local HTTP/1.1 server that hosts files. Preferably also a few huge 36013498266Sopenharmony_ciones. You can easily create huge local files like `truncate -s=8G 8GB` - they 36113498266Sopenharmony_ciare huge but do not occupy that much space on disk since they are just big 36213498266Sopenharmony_ciholes. 36313498266Sopenharmony_ci 36413498266Sopenharmony_ciIn a Debian setup you can install **apache2**. It runs on port 80 and has a 36513498266Sopenharmony_cidocument root in `/var/www/html`. Download the 8GB file from apache with `curl 36613498266Sopenharmony_cilocalhost/8GB -o dev/null` 36713498266Sopenharmony_ci 36813498266Sopenharmony_ciIn this description we setup and run an HTTP/3 reverse-proxy in front of the 36913498266Sopenharmony_ciHTTP/1 server. 37013498266Sopenharmony_ci 37113498266Sopenharmony_ci## Setup 37213498266Sopenharmony_ci 37313498266Sopenharmony_ciYou can select either or both of these server solutions. 37413498266Sopenharmony_ci 37513498266Sopenharmony_ci### nghttpx 37613498266Sopenharmony_ci 37713498266Sopenharmony_ciGet, build and install **quictls**, **nghttp3** and **ngtcp2** as described 37813498266Sopenharmony_ciabove. 37913498266Sopenharmony_ci 38013498266Sopenharmony_ciGet, build and install **nghttp2**: 38113498266Sopenharmony_ci 38213498266Sopenharmony_ci git clone https://github.com/nghttp2/nghttp2.git 38313498266Sopenharmony_ci cd nghttp2 38413498266Sopenharmony_ci autoreconf -fi 38513498266Sopenharmony_ci PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/daniel/build-quictls/lib/pkgconfig:/home/daniel/build-nghttp3/lib/pkgconfig:/home/daniel/build-ngtcp2/lib/pkgconfig LDFLAGS=-L/home/daniel/build-quictls/lib CFLAGS=-I/home/daniel/build-quictls/include ./configure --enable-maintainer-mode --prefix=/home/daniel/build-nghttp2 --disable-shared --enable-app --enable-http3 --without-jemalloc --without-libxml2 --without-systemd 38613498266Sopenharmony_ci make && make install 38713498266Sopenharmony_ci 38813498266Sopenharmony_ciRun the local h3 server on port 9443, make it proxy all traffic through to 38913498266Sopenharmony_ciHTTP/1 on localhost port 80. For local toying, we can just use the test cert 39013498266Sopenharmony_cithat exists in curl's test dir. 39113498266Sopenharmony_ci 39213498266Sopenharmony_ci CERT=$CURLSRC/tests/stunnel.pem 39313498266Sopenharmony_ci $HOME/bin/nghttpx $CERT $CERT --backend=localhost,80 \ 39413498266Sopenharmony_ci --frontend="localhost,9443;quic" 39513498266Sopenharmony_ci 39613498266Sopenharmony_ci### Caddy 39713498266Sopenharmony_ci 39813498266Sopenharmony_ci[Install Caddy](https://caddyserver.com/docs/install). For easiest use, the binary 39913498266Sopenharmony_cishould be either in your PATH or your current directory. 40013498266Sopenharmony_ci 40113498266Sopenharmony_ciCreate a `Caddyfile` with the following content: 40213498266Sopenharmony_ci~~~ 40313498266Sopenharmony_cilocalhost:7443 { 40413498266Sopenharmony_ci respond "Hello, world! you are using {http.request.proto}" 40513498266Sopenharmony_ci} 40613498266Sopenharmony_ci~~~ 40713498266Sopenharmony_ci 40813498266Sopenharmony_ciThen run Caddy: 40913498266Sopenharmony_ci 41013498266Sopenharmony_ci ./caddy start 41113498266Sopenharmony_ci 41213498266Sopenharmony_ciMaking requests to `https://localhost:7443` should tell you which protocol is being used. 41313498266Sopenharmony_ci 41413498266Sopenharmony_ciYou can change the hard-coded response to something more useful by replacing `respond` 41513498266Sopenharmony_ciwith `reverse_proxy` or `file_server`, for example: `reverse_proxy localhost:80` 416