Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): Add more Http2 client settings options #3731

Merged
merged 10 commits into from
Aug 16, 2024
60 changes: 57 additions & 3 deletions src/client/conn/http2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,7 @@ where
///
/// If not set, hyper will use a default.
pub fn max_frame_size(&mut self, sz: impl Into<Option<u32>>) -> &mut Self {
if let Some(sz) = sz.into() {
self.h2_builder.max_frame_size = sz;
}
self.h2_builder.max_frame_size = sz.into();
self
}

Expand All @@ -355,6 +353,62 @@ where
self
}

/// Sets the header table size.
///
/// This setting informs the peer of the maximum size of the header compression
/// table used to encode header blocks, in octets. The encoder may select any value
/// equal to or less than the header table size specified by the sender.
///
/// The default value of crate `h2` is 4,096.
pub fn header_table_size(&mut self, size: impl Into<Option<u32>>) -> &mut Self {
self.h2_builder.header_table_size = size.into();
self
}

/// Enables or disables server push promises.
///
/// This value is included in the initial SETTINGS handshake.
/// Setting this value to value to
/// false in the initial SETTINGS handshake guarantees that the remote server
/// will never send a push promise.
///
/// This setting can be changed during the life of a single HTTP/2
/// connection by sending another settings frame updating the value.
///
/// Default value of crate `h2`: `true`.
pub fn enable_push(&mut self, enabled: bool) -> &mut Self {
0x676e67 marked this conversation as resolved.
Show resolved Hide resolved
self.h2_builder.enable_push = enabled;
self
}

/// Sets the maximum number of concurrent streams.
///
/// The maximum concurrent streams setting only controls the maximum number
/// of streams that can be initiated by the remote peer. In other words,
/// when this setting is set to 100, this does not limit the number of
/// concurrent streams that can be created by the caller.
///
/// It is recommended that this value be no smaller than 100, so as to not
/// unnecessarily limit parallelism. However, any value is legal, including
/// 0. If `max` is set to 0, then the remote will not be permitted to
/// initiate streams.
///
/// Note that streams in the reserved state, i.e., push promises that have
/// been reserved but the stream has not started, do not count against this
/// setting.
///
/// Also note that if the remote *does* exceed the value set here, it is not
/// a protocol level error. Instead, the `h2` library will immediately reset
/// the stream.
///
/// See [Section 5.1.2] in the HTTP/2 spec for more details.
///
/// [Section 5.1.2]: https://http2.github.io/http2-spec/#rfc.section.5.1.2
pub fn max_concurrent_streams(&mut self, max: impl Into<Option<u32>>) -> &mut Self {
self.h2_builder.max_concurrent_streams = max.into();
self
}

/// Sets an interval for HTTP2 Ping frames should be sent to keep a
/// connection alive.
///
Expand Down
22 changes: 18 additions & 4 deletions src/proto/h2/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ pub(crate) struct Config {
pub(crate) initial_conn_window_size: u32,
pub(crate) initial_stream_window_size: u32,
pub(crate) initial_max_send_streams: usize,
pub(crate) max_frame_size: u32,
pub(crate) max_frame_size: Option<u32>,
pub(crate) max_header_list_size: u32,
pub(crate) keep_alive_interval: Option<Duration>,
pub(crate) keep_alive_timeout: Duration,
pub(crate) keep_alive_while_idle: bool,
pub(crate) max_concurrent_reset_streams: Option<usize>,
pub(crate) max_send_buffer_size: usize,
pub(crate) max_pending_accept_reset_streams: Option<usize>,
pub(crate) header_table_size: Option<u32>,
pub(crate) enable_push: bool,
pub(crate) max_concurrent_streams: Option<u32>,
}

impl Default for Config {
Expand All @@ -85,14 +88,17 @@ impl Default for Config {
initial_conn_window_size: DEFAULT_CONN_WINDOW,
initial_stream_window_size: DEFAULT_STREAM_WINDOW,
initial_max_send_streams: DEFAULT_INITIAL_MAX_SEND_STREAMS,
max_frame_size: DEFAULT_MAX_FRAME_SIZE,
max_frame_size: Some(DEFAULT_MAX_FRAME_SIZE),
max_header_list_size: DEFAULT_MAX_HEADER_LIST_SIZE,
keep_alive_interval: None,
keep_alive_timeout: Duration::from_secs(20),
keep_alive_while_idle: false,
max_concurrent_reset_streams: None,
max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE,
max_pending_accept_reset_streams: None,
header_table_size: None,
enable_push: true,
max_concurrent_streams: None,
}
}
}
Expand All @@ -103,16 +109,24 @@ fn new_builder(config: &Config) -> Builder {
.initial_max_send_streams(config.initial_max_send_streams)
.initial_window_size(config.initial_stream_window_size)
.initial_connection_window_size(config.initial_conn_window_size)
.max_frame_size(config.max_frame_size)
.max_header_list_size(config.max_header_list_size)
.max_send_buffer_size(config.max_send_buffer_size)
.enable_push(false);
.enable_push(config.enable_push);
if let Some(max) = config.max_frame_size {
builder.max_frame_size(max);
}
if let Some(max) = config.max_concurrent_reset_streams {
builder.max_concurrent_reset_streams(max);
}
if let Some(max) = config.max_pending_accept_reset_streams {
builder.max_pending_accept_reset_streams(max);
}
if let Some(size) = config.header_table_size {
builder.header_table_size(size);
}
if let Some(max) = config.max_concurrent_streams {
builder.max_concurrent_streams(max);
}
builder
}

Expand Down