Skip to content
This repository has been archived by the owner on Feb 7, 2025. It is now read-only.

Commit

Permalink
fix(client): Fix http version setting order
Browse files Browse the repository at this point in the history
  • Loading branch information
0x676e67 committed Aug 15, 2024
1 parent e0604a8 commit 11f2fd3
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 61 deletions.
12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ rustdoc-args = ["--cfg", "docsrs"]
targets = ["x86_64-unknown-linux-gnu"]

[features]
default = ["boring-tls", "http2"]
default = ["boring-tls"]

full = [
"boring-tls",
Expand All @@ -31,12 +31,9 @@ full = [
"stream",
"cookies",
"socks",
"http2",
"hickory-dns",
]

http2 = ["h2", "hyper/http2"]

blocking = ["futures-util/io", "tokio/sync"]

websocket = ["async-tungstenite", "tokio-util/compat"]
Expand Down Expand Up @@ -76,6 +73,7 @@ boring-tls = [
"dep:linked_hash_set",
"dep:tower-layer",
"dep:antidote",
"dep:typed-builder"
]

# When enabled, disable using the cached SYS_PROXIES.
Expand Down Expand Up @@ -104,10 +102,11 @@ http-body = "0.4.6"
hyper = { package = "rhyper", version = "0.14", default-features = false, features = [
"tcp",
"http1",
"http2",
"client",
"runtime",
] }
h2 = { package = "rh2", version = "0.3", optional = true }
h2 = { package = "rh2", version = "0.3" }
log = "0.4"
mime = "0.3.17"
percent-encoding = "2.3"
Expand All @@ -131,6 +130,9 @@ linked_hash_set = { version = "0.1", optional = true }
tower-layer = { version = "0.3", optional = true }
antidote = { version = "1", optional = true }

# boring-tls extension builder
typed-builder = { version = "0.19", optional = true }

## cookies
cookie_crate = { version = "0.18", package = "cookie", optional = true }
cookie_store = { version = "0.21", optional = true }
Expand Down
62 changes: 15 additions & 47 deletions src/async_impl/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use http::header::{
use http::uri::Scheme;
use http::{HeaderName, Uri};
use hyper::client::{HttpConnector, ResponseFuture as HyperResponseFuture};
#[cfg(feature = "http2")]
#[cfg(feature = "boring-tls")]
use hyper::{PseudoOrder, SettingsOrder, StreamDependency};
use pin_project_lite::pin_project;
use std::future::Future;
Expand Down Expand Up @@ -68,7 +68,6 @@ pub enum HttpVersionPref {
/// Prefer HTTP/1.1
Http1,
/// Prefer HTTP/2
#[cfg(feature = "http2")]
Http2,
/// Prefer HTTP/1 and HTTP/2
All,
Expand Down Expand Up @@ -98,7 +97,6 @@ struct Config {
cookie_store: Option<Arc<dyn cookie::CookieStore>>,
hickory_dns: bool,
error: Option<crate::Error>,
http_version_pref: HttpVersionPref,
dns_overrides: HashMap<String, Vec<SocketAddr>>,
dns_resolver: Option<Arc<dyn Resolve>>,
builder: hyper::client::Builder,
Expand Down Expand Up @@ -149,7 +147,6 @@ impl ClientBuilder {
hickory_dns: cfg!(feature = "hickory-dns"),
#[cfg(feature = "cookies")]
cookie_store: None,
http_version_pref: HttpVersionPref::All,
dns_overrides: HashMap::new(),
dns_resolver: None,
builder: hyper::Client::builder(),
Expand Down Expand Up @@ -244,10 +241,6 @@ impl ClientBuilder {
.builder
.pool_idle_timeout(config.pool_idle_timeout)
.pool_max_idle_per_host(config.pool_max_idle_per_host);
#[cfg(feature = "http2")]
if matches!(config.http_version_pref, HttpVersionPref::Http2) {
config.builder.http2_only(true);
}

Ok(Client {
inner: Arc::new(ClientRef {
Expand Down Expand Up @@ -296,26 +289,17 @@ impl ClientBuilder {
func(&mut self.config.headers);
self.config.tls.builder = Some(settings.builder);
self.config.tls.extension = settings.extension;
self.config.tls.extension.http_version_pref = self.config.http_version_pref;

// Set the http2 version preference
#[cfg(feature = "http2")]
{
self.http2_initial_stream_window_size(settings.http2.initial_stream_window_size)
.http2_initial_connection_window_size(settings.http2.initial_connection_window_size)
.http2_max_concurrent_streams(settings.http2.max_concurrent_streams)
.http2_max_header_list_size(settings.http2.max_header_list_size)
.http2_header_table_size(settings.http2.header_table_size)
.http2_enable_push(settings.http2.enable_push)
.http2_headers_priority(settings.http2.headers_priority)
.http2_headers_pseudo_order(settings.http2.headers_pseudo_order)
.http2_settings_order(settings.http2.settings_order)
}

#[cfg(not(feature = "http2"))]
{
self
}
self.http2_initial_stream_window_size(settings.http2.initial_stream_window_size)
.http2_initial_connection_window_size(settings.http2.initial_connection_window_size)
.http2_max_concurrent_streams(settings.http2.max_concurrent_streams)
.http2_max_header_list_size(settings.http2.max_header_list_size)
.http2_header_table_size(settings.http2.header_table_size)
.http2_enable_push(settings.http2.enable_push)
.http2_headers_priority(settings.http2.headers_priority)
.http2_headers_pseudo_order(settings.http2.headers_pseudo_order)
.http2_settings_order(settings.http2.settings_order)
}

/// Enable Encrypted Client Hello (Secure SNI)
Expand Down Expand Up @@ -787,33 +771,32 @@ impl ClientBuilder {
}

/// Only use HTTP/1.
/// Default is Http/1.
pub fn http1_only(mut self) -> ClientBuilder {
self.config.http_version_pref = HttpVersionPref::Http1;
self.config.tls.extension.http_version_pref = HttpVersionPref::Http1;
self
}

/// Allow HTTP/0.9 responses
#[cfg(feature = "http2")]
pub fn http09_responses(mut self) -> ClientBuilder {
self.config.builder.http09_responses(true);
self
}

/// Only use HTTP/2.
#[cfg(feature = "http2")]
pub fn http2_prior_knowledge(mut self) -> ClientBuilder {
pub fn http2_only(mut self) -> ClientBuilder {
#[cfg(feature = "boring-tls")]
{
self.config.tls.extension.http_version_pref = HttpVersionPref::Http2;
self.config.builder.http2_only(true);
}
self.config.builder.http2_only(true);

self
}

/// Sets the `SETTINGS_INITIAL_WINDOW_SIZE` option for HTTP2 stream-level flow control.
///
/// Default is currently 65,535 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
pub fn http2_initial_stream_window_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
self.config
.builder
Expand All @@ -824,7 +807,6 @@ impl ClientBuilder {
/// Sets the max connection-level flow control for HTTP2
///
/// Default is currently 65,535 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
pub fn http2_initial_connection_window_size(
mut self,
sz: impl Into<Option<u32>>,
Expand All @@ -839,7 +821,6 @@ impl ClientBuilder {
///
/// Enabling this will override the limits set in `http2_initial_stream_window_size` and
/// `http2_initial_connection_window_size`.
#[cfg(feature = "http2")]
pub fn http2_adaptive_window(mut self, enabled: bool) -> ClientBuilder {
self.config.builder.http2_adaptive_window(enabled);
self
Expand All @@ -848,7 +829,6 @@ impl ClientBuilder {
/// Sets the maximum frame size to use for HTTP2.
///
/// Default is currently 16,384 but may change internally to optimize for common uses.
#[cfg(feature = "http2")]
pub fn http2_max_frame_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
self.config.builder.http2_max_frame_size(sz.into());
self
Expand All @@ -857,7 +837,6 @@ impl ClientBuilder {
/// Sets the maximum concurrent streams to use for HTTP2.
///
/// Passing `None` will do nothing.
#[cfg(feature = "http2")]
pub fn http2_max_concurrent_streams(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
if let Some(max) = sz.into() {
self.config.builder.http2_max_concurrent_streams(max);
Expand All @@ -868,7 +847,6 @@ impl ClientBuilder {
/// Sets the max header list size to use for HTTP2.
///
/// Passing `None` will do nothing.
#[cfg(feature = "http2")]
pub fn http2_max_header_list_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
if let Some(sz) = sz.into() {
self.config.builder.http2_max_header_list_size(sz);
Expand All @@ -879,7 +857,6 @@ impl ClientBuilder {
/// Enables and disables the push feature for HTTP2.
///
/// Passing `None` will do nothing.
#[cfg(feature = "http2")]
pub fn http2_enable_push(mut self, sz: impl Into<Option<bool>>) -> ClientBuilder {
if let Some(sz) = sz.into() {
self.config.builder.http2_enable_push(sz);
Expand All @@ -890,7 +867,6 @@ impl ClientBuilder {
/// Sets the header table size to use for HTTP2.
///
/// Passing `None` will do nothing.
#[cfg(feature = "http2")]
pub fn http2_header_table_size(mut self, sz: impl Into<Option<u32>>) -> ClientBuilder {
if let Some(sz) = sz.into() {
self.config.builder.http2_header_table_size(sz);
Expand All @@ -901,7 +877,6 @@ impl ClientBuilder {
/// Sets the pseudo header order for HTTP2.
/// This is an array of 4 elements, each element is a `PseudoOrder` enum.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_headers_pseudo_order(
mut self,
order: impl Into<Option<[PseudoOrder; 4]>>,
Expand All @@ -912,7 +887,6 @@ impl ClientBuilder {

/// Sets the priority for HTTP2 headers.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_headers_priority(
mut self,
priority: impl Into<Option<StreamDependency>>,
Expand All @@ -924,7 +898,6 @@ impl ClientBuilder {
/// Sets the settings order for HTTP2.
/// This is an array of 2 elements, each element is a `SettingsOrder` enum.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_settings_order(
mut self,
order: impl Into<Option<[SettingsOrder; 2]>>,
Expand All @@ -937,7 +910,6 @@ impl ClientBuilder {
///
/// Pass `None` to disable HTTP2 keep-alive.
/// Default is currently disabled.
#[cfg(feature = "http2")]
pub fn http2_keep_alive_interval(
mut self,
interval: impl Into<Option<Duration>>,
Expand All @@ -953,7 +925,6 @@ impl ClientBuilder {
/// If the ping is not acknowledged within the timeout, the connection will be closed.
/// Does nothing if `http2_keep_alive_interval` is disabled.
/// Default is currently disabled.
#[cfg(feature = "http2")]
pub fn http2_keep_alive_timeout(mut self, timeout: Duration) -> ClientBuilder {
self.config.builder.http2_keep_alive_timeout(timeout);
self
Expand All @@ -965,7 +936,6 @@ impl ClientBuilder {
/// If enabled, pings are also sent when no streams are active.
/// Does nothing if `http2_keep_alive_interval` is disabled.
/// Default is `false`.
#[cfg(feature = "http2")]
pub fn http2_keep_alive_while_idle(mut self, enabled: bool) -> ClientBuilder {
self.config.builder.http2_keep_alive_while_idle(enabled);
self
Expand Down Expand Up @@ -1779,7 +1749,6 @@ impl PendingRequest {
}

fn retry_error(mut self: Pin<&mut Self>, err: &(dyn std::error::Error + 'static)) -> bool {
#[cfg(feature = "http2")]
if !is_retryable_error(err) {
return false;
}
Expand Down Expand Up @@ -1819,7 +1788,6 @@ impl PendingRequest {
}
}

#[cfg(feature = "http2")]
fn is_retryable_error(err: &(dyn std::error::Error + 'static)) -> bool {
if let Some(cause) = err.source() {
if let Some(err) = cause.downcast_ref::<h2::Error>() {
Expand Down
5 changes: 1 addition & 4 deletions src/blocking/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::tls::{Impersonate, TlsSettings, Version};
use crate::{async_impl, header, redirect, IntoUrl, Method, Proxy};
#[cfg(feature = "boring-tls")]
use header::HeaderMap;
#[cfg(feature = "http2")]
#[cfg(feature = "boring-tls")]
use hyper::{PseudoOrder, SettingsOrder, StreamDependency};

/// A `Client` to make Requests with.
Expand Down Expand Up @@ -582,7 +582,6 @@ impl ClientBuilder {
/// Sets the pseudo header order for HTTP2.
/// This is an array of 4 elements, each element is a `PseudoOrder` enum.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_headers_pseudo_order(
self,
order: impl Into<Option<[PseudoOrder; 4]>>,
Expand All @@ -592,7 +591,6 @@ impl ClientBuilder {

/// Sets the priority for HTTP2 headers.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_headers_priority(
self,
priority: impl Into<Option<StreamDependency>>,
Expand All @@ -603,7 +601,6 @@ impl ClientBuilder {
/// Sets the settings order for HTTP2.
/// This is an array of 2 elements, each element is a `SettingsOrder` enum.
/// Default is `None`.
#[cfg(feature = "http2")]
pub fn http2_settings_order(
self,
order: impl Into<Option<[SettingsOrder; 2]>>,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ pub use self::async_impl::{
};
pub use self::proxy::{NoProxy, Proxy};

#[cfg(all(feature = "boring-tls", feature = "http2"))]
#[cfg(feature = "boring-tls")]
pub use hyper::{PseudoOrder, SettingsOrder, StreamDependency, StreamId};

mod async_impl;
Expand Down
4 changes: 0 additions & 4 deletions src/tls/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl TlsExtension for SslConnectorBuilder {
HttpVersionPref::Http1 => {
self.set_alpn_protos(b"\x08http/1.1")?;
}
#[cfg(feature = "http2")]
HttpVersionPref::Http2 => {
self.set_alpn_protos(b"\x02h2")?;
}
Expand Down Expand Up @@ -363,10 +362,7 @@ impl TlsConnectExtension for ConnectConfiguration {

let (alpn, alpn_len) = match http_version {
HttpVersionPref::Http1 => ("http/1.1", 8),
#[cfg(feature = "http2")]
HttpVersionPref::Http2 | HttpVersionPref::All => ("h2", 2),
#[cfg(not(feature = "http2"))]
HttpVersionPref::All => ("http/1.1", 8),
};

unsafe {
Expand Down

0 comments on commit 11f2fd3

Please sign in to comment.