Skip to content

Commit 4c84e8c

Browse files
authored
feat(client): Add HTTP/2 builder options header_table_size() and max_concurrent_streams() (#3731)
1 parent 450b3b6 commit 4c84e8c

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

src/client/conn/http2.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,9 @@ where
337337

338338
/// Sets the maximum frame size to use for HTTP2.
339339
///
340-
/// Passing `None` will do nothing.
341-
///
342-
/// If not set, hyper will use a default.
340+
/// Default is currently 16KB, but can change.
343341
pub fn max_frame_size(&mut self, sz: impl Into<Option<u32>>) -> &mut Self {
344-
if let Some(sz) = sz.into() {
345-
self.h2_builder.max_frame_size = sz;
346-
}
342+
self.h2_builder.max_frame_size = sz.into();
347343
self
348344
}
349345

@@ -355,6 +351,46 @@ where
355351
self
356352
}
357353

354+
/// Sets the header table size.
355+
///
356+
/// This setting informs the peer of the maximum size of the header compression
357+
/// table used to encode header blocks, in octets. The encoder may select any value
358+
/// equal to or less than the header table size specified by the sender.
359+
///
360+
/// The default value of crate `h2` is 4,096.
361+
pub fn header_table_size(&mut self, size: impl Into<Option<u32>>) -> &mut Self {
362+
self.h2_builder.header_table_size = size.into();
363+
self
364+
}
365+
366+
/// Sets the maximum number of concurrent streams.
367+
///
368+
/// The maximum concurrent streams setting only controls the maximum number
369+
/// of streams that can be initiated by the remote peer. In other words,
370+
/// when this setting is set to 100, this does not limit the number of
371+
/// concurrent streams that can be created by the caller.
372+
///
373+
/// It is recommended that this value be no smaller than 100, so as to not
374+
/// unnecessarily limit parallelism. However, any value is legal, including
375+
/// 0. If `max` is set to 0, then the remote will not be permitted to
376+
/// initiate streams.
377+
///
378+
/// Note that streams in the reserved state, i.e., push promises that have
379+
/// been reserved but the stream has not started, do not count against this
380+
/// setting.
381+
///
382+
/// Also note that if the remote *does* exceed the value set here, it is not
383+
/// a protocol level error. Instead, the `h2` library will immediately reset
384+
/// the stream.
385+
///
386+
/// See [Section 5.1.2] in the HTTP/2 spec for more details.
387+
///
388+
/// [Section 5.1.2]: https://http2.github.io/http2-spec/#rfc.section.5.1.2
389+
pub fn max_concurrent_streams(&mut self, max: impl Into<Option<u32>>) -> &mut Self {
390+
self.h2_builder.max_concurrent_streams = max.into();
391+
self
392+
}
393+
358394
/// Sets an interval for HTTP2 Ping frames should be sent to keep a
359395
/// connection alive.
360396
///

src/proto/h2/client.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,16 @@ pub(crate) struct Config {
6868
pub(crate) initial_conn_window_size: u32,
6969
pub(crate) initial_stream_window_size: u32,
7070
pub(crate) initial_max_send_streams: usize,
71-
pub(crate) max_frame_size: u32,
71+
pub(crate) max_frame_size: Option<u32>,
7272
pub(crate) max_header_list_size: u32,
7373
pub(crate) keep_alive_interval: Option<Duration>,
7474
pub(crate) keep_alive_timeout: Duration,
7575
pub(crate) keep_alive_while_idle: bool,
7676
pub(crate) max_concurrent_reset_streams: Option<usize>,
7777
pub(crate) max_send_buffer_size: usize,
7878
pub(crate) max_pending_accept_reset_streams: Option<usize>,
79+
pub(crate) header_table_size: Option<u32>,
80+
pub(crate) max_concurrent_streams: Option<u32>,
7981
}
8082

8183
impl Default for Config {
@@ -85,14 +87,16 @@ impl Default for Config {
8587
initial_conn_window_size: DEFAULT_CONN_WINDOW,
8688
initial_stream_window_size: DEFAULT_STREAM_WINDOW,
8789
initial_max_send_streams: DEFAULT_INITIAL_MAX_SEND_STREAMS,
88-
max_frame_size: DEFAULT_MAX_FRAME_SIZE,
90+
max_frame_size: Some(DEFAULT_MAX_FRAME_SIZE),
8991
max_header_list_size: DEFAULT_MAX_HEADER_LIST_SIZE,
9092
keep_alive_interval: None,
9193
keep_alive_timeout: Duration::from_secs(20),
9294
keep_alive_while_idle: false,
9395
max_concurrent_reset_streams: None,
9496
max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE,
9597
max_pending_accept_reset_streams: None,
98+
header_table_size: None,
99+
max_concurrent_streams: None,
96100
}
97101
}
98102
}
@@ -103,16 +107,24 @@ fn new_builder(config: &Config) -> Builder {
103107
.initial_max_send_streams(config.initial_max_send_streams)
104108
.initial_window_size(config.initial_stream_window_size)
105109
.initial_connection_window_size(config.initial_conn_window_size)
106-
.max_frame_size(config.max_frame_size)
107110
.max_header_list_size(config.max_header_list_size)
108111
.max_send_buffer_size(config.max_send_buffer_size)
109112
.enable_push(false);
113+
if let Some(max) = config.max_frame_size {
114+
builder.max_frame_size(max);
115+
}
110116
if let Some(max) = config.max_concurrent_reset_streams {
111117
builder.max_concurrent_reset_streams(max);
112118
}
113119
if let Some(max) = config.max_pending_accept_reset_streams {
114120
builder.max_pending_accept_reset_streams(max);
115121
}
122+
if let Some(size) = config.header_table_size {
123+
builder.header_table_size(size);
124+
}
125+
if let Some(max) = config.max_concurrent_streams {
126+
builder.max_concurrent_streams(max);
127+
}
116128
builder
117129
}
118130

0 commit comments

Comments
 (0)