Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ jobs:
- uses: Swatinem/rust-cache@v2

- name: check --feature-powerset
run: cargo hack --no-dev-deps check --feature-powerset --depth 2 --skip http3,__tls,__rustls,__rustls-ring,native-tls-vendored,trust-dns
run: cargo hack --no-dev-deps check --feature-powerset --depth 2 --skip http3,http3-no-provider,http3-aws-lc-rs,__tls,__rustls,__rustls-ring,native-tls-vendored,trust-dns
env:
RUSTFLAGS: "-D dead_code -D unused_imports"

Expand All @@ -237,7 +237,7 @@ jobs:
toolchain: 'stable'

- name: Check
run: cargo test --features http3,stream
run: cargo test --features http3,http3-no-provider,http3-aws-lc-rs,stream
env:
RUSTFLAGS: --cfg reqwest_unstable
RUSTDOCFLAGS: --cfg reqwest_unstable
Expand Down
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ system-proxy = ["hyper-util/client-proxy-system"]
macos-system-configuration = ["system-proxy"]

# Experimental HTTP/3 client.
http3 = ["rustls-tls-manual-roots", "dep:h3", "dep:h3-quinn", "dep:quinn", "tokio/macros"]
http3-no-provider = ["rustls-tls-manual-roots-no-provider", "dep:h3", "dep:h3-quinn", "dep:quinn", "tokio/macros"]
http3 = ["http3-no-provider", "quinn/rustls-ring"]
http3-aws-lc-rs = ["http3-no-provider", "quinn/rustls-aws-lc-rs"]


# Internal (PRIVATE!) features used to aid testing.
Expand Down Expand Up @@ -169,7 +171,7 @@ once_cell = { version = "1.18", optional = true }
# HTTP/3 experimental support
h3 = { version = "0.0.8", optional = true }
h3-quinn = { version = "0.0.10", optional = true }
quinn = { version = "0.11.1", default-features = false, features = ["rustls", "runtime-tokio"], optional = true }
quinn = { version = "0.11.1", default-features = false, features = ["runtime-tokio"], optional = true }
futures-channel = { version = "0.3", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions examples/h3_simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// This is using the `tokio` runtime. You'll need the following dependency:
//
// `tokio = { version = "1", features = ["full"] }`
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
Expand Down Expand Up @@ -40,5 +40,5 @@ async fn main() -> Result<(), reqwest::Error> {
// for wasm32 target, because tokio isn't compatible with wasm32.
// If you aren't building for wasm32, you don't need that line.
// The two lines below avoid the "'main' function not found" error when building for wasm32 target.
#[cfg(any(target_arch = "wasm32", not(feature = "http3")))]
#[cfg(any(target_arch = "wasm32", not(feature = "http3-no-provider")))]
fn main() {}
104 changes: 52 additions & 52 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use super::decoder::Accepts;
use super::request::{Request, RequestBuilder};
use super::response::Response;
use super::Body;
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
use crate::async_impl::h3_client::connect::{H3ClientConfig, H3Connector};
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
use crate::async_impl::h3_client::H3Client;
use crate::config::{RequestConfig, TotalTimeout};
#[cfg(unix)]
Expand Down Expand Up @@ -54,9 +54,9 @@ use hyper_util::client::legacy::connect::HttpConnector;
#[cfg(feature = "default-tls")]
use native_tls_crate::TlsConnector;
use pin_project_lite::pin_project;
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
use quinn::TransportConfig;
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
use quinn::VarInt;
use tokio::time::Sleep;
use tower::util::BoxCloneSyncServiceLayer;
Expand Down Expand Up @@ -91,7 +91,7 @@ enum HttpVersionPref {
Http1,
#[cfg(feature = "http2")]
Http2,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
Http3,
All,
}
Expand Down Expand Up @@ -206,21 +206,21 @@ struct Config {
hickory_dns: bool,
error: Option<crate::Error>,
https_only: bool,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
tls_enable_early_data: bool,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_max_idle_timeout: Option<Duration>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_stream_receive_window: Option<VarInt>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_receive_window: Option<VarInt>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_send_window: Option<u64>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_congestion_bbr: bool,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_max_field_section_size: Option<u64>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_send_grease: Option<bool>,
dns_overrides: HashMap<String, Vec<SocketAddr>>,
dns_resolver: Option<Arc<dyn Resolve>>,
Expand Down Expand Up @@ -333,21 +333,21 @@ impl ClientBuilder {
cookie_store: None,
https_only: false,
dns_overrides: HashMap::new(),
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
tls_enable_early_data: false,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_max_idle_timeout: None,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_stream_receive_window: None,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_receive_window: None,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_send_window: None,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
quic_congestion_bbr: false,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_max_field_section_size: None,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_send_grease: None,
dns_resolver: None,
#[cfg(unix)]
Expand Down Expand Up @@ -378,7 +378,7 @@ impl ClientBuilder {
let proxies = Arc::new(proxies);

#[allow(unused)]
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
let mut h3_connector = None;

let resolver = {
Expand Down Expand Up @@ -410,7 +410,7 @@ impl ClientBuilder {
let mut http = HttpConnector::new_with_resolver(resolver.clone());
http.set_connect_timeout(config.connect_timeout);

#[cfg(all(feature = "http3", feature = "__rustls"))]
#[cfg(all(feature = "http3-no-provider", feature = "__rustls"))]
let build_h3_connector =
|resolver,
tls,
Expand Down Expand Up @@ -484,7 +484,7 @@ impl ClientBuilder {
TlsBackend::Default => {
let mut tls = TlsConnector::builder();

#[cfg(all(feature = "native-tls-alpn", not(feature = "http3")))]
#[cfg(all(feature = "native-tls-alpn", not(feature = "http3-no-provider")))]
{
match config.http_version_pref {
HttpVersionPref::Http1 => {
Expand Down Expand Up @@ -595,7 +595,7 @@ impl ClientBuilder {
),
#[cfg(feature = "__rustls")]
TlsBackend::BuiltRustls(conn) => {
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
{
h3_connector = build_h3_connector(
resolver.clone(),
Expand Down Expand Up @@ -785,7 +785,7 @@ impl ClientBuilder {
HttpVersionPref::Http2 => {
tls.alpn_protocols = vec!["h2".into()];
}
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
HttpVersionPref::Http3 => {
tls.alpn_protocols = vec!["h3".into()];
}
Expand All @@ -798,7 +798,7 @@ impl ClientBuilder {
}
}

#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
{
tls.enable_early_data = config.tls_enable_early_data;

Expand Down Expand Up @@ -986,7 +986,7 @@ impl ClientBuilder {
cookie_store: config.cookie_store.clone(),
// Use match instead of map since config is partially moved,
// and it cannot be used in closure
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_client: match h3_connector {
Some(h3_connector) => {
let h3_service = H3Client::new(h3_connector, config.pool_idle_timeout);
Expand Down Expand Up @@ -1472,8 +1472,8 @@ impl ClientBuilder {
}

/// Only use HTTP/3.
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_prior_knowledge(mut self) -> ClientBuilder {
self.config.http_version_pref = HttpVersionPref::Http3;
self
Expand Down Expand Up @@ -2199,8 +2199,8 @@ impl ClientBuilder {
/// for HTTP/3 connections.
///
/// The default is false.
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn tls_early_data(mut self, enabled: bool) -> ClientBuilder {
self.config.tls_enable_early_data = enabled;
self
Expand All @@ -2211,8 +2211,8 @@ impl ClientBuilder {
/// Please see docs in [`TransportConfig`] in [`quinn`].
///
/// [`TransportConfig`]: https://docs.rs/quinn/latest/quinn/struct.TransportConfig.html
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_max_idle_timeout(mut self, value: Duration) -> ClientBuilder {
self.config.quic_max_idle_timeout = Some(value);
self
Expand All @@ -2228,8 +2228,8 @@ impl ClientBuilder {
/// # Panics
///
/// Panics if the value is over 2^62.
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_stream_receive_window(mut self, value: u64) -> ClientBuilder {
self.config.quic_stream_receive_window = Some(value.try_into().unwrap());
self
Expand All @@ -2245,8 +2245,8 @@ impl ClientBuilder {
/// # Panics
///
/// Panics if the value is over 2^62.
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_conn_receive_window(mut self, value: u64) -> ClientBuilder {
self.config.quic_receive_window = Some(value.try_into().unwrap());
self
Expand All @@ -2257,8 +2257,8 @@ impl ClientBuilder {
/// Please see docs in [`TransportConfig`] in [`quinn`].
///
/// [`TransportConfig`]: https://docs.rs/quinn/latest/quinn/struct.TransportConfig.html
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_send_window(mut self, value: u64) -> ClientBuilder {
self.config.quic_send_window = Some(value);
self
Expand All @@ -2271,8 +2271,8 @@ impl ClientBuilder {
///
/// [BBR]: https://datatracker.ietf.org/doc/html/draft-ietf-ccwg-bbr
/// [CUBIC]: https://datatracker.ietf.org/doc/html/rfc8312
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_congestion_bbr(mut self) -> ClientBuilder {
self.config.quic_congestion_bbr = true;
self
Expand All @@ -2287,8 +2287,8 @@ impl ClientBuilder {
/// Please see docs in [`Builder`] in [`h3`].
///
/// [`Builder`]: https://docs.rs/h3/latest/h3/client/struct.Builder.html#method.max_field_section_size
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_max_field_section_size(mut self, value: u64) -> ClientBuilder {
self.config.h3_max_field_section_size = Some(value.try_into().unwrap());
self
Expand All @@ -2305,8 +2305,8 @@ impl ClientBuilder {
/// Please see docs in [`Builder`] in [`h3`].
///
/// [`Builder`]: https://docs.rs/h3/latest/h3/client/struct.Builder.html#method.send_grease
#[cfg(feature = "http3")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3",))))]
#[cfg(feature = "http3-no-provider")]
#[cfg_attr(docsrs, doc(cfg(all(reqwest_unstable, feature = "http3-no-provider"))))]
pub fn http3_send_grease(mut self, enabled: bool) -> ClientBuilder {
self.config.h3_send_grease = Some(enabled);
self
Expand All @@ -2324,7 +2324,7 @@ impl ClientBuilder {
/// ```
/// use std::time::Duration;
///
/// # #[cfg(not(feature = "rustls-tls-no-provider"))]
/// # #[cfg(feature = "rustls-tls")]
/// let client = reqwest::Client::builder()
/// // resolved to outermost layer, meaning while we are waiting on concurrency limit
/// .connect_timeout(Duration::from_millis(200))
Expand Down Expand Up @@ -2508,7 +2508,7 @@ impl Client {
.version(version);

let in_flight = match version {
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
http::Version::HTTP_3 if self.inner.h3_client.is_some() => {
let mut req = builder.body(body).expect("valid request parts");
*req.headers_mut() = headers.clone();
Expand Down Expand Up @@ -2761,7 +2761,7 @@ impl Config {
f.field("dns_overrides", &self.dns_overrides);
}

#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
{
if self.tls_enable_early_data {
f.field("tls_enable_early_data", &true);
Expand Down Expand Up @@ -2791,7 +2791,7 @@ struct ClientRef {
cookie_store: Option<Arc<dyn cookie::CookieStore>>,
headers: HeaderMap,
hyper: LayeredService<HyperService>,
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
h3_client: Option<LayeredService<H3Client>>,
referer: bool,
total_timeout: RequestConfig<TotalTimeout>,
Expand Down Expand Up @@ -2871,7 +2871,7 @@ pin_project! {

enum ResponseFuture {
Default(LayeredFuture<HyperService>),
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
H3(LayeredFuture<H3Client>),
}

Expand Down Expand Up @@ -2942,7 +2942,7 @@ impl Future for PendingRequest {
}
Ok(res) => res.map(super::body::boxed),
},
#[cfg(feature = "http3")]
#[cfg(feature = "http3-no-provider")]
ResponseFuture::H3(r) => match ready!(Pin::new(r).poll(cx)) {
Err(e) => {
return Poll::Ready(Err(crate::error::request(e).with_url(self.url.clone())));
Expand Down
2 changes: 1 addition & 1 deletion src/async_impl/h3_client/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![cfg(feature = "http3")]
#![cfg(feature = "http3-no-provider")]

pub(crate) mod connect;
pub(crate) mod dns;
Expand Down
Loading
Loading