2024-03-31 11:52:28 +02:00
|
|
|
<!--
|
|
|
|
|
Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
|
|
|
|
|
|
|
|
SPDX-License-Identifier: curl
|
|
|
|
|
-->
|
|
|
|
|
|
2019-07-21 23:48:58 +02:00
|
|
|
# HTTP3 (and QUIC)
|
|
|
|
|
|
|
|
|
|
## Resources
|
|
|
|
|
|
2021-10-04 18:32:59 -07:00
|
|
|
[HTTP/3 Explained](https://http3-explained.haxx.se/en/) - the online free
|
2019-07-21 23:48:58 +02:00
|
|
|
book describing the protocols involved.
|
|
|
|
|
|
|
|
|
|
[quicwg.org](https://quicwg.org/) - home of the official protocol drafts
|
|
|
|
|
|
|
|
|
|
## QUIC libraries
|
|
|
|
|
|
2023-10-17 18:04:50 +02:00
|
|
|
QUIC libraries we are using:
|
2019-07-21 23:48:58 +02:00
|
|
|
|
|
|
|
|
[ngtcp2](https://github.com/ngtcp2/ngtcp2)
|
|
|
|
|
|
2023-10-17 18:04:50 +02:00
|
|
|
[quiche](https://github.com/cloudflare/quiche) - **EXPERIMENTAL**
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2021-12-23 11:20:34 +01:00
|
|
|
## Experimental
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2026-03-12 22:46:42 +01:00
|
|
|
HTTP/3 support using *quiche* in curl is considered **EXPERIMENTAL** until
|
|
|
|
|
further notice. Only the *ngtcp2* backend is not experimental.
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2024-02-27 07:48:10 +01:00
|
|
|
Further development and tweaking of the HTTP/3 support in curl happens in the
|
2026-03-02 23:41:35 +01:00
|
|
|
master branch using pull-requests like ordinary changes.
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2022-12-27 15:57:00 +01:00
|
|
|
To fix before we remove the experimental label:
|
|
|
|
|
|
2026-01-02 01:34:05 +01:00
|
|
|
- the used QUIC library needs to consider itself non-beta
|
|
|
|
|
- it is fine to "leave" individual backends as experimental if necessary
|
2022-12-27 15:57:00 +01:00
|
|
|
|
2019-07-21 23:48:58 +02:00
|
|
|
# ngtcp2 version
|
|
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
Building curl with ngtcp2 involves 3 components: `ngtcp2` itself, `nghttp3`
|
|
|
|
|
and a QUIC supporting TLS library. The supported TLS libraries are covered
|
|
|
|
|
below.
|
2023-04-25 12:05:54 +02:00
|
|
|
|
2025-02-13 14:33:26 +01:00
|
|
|
While any version of `ngtcp2` and `nghttp3` from v1.0.0 on are expected to
|
|
|
|
|
work, using the latest versions often brings functional and performance
|
|
|
|
|
improvements.
|
|
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
The build examples use `$NGHTTP3_VERSION` and `$NGTCP2_VERSION` as
|
|
|
|
|
placeholders for the version you build.
|
2023-04-25 12:05:54 +02:00
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
## Build with OpenSSL or fork
|
2025-04-16 16:16:26 +02:00
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
OpenSSL v3.5.0+ requires *ngtcp2* v1.12.0+. Earlier versions do not work.
|
2025-04-16 16:16:26 +02:00
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build OpenSSL (v3.5.0+) or fork AWS-LC, BoringSSL, LibreSSL or quictls:
|
2025-04-16 16:16:26 +02:00
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
# Instructions for OpenSSL v3.5.0+
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch openssl-$OPENSSL_VERSION https://github.com/openssl/openssl
|
2025-04-16 16:16:26 +02:00
|
|
|
% cd openssl
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./config --prefix=/path/to/openssl --libdir=lib
|
2025-04-16 16:16:26 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
|
|
|
|
Build nghttp3:
|
|
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGHTTP3_VERSION https://github.com/ngtcp2/nghttp3
|
2025-04-16 16:16:26 +02:00
|
|
|
% cd nghttp3
|
|
|
|
|
% git submodule update --init
|
|
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure --prefix=/path/to/nghttp3 --enable-lib-only
|
2025-04-16 16:16:26 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
|
|
|
|
Build ngtcp2:
|
|
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGTCP2_VERSION https://github.com/ngtcp2/ngtcp2
|
2025-04-16 16:16:26 +02:00
|
|
|
% cd ngtcp2
|
|
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
# Change --with-openssl to --with-boringssl for AWS-LC and BoringSSL
|
2026-03-24 14:42:39 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/openssl/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig LDFLAGS="-Wl,-rpath,/path/to/openssl/lib" \
|
|
|
|
|
--prefix=/path/to/ngtcp2 --enable-lib-only --with-openssl
|
2025-04-16 16:16:26 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with autotools):
|
2025-04-16 16:16:26 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2025-04-16 16:16:26 +02:00
|
|
|
% cd curl
|
|
|
|
|
% autoreconf -fi
|
2026-03-24 14:42:39 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/openssl/lib/pkgconfig LDFLAGS="-Wl,-rpath,/path/to/openssl/lib" \
|
|
|
|
|
--with-openssl=/path/to/openssl --with-ngtcp2=/path/to/ngtcp2 --with-nghttp3=/path/to/nghttp3
|
2025-04-16 16:16:26 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with CMake):
|
2019-08-10 23:19:55 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2019-08-10 23:19:55 +02:00
|
|
|
% cd curl
|
2026-03-24 14:42:39 +01:00
|
|
|
% PKG_CONFIG_PATH=/path/to/openssl/lib/pkgconfig:/path/to/ngtcp2/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig cmake -B bld \
|
|
|
|
|
-DOPENSSL_ROOT_DIR=/path/to/openssl -DUSE_NGTCP2=ON
|
2026-03-16 20:00:44 +01:00
|
|
|
% cmake --build bld
|
2021-10-11 18:38:01 -07:00
|
|
|
|
2020-03-25 22:49:02 +01:00
|
|
|
## Build with GnuTLS
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build GnuTLS:
|
2020-03-25 22:49:02 +01:00
|
|
|
|
2025-12-08 16:44:29 +01:00
|
|
|
% git clone --depth 1 https://gitlab.com/gnutls/gnutls
|
2020-03-25 22:49:02 +01:00
|
|
|
% cd gnutls
|
|
|
|
|
% ./bootstrap
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure --prefix=/path/to/gnutls
|
2020-03-25 22:49:02 +01:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build nghttp3:
|
2020-03-25 22:49:02 +01:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGHTTP3_VERSION https://github.com/ngtcp2/nghttp3
|
2020-03-25 22:49:02 +01:00
|
|
|
% cd nghttp3
|
2024-02-12 15:22:39 +05:30
|
|
|
% git submodule update --init
|
2021-10-11 18:38:01 -07:00
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure --prefix=/path/to/nghttp3 --enable-lib-only
|
2020-03-25 22:49:02 +01:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build ngtcp2:
|
2020-03-25 22:49:02 +01:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGTCP2_VERSION https://github.com/ngtcp2/ngtcp2
|
2020-03-25 22:49:02 +01:00
|
|
|
% cd ngtcp2
|
2021-10-11 18:38:01 -07:00
|
|
|
% autoreconf -fi
|
2026-03-24 14:42:39 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/gnutls/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig LDFLAGS="-Wl,-rpath,/path/to/gnutls/lib" \
|
|
|
|
|
--prefix=/path/to/ngtcp2 --enable-lib-only --with-gnutls
|
2020-03-25 22:49:02 +01:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with autotools):
|
2020-03-25 22:49:02 +01:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2020-03-25 22:49:02 +01:00
|
|
|
% cd curl
|
2021-09-19 22:17:42 +09:00
|
|
|
% autoreconf -fi
|
2026-03-13 16:34:57 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/gnutls/lib/pkgconfig --with-gnutls=/path/to/gnutls --with-ngtcp2=/path/to/ngtcp2 --with-nghttp3=/path/to/nghttp3
|
2020-03-25 22:49:02 +01:00
|
|
|
% make
|
2021-10-11 18:38:01 -07:00
|
|
|
% make install
|
2020-03-25 22:49:02 +01:00
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with CMake):
|
|
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2026-03-16 20:00:44 +01:00
|
|
|
% cd curl
|
|
|
|
|
% PKG_CONFIG_PATH=/path/to/gnutls/lib/pkgconfig:/path/to/ngtcp2/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig cmake -B bld -DCURL_USE_GNUTLS=ON -DUSE_NGTCP2=ON
|
|
|
|
|
% cmake --build bld
|
|
|
|
|
|
2022-08-10 10:06:52 +02:00
|
|
|
## Build with wolfSSL
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build wolfSSL:
|
2022-08-10 10:06:52 +02:00
|
|
|
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/wolfSSL/wolfssl
|
2022-08-10 10:06:52 +02:00
|
|
|
% cd wolfssl
|
2022-08-23 13:54:27 +02:00
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure --prefix=/path/to/wolfssl --enable-quic --enable-session-ticket --enable-earlydata --enable-psk --enable-harden --enable-altcertchains
|
2022-08-10 10:06:52 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build nghttp3:
|
2022-08-10 10:06:52 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGHTTP3_VERSION https://github.com/ngtcp2/nghttp3
|
2022-08-10 10:06:52 +02:00
|
|
|
% cd nghttp3
|
2024-02-12 15:22:39 +05:30
|
|
|
% git submodule update --init
|
2022-08-10 10:06:52 +02:00
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure --prefix=/path/to/nghttp3 --enable-lib-only
|
2022-08-10 10:06:52 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Build ngtcp2:
|
2022-08-10 10:06:52 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 --branch $NGTCP2_VERSION https://github.com/ngtcp2/ngtcp2
|
2022-08-10 10:06:52 +02:00
|
|
|
% cd ngtcp2
|
|
|
|
|
% autoreconf -fi
|
2026-03-24 14:42:39 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/wolfssl/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig LDFLAGS="-Wl,-rpath,/path/to/wolfssl/lib" \
|
|
|
|
|
--prefix=/path/to/ngtcp2 --enable-lib-only --with-wolfssl
|
2022-08-10 10:06:52 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with autotools):
|
2022-08-10 10:06:52 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2022-08-10 10:06:52 +02:00
|
|
|
% cd curl
|
|
|
|
|
% autoreconf -fi
|
2026-03-16 20:00:44 +01:00
|
|
|
% ./configure PKG_CONFIG_PATH=/path/to/wolfssl/lib/pkgconfig --with-wolfssl=/path/to/wolfssl --with-ngtcp2=/path/to/ngtcp2 --with-nghttp3=/path/to/nghttp3
|
2022-08-10 10:06:52 +02:00
|
|
|
% make
|
|
|
|
|
% make install
|
|
|
|
|
|
2026-03-16 20:00:44 +01:00
|
|
|
Build curl (with CMake):
|
|
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2026-03-16 20:00:44 +01:00
|
|
|
% cd curl
|
|
|
|
|
% PKG_CONFIG_PATH=/path/to/wolfssl/lib/pkgconfig:/path/to/ngtcp2/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig cmake -B bld -DCURL_USE_WOLFSSL=ON -DUSE_NGTCP2=ON
|
|
|
|
|
% cmake --build bld
|
|
|
|
|
|
2019-07-21 23:48:58 +02:00
|
|
|
# quiche version
|
|
|
|
|
|
2023-10-17 18:04:50 +02:00
|
|
|
quiche support is **EXPERIMENTAL**
|
|
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
Since 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.
|
2023-04-25 12:05:54 +02:00
|
|
|
|
2024-07-07 17:39:33 +02:00
|
|
|
## Build
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2026-06-19 15:44:33 +02:00
|
|
|
Build quiche and BoringSSL (described here for quiche v0.29.1, the locations
|
|
|
|
|
where BoringSSL is to be found vary with version):
|
2019-08-10 00:57:04 -05:00
|
|
|
|
2026-06-19 15:44:33 +02:00
|
|
|
% git clone --depth 1 --branch 0.29.1 --recursive https://github.com/cloudflare/quiche
|
2020-06-04 13:18:00 -04:00
|
|
|
% cd quiche
|
2021-11-30 13:37:36 +00:00
|
|
|
% cargo build --package quiche --release --features ffi,pkg-config-meta,qlog
|
2024-06-28 12:51:25 +09:00
|
|
|
% ln -s libquiche.so target/release/libquiche.so.0
|
2026-06-19 15:44:33 +02:00
|
|
|
% mkdir -p boringssl/lib
|
|
|
|
|
% find target/release \( -name libcrypto.a -o -name libssl.a \) -exec ln -vnf -- '{}' boringssl/lib \;
|
|
|
|
|
% find target/release/build/boring-sys-*/out/boringssl/src -maxdepth 1 \( -name include \) -exec ln -vsf -- '../{}' boringssl \;
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2020-02-05 00:25:12 +01:00
|
|
|
Build curl:
|
2019-07-21 23:48:58 +02:00
|
|
|
|
|
|
|
|
% cd ..
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/curl/curl
|
2019-08-10 00:57:04 -05:00
|
|
|
% cd curl
|
2021-09-19 22:17:42 +09:00
|
|
|
% autoreconf -fi
|
2026-06-15 14:33:20 +02:00
|
|
|
% ./configure --with-openssl=$PWD/../quiche/boringssl --with-quiche=$PWD/../quiche/target/release
|
2019-09-23 20:56:48 +02:00
|
|
|
% make
|
2021-10-11 18:38:01 -07:00
|
|
|
% make install
|
|
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
If `make install` results in `Permission denied` error, you need to prepend
|
|
|
|
|
it with `sudo`.
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2021-12-23 11:20:34 +01:00
|
|
|
# `--http3`
|
2019-09-26 14:17:09 +02:00
|
|
|
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
Use only HTTP/3:
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
% curl --http3-only https://example.org:4433/
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
|
|
|
|
Use HTTP/3 with fallback to HTTP/2 or HTTP/1.1 (see "HTTPS eyeballing" below):
|
2019-09-26 14:17:09 +02:00
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
% curl --http3 https://example.org:4433/
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2019-09-26 14:17:09 +02:00
|
|
|
Upgrade via Alt-Svc:
|
2019-07-21 23:48:58 +02:00
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
% curl --alt-svc altsvc.cache https://curl.se/
|
2019-09-26 13:18:17 +02:00
|
|
|
|
|
|
|
|
See this [list of public HTTP/3 servers](https://bagder.github.io/HTTP3-test/)
|
2021-12-16 09:20:54 +01:00
|
|
|
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
### HTTPS eyeballing
|
|
|
|
|
|
2024-02-27 07:48:10 +01:00
|
|
|
With option `--http3` curl attempts earlier HTTP versions as well should the
|
2025-12-11 02:46:24 +01:00
|
|
|
connect attempt via HTTP/3 fail "fast enough". This strategy is similar
|
2024-02-27 07:48:10 +01:00
|
|
|
to IPv4/6 happy eyeballing where the alternate address family is used in
|
|
|
|
|
parallel after a short delay.
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
2023-09-11 09:27:43 +02:00
|
|
|
The IPv4/6 eyeballing has a default of 200ms and you may override that via
|
|
|
|
|
`--happy-eyeballs-timeout-ms value`. Since HTTP/3 is still relatively new, we
|
|
|
|
|
decided to use this timeout also for the HTTP eyeballing - with a slight
|
|
|
|
|
twist.
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
2023-09-11 09:27:43 +02:00
|
|
|
The `happy-eyeballs-timeout-ms` value is the **hard** timeout, meaning after
|
|
|
|
|
that time expired, a TLS connection is opened in addition to negotiate HTTP/2
|
|
|
|
|
or HTTP/1.1. At half of that value - currently - is the **soft** timeout. The
|
|
|
|
|
soft timeout fires, when there has been **no data at all** seen from the
|
|
|
|
|
server on the HTTP/3 connection.
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
2026-03-09 16:31:37 +01:00
|
|
|
Without you specifying anything, the hard timeout is 200ms and the soft is
|
2026-01-16 18:13:44 +01:00
|
|
|
100ms:
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
* Ideally, the whole QUIC handshake happens and curl has an HTTP/3 connection
|
|
|
|
|
in less than 100ms.
|
|
|
|
|
* When QUIC is not supported (or UDP does not work for this network path), no
|
|
|
|
|
reply is seen and the HTTP/2 TLS+TCP connection starts 100ms later.
|
|
|
|
|
* In the worst case, UDP replies start before 100ms, but drag on. This starts
|
|
|
|
|
the TLS+TCP connection after 200ms.
|
|
|
|
|
* When the QUIC handshake fails, the TLS+TCP connection is attempted right
|
|
|
|
|
away. For example, when the QUIC server presents the wrong certificate.
|
2023-09-11 09:27:43 +02:00
|
|
|
|
|
|
|
|
The whole transfer only fails, when **both** QUIC and TLS+TCP fail to
|
|
|
|
|
handshake or time out.
|
|
|
|
|
|
|
|
|
|
Note that all this happens in addition to IP version happy eyeballing. If the
|
2024-02-27 07:48:10 +01:00
|
|
|
name resolution for the server gives more than one IP address, curl tries all
|
2026-03-02 23:41:35 +01:00
|
|
|
those until one succeeds - as with all other protocols. If those IP addresses
|
|
|
|
|
contain both IPv6 and IPv4, those attempts happen, delayed, in parallel (the
|
|
|
|
|
actual eyeballing).
|
connections: introduce http/3 happy eyeballs
New cfilter HTTP-CONNECT for h3/h2/http1.1 eyeballing.
- filter is installed when `--http3` in the tool is used (or
the equivalent CURLOPT_ done in the library)
- starts a QUIC/HTTP/3 connect right away. Should that not
succeed after 100ms (subject to change), a parallel attempt
is started for HTTP/2 and HTTP/1.1 via TCP
- both attempts are subject to IPv6/IPv4 eyeballing, same
as happens for other connections
- tie timeout to the ip-version HAPPY_EYEBALLS_TIMEOUT
- use a `soft` timeout at half the value. When the soft timeout
expires, the HTTPS-CONNECT filter checks if the QUIC filter
has received any data from the server. If not, it will start
the HTTP/2 attempt.
HTTP/3(ngtcp2) improvements.
- setting call_data in all cfilter calls similar to http/2 and vtls filters
for use in callback where no stream data is available.
- returning CURLE_PARTIAL_FILE for prematurely terminated transfers
- enabling pytest test_05 for h3
- shifting functionality to "connect" UDP sockets from ngtcp2
implementation into the udp socket cfilter. Because unconnected
UDP sockets are weird. For example they error when adding to a
pollset.
HTTP/3(quiche) improvements.
- fixed upload bug in quiche implementation, now passes 251 and pytest
- error codes on stream RESET
- improved debug logs
- handling of DRAIN during connect
- limiting pending event queue
HTTP/2 cfilter improvements.
- use LOG_CF macros for dynamic logging in debug build
- fix CURLcode on RST streams to be CURLE_PARTIAL_FILE
- enable pytest test_05 for h2
- fix upload pytests and improve parallel transfer performance.
GOAWAY handling for ngtcp2/quiche
- during connect, when the remote server refuses to accept new connections
and closes immediately (so the local conn goes into DRAIN phase), the
connection is torn down and a another attempt is made after a short grace
period.
This is the behaviour observed with nghttpx when we tell it to shut
down gracefully. Tested in pytest test_03_02.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
- new tests/tests-httpd/scorecard.py for testing h3/h2 protocol implementation.
Invoke:
python3 tests/tests-httpd/scorecard.py --help
for usage.
Improvements on gathering connect statistics and socket access.
- new CF_CTRL_CONN_REPORT_STATS cfilter control for having cfilters
report connection statistics. This is triggered when the connection
has completely connected.
- new void Curl_pgrsTimeWas(..) method to report a timer update with
a timestamp of when it happend. This allows for updating timers
"later", e.g. a connect statistic after full connectivity has been
reached.
- in case of HTTP eyeballing, the previous changes will update
statistics only from the filter chain that "won" the eyeballing.
- new cfilter query CF_QUERY_SOCKET for retrieving the socket used
by a filter chain.
Added methods Curl_conn_cf_get_socket() and Curl_conn_get_socket()
for convenient use of this query.
- Change VTLS backend to query their sub-filters for the socket when
checks during the handshake are made.
HTTP/3 documentation on how https eyeballing works.
TLS improvements
- ALPN selection for SSL/SSL-PROXY filters in one vtls set of functions, replaces
copy of logic in all tls backends.
- standardized the infof logging of offered ALPNs
- ALPN negotiated: have common function for all backends that sets alpn proprty
and connection related things based on the negotiated protocol (or lack thereof).
Scorecard with Caddy.
- configure can be run with `--with-test-caddy=path` to specify which caddy to use for testing
- tests/tests-httpd/scorecard.py now measures download speeds with caddy
pytest improvements
- adding Makfile to clean gen dir
- adding nghttpx rundir creation on start
- checking httpd version 2.4.55 for test_05 cases where it is needed. Skipping with message if too old.
- catch exception when checking for caddy existance on system.
Closes #10349
2023-02-01 17:13:12 +01:00
|
|
|
|
2021-12-16 09:20:54 +01:00
|
|
|
## Known Bugs
|
|
|
|
|
|
2021-12-23 11:20:34 +01:00
|
|
|
Check out the [list of known HTTP3 bugs](https://curl.se/docs/knownbugs.html#HTTP3).
|
|
|
|
|
|
|
|
|
|
# HTTP/3 Test server
|
|
|
|
|
|
|
|
|
|
This is not advice on how to run anything in production. This is for
|
|
|
|
|
development and experimenting.
|
|
|
|
|
|
2022-04-21 17:05:36 +02:00
|
|
|
## Prerequisite(s)
|
2021-12-23 11:20:34 +01:00
|
|
|
|
|
|
|
|
An existing local HTTP/1.1 server that hosts files. Preferably also a few huge
|
2022-09-19 17:30:30 +02:00
|
|
|
ones. You can easily create huge local files like `truncate -s=8G 8GB` - they
|
2026-03-02 23:41:35 +01:00
|
|
|
are huge but do not occupy that much space on disk since they are big holes.
|
2021-12-23 11:20:34 +01:00
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
In a Debian setup you can install apache2. It runs on port 80 and has a
|
2023-04-27 11:31:36 +02:00
|
|
|
document root in `/var/www/html`. Download the 8GB file from apache with `curl
|
2021-12-23 11:20:34 +01:00
|
|
|
localhost/8GB -o dev/null`
|
|
|
|
|
|
2022-03-29 13:58:11 +02:00
|
|
|
In this description we setup and run an HTTP/3 reverse-proxy in front of the
|
2021-12-23 11:20:34 +01:00
|
|
|
HTTP/1 server.
|
|
|
|
|
|
|
|
|
|
## Setup
|
|
|
|
|
|
|
|
|
|
You can select either or both of these server solutions.
|
|
|
|
|
|
|
|
|
|
### nghttpx
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Get, build and install quictls, nghttp3 and ngtcp2 as described
|
2021-12-23 11:20:34 +01:00
|
|
|
above.
|
|
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
Get, build and install nghttp2:
|
2021-12-23 11:20:34 +01:00
|
|
|
|
2026-04-25 12:59:55 +02:00
|
|
|
% git clone --depth 1 https://github.com/nghttp2/nghttp2
|
2024-08-27 09:28:58 +02:00
|
|
|
% cd nghttp2
|
|
|
|
|
% autoreconf -fi
|
2026-03-24 14:42:39 +01:00
|
|
|
% PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/quictls/lib/pkgconfig:/path/to/nghttp3/lib/pkgconfig:/path/to/ngtcp2/lib/pkgconfig \
|
|
|
|
|
LDFLAGS=-L/path/to/quictls/lib CFLAGS=-I/path/to/quictls/include ./configure --enable-maintainer-mode \
|
|
|
|
|
--prefix=/path/to/nghttp2 --disable-shared --enable-app --enable-http3 --without-jemalloc --without-libxml2 --without-systemd
|
2024-08-27 09:28:58 +02:00
|
|
|
% make && make install
|
2021-12-23 11:20:34 +01:00
|
|
|
|
|
|
|
|
Run the local h3 server on port 9443, make it proxy all traffic through to
|
2026-03-02 23:41:35 +01:00
|
|
|
HTTP/1 on localhost port 80. For local toying, we can use the test cert that
|
|
|
|
|
exists in curl's test dir.
|
2021-12-23 11:20:34 +01:00
|
|
|
|
runtests: generate certs dynamically, bump to EC-256, tidy up
Before this patch the curl repository and source tarball distribution
contained test certificates as binary blobs. Used by runtests.
Drop these certificates in favor of generating them dynamically as
part of the build process. Both via autotools and CMake.
As part of this, improve certificates, the generator script and process,
file layout, and fix any issue to make it work fast and smooth both in
CI and local builds.
Note, cert generator scripts require OpenSSL >=1.0.2
(or LibreSSL >=3.1.0). Generation requires POSIX shell, also with CMake.
Without a POSIX shell tests relying on TLS (and stunnel) will fail.
Details:
- build: generate certs as part of the test run process.
- build, tests: generate certs in the build directory.
- binarycheck: drop concept of known binary files with hashes.
- binarycheck: move binary check logic into spacecheck and drop this
separate checker tool.
- build: fix to clean all cert files.
- autotools: fix to not run leaf cert generators in parallel. To avoid
confusion when updating the revocation database and counter.
- scripts: drop `scripts` subdir, merge two scripts into one,
auto-generate root cert, allow generating multiple leafs at once.
- scripts: switch to EC-256 keys (was: RSA-2048). For key size and perf.
- scripts: drop `-x` echo, text dumps, most other output. To avoid log
noise and make it quicker in CI.
- scripts: make it non-RSA-specific.
- scripts: delete unused code.
- scripts: use POSIX shell shebang. Some envs don't have bash (Alpine).
- scripts: pass test pseudo-secrets via the command-line. To avoid:
```
+ openssl genrsa -out test-ca.key -passout fd:0 2048
Invalid password argument, starting with "fd:"
```
- cmake: fix to launch generator scripts via the detected POSIX shell.
- cmake: fix `build-certs` rule to not depend on `SRPFILES`
(`srp-verifier-*`).
- cmake: drop `EXCLUDE_FROM_ALL` for the cert subdir. It makes
the Visual Studio generator miss to create the `clean-certs`,
`build-certs` targets. No target depend on them, so they don't execute
implicitly anyway. Fixes:
```
MSBUILD : error MSB1009: Project file does not exist.
Switch: clean-certs.vcxproj
```
- cmake: add `VERBATIM USES_TERMINAL` to `build-certs` target.
- GHA/linux: install openssl on Alpine, for the cert generator scripts.
Follow-up to 556f722fe32e5e9f4e24f0242100c5e9d57c129b #16593
Follow-up to fa461b4eff52b413f88debf543b5350a6cef4724 #14486
Closes #16824
2025-03-24 22:13:29 +01:00
|
|
|
% CERT=/path/to/stunnel.pem
|
2024-08-27 09:28:58 +02:00
|
|
|
% $HOME/bin/nghttpx $CERT $CERT --backend=localhost,80 \
|
2026-03-24 14:42:39 +01:00
|
|
|
--frontend="localhost,9443;quic"
|
2021-12-23 11:20:34 +01:00
|
|
|
|
|
|
|
|
### Caddy
|
|
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
[Install Caddy](https://caddyserver.com/docs/install). For easiest use, the
|
|
|
|
|
binary should be either in your PATH or your current directory.
|
2021-12-23 11:20:34 +01:00
|
|
|
|
2022-09-29 12:42:00 -06:00
|
|
|
Create a `Caddyfile` with the following content:
|
2021-12-23 11:20:34 +01:00
|
|
|
~~~
|
|
|
|
|
localhost:7443 {
|
2023-08-31 13:28:49 +00:00
|
|
|
respond "Hello, world! you are using {http.request.proto}"
|
2021-12-23 11:20:34 +01:00
|
|
|
}
|
|
|
|
|
~~~
|
|
|
|
|
|
2022-09-20 23:30:19 +02:00
|
|
|
Then run Caddy:
|
2021-12-23 11:20:34 +01:00
|
|
|
|
2024-08-27 09:28:58 +02:00
|
|
|
% ./caddy start
|
2022-09-29 12:42:00 -06:00
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
Making requests to `https://localhost:7443` should tell you which protocol is
|
|
|
|
|
being used.
|
2022-09-29 12:42:00 -06:00
|
|
|
|
2026-01-16 18:13:44 +01:00
|
|
|
You can change the hard-coded response to something more useful by replacing
|
|
|
|
|
`respond` with `reverse_proxy` or `file_server`, for example: `reverse_proxy
|
|
|
|
|
localhost:80`
|