diff --git a/Cargo.toml b/Cargo.toml index 413c6991b..6ad08816a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ default = ["ssl"] ssl = ["openssl-sys", "openssl-probe", "curl-sys/ssl"] # OpenSSL/system TLS backend mesalink = ["curl-sys/mesalink"] # MesaLink TLS backend http2 = ["curl-sys/http2"] +http3-quiche = ["curl-sys/http3-quiche"] spnego = ["curl-sys/spnego"] rustls = ["curl-sys/rustls"] static-curl = ["curl-sys/static-curl"] diff --git a/README.md b/README.md index aad5f487a..ce517c3c7 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ with various Cargo features: Note that Rustls support is experimental within Curl itself and may have significant bugs, so we don't offer any sort of stability guarantee with this feature. - `mesalink`: Enable SSL/TLS support via [MesaLink], an alternative TLS backend written in Rust based on [Rustls]. MesaLink is always statically linked. Disabled by default. - `http2`: Enable HTTP/2 support via libnghttp2. Disabled by default. +- `http3-quiche`: Enable experimental HTTP/3 support via [Quiche](https://github.com/cloudflare/quiche). Disabled by default. - `static-curl`: Use a bundled libcurl version and statically link to it. Disabled by default. - `static-ssl`: Use a bundled OpenSSL version and statically link to it. Only applies on platforms that use OpenSSL. Disabled by default. - `spnego`: Enable SPNEGO support. Disabled by default. diff --git a/curl-sys/Cargo.toml b/curl-sys/Cargo.toml index e5f3ab649..d4e2f7b23 100644 --- a/curl-sys/Cargo.toml +++ b/curl-sys/Cargo.toml @@ -30,6 +30,13 @@ optional = true default-features = false features = ["client_apis", "error_strings", "tls13", "aesgcm", "chachapoly", "x25519", "ecdh", "ecdsa", "verifier"] +[dependencies.quiche] +git = "https://github.com/sagebind/quiche" +branch = "include-metadata" +optional = true +default-features = false +features = ["ffi"] + [dependencies.rustls-ffi] version = "0.8" optional = true @@ -52,6 +59,8 @@ cc = "1.0" default = ["ssl"] ssl = ["openssl-sys"] http2 = ["libnghttp2-sys"] +http3-quiche = ["quiche"] +http3-quiche-boringssl-vendored = ["quiche/boringssl-vendored"] rustls = ["rustls-ffi"] static-curl = [] static-ssl = ["openssl-sys/vendored"] diff --git a/curl-sys/build.rs b/curl-sys/build.rs index e9a2a42dd..efbc88558 100644 --- a/curl-sys/build.rs +++ b/curl-sys/build.rs @@ -248,6 +248,14 @@ fn main() { } } + if cfg!(feature = "http3-quiche") { + cfg.define("USE_QUICHE", None) + .file("curl/lib/vquic/vquic.c") + .file("curl/lib/vquic/quiche.c"); + + cfg.include(env::var_os("DEP_QUICHE_INCLUDE").unwrap()); + } + println!("cargo:rustc-cfg=link_libz"); if let Some(path) = env::var_os("DEP_Z_INCLUDE") { cfg.include(path); diff --git a/curl-sys/lib.rs b/curl-sys/lib.rs index c539206e3..130605a3d 100644 --- a/curl-sys/lib.rs +++ b/curl-sys/lib.rs @@ -10,6 +10,8 @@ extern crate libz_sys; extern crate mesalink; #[cfg(link_openssl)] extern crate openssl_sys; +#[cfg(feature = "http3-quiche")] +extern crate quiche; #[cfg(feature = "rustls")] extern crate rustls_ffi; diff --git a/examples/http3.rs b/examples/http3.rs new file mode 100644 index 000000000..aec4e6df3 --- /dev/null +++ b/examples/http3.rs @@ -0,0 +1,20 @@ +//! Simple HTTP/3 GET +//! +//! This example is a Rust adaptation of the [C example of the same +//! name](https://curl.se/libcurl/c/http3.html). + +use curl::easy::Easy; + +fn main() -> Result<(), curl::Error> { + let mut curl = Easy::new(); + + // An HTTP/3-capable server. + curl.url("https://cloudflare-quic.com")?; + + // Force HTTP/3 to be used. + curl.http_version(curl::easy::HttpVersion::V3)?; + + curl.perform()?; + + Ok(()) +}