Skip to content

Commit bff977b

Browse files
committedDec 9, 2021
feat(http2): add http2_max_send_buf_size option to client and server
This value is like a high-water mark. It applies per stream. Once a stream has buffered that amount of bytes to send, it won't poll more data from the `HttpBody` until the stream has been able to flush under it.
1 parent 84b78b6 commit bff977b

File tree

7 files changed

+68
-2
lines changed

7 files changed

+68
-2
lines changed
 

‎Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ http = "0.2"
3131
http-body = "0.4"
3232
httpdate = "1.0"
3333
httparse = "1.5.1"
34-
h2 = { version = "0.3.3", optional = true }
34+
h2 = { version = "0.3.9", optional = true }
3535
itoa = "0.4.1"
3636
tracing = { version = "0.1", default-features = false, features = ["std"] }
3737
pin-project-lite = "0.2.4"

‎src/client/client.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,20 @@ impl Builder {
12231223
self
12241224
}
12251225

1226+
/// Set the maximum write buffer size for each HTTP/2 stream.
1227+
///
1228+
/// Default is currently 1MB, but may change.
1229+
///
1230+
/// # Panics
1231+
///
1232+
/// The value must be no larger than `u32::MAX`.
1233+
#[cfg(feature = "http2")]
1234+
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
1235+
pub fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
1236+
self.conn_builder.http2_max_send_buf_size(max);
1237+
self
1238+
}
1239+
12261240
/// Set whether to retry requests that get disrupted before ever starting
12271241
/// to write.
12281242
///

‎src/client/conn.rs

+15
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,21 @@ impl Builder {
837837
self
838838
}
839839

840+
/// Set the maximum write buffer size for each HTTP/2 stream.
841+
///
842+
/// Default is currently 1MB, but may change.
843+
///
844+
/// # Panics
845+
///
846+
/// The value must be no larger than `u32::MAX`.
847+
#[cfg(feature = "http2")]
848+
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
849+
pub fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
850+
assert!(max <= std::u32::MAX as usize);
851+
self.h2_builder.max_send_buffer_size = max;
852+
self
853+
}
854+
840855
/// Constructs a connection with the configured options and IO.
841856
/// See [`client::conn`](crate::client::conn) for more.
842857
///

‎src/proto/h2/client.rs

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type ConnEof = oneshot::Receiver<Never>;
3636
const DEFAULT_CONN_WINDOW: u32 = 1024 * 1024 * 5; // 5mb
3737
const DEFAULT_STREAM_WINDOW: u32 = 1024 * 1024 * 2; // 2mb
3838
const DEFAULT_MAX_FRAME_SIZE: u32 = 1024 * 16; // 16kb
39+
const DEFAULT_MAX_SEND_BUF_SIZE: usize = 1024 * 1024; // 1mb
3940

4041
#[derive(Clone, Debug)]
4142
pub(crate) struct Config {
@@ -50,6 +51,7 @@ pub(crate) struct Config {
5051
#[cfg(feature = "runtime")]
5152
pub(crate) keep_alive_while_idle: bool,
5253
pub(crate) max_concurrent_reset_streams: Option<usize>,
54+
pub(crate) max_send_buffer_size: usize,
5355
}
5456

5557
impl Default for Config {
@@ -66,6 +68,7 @@ impl Default for Config {
6668
#[cfg(feature = "runtime")]
6769
keep_alive_while_idle: false,
6870
max_concurrent_reset_streams: None,
71+
max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE,
6972
}
7073
}
7174
}
@@ -76,6 +79,7 @@ fn new_builder(config: &Config) -> Builder {
7679
.initial_window_size(config.initial_stream_window_size)
7780
.initial_connection_window_size(config.initial_conn_window_size)
7881
.max_frame_size(config.max_frame_size)
82+
.max_send_buffer_size(config.max_send_buffer_size)
7983
.enable_push(false);
8084
if let Some(max) = config.max_concurrent_reset_streams {
8185
builder.max_concurrent_reset_streams(max);

‎src/proto/h2/server.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use crate::{Body, Response};
3333
const DEFAULT_CONN_WINDOW: u32 = 1024 * 1024; // 1mb
3434
const DEFAULT_STREAM_WINDOW: u32 = 1024 * 1024; // 1mb
3535
const DEFAULT_MAX_FRAME_SIZE: u32 = 1024 * 16; // 16kb
36+
const DEFAULT_MAX_SEND_BUF_SIZE: usize = 1024 * 400; // 400kb
3637

3738
#[derive(Clone, Debug)]
3839
pub(crate) struct Config {
@@ -45,6 +46,7 @@ pub(crate) struct Config {
4546
pub(crate) keep_alive_interval: Option<Duration>,
4647
#[cfg(feature = "runtime")]
4748
pub(crate) keep_alive_timeout: Duration,
49+
pub(crate) max_send_buffer_size: usize,
4850
}
4951

5052
impl Default for Config {
@@ -59,6 +61,7 @@ impl Default for Config {
5961
keep_alive_interval: None,
6062
#[cfg(feature = "runtime")]
6163
keep_alive_timeout: Duration::from_secs(20),
64+
max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE,
6265
}
6366
}
6467
}
@@ -109,7 +112,8 @@ where
109112
builder
110113
.initial_window_size(config.initial_stream_window_size)
111114
.initial_connection_window_size(config.initial_conn_window_size)
112-
.max_frame_size(config.max_frame_size);
115+
.max_frame_size(config.max_frame_size)
116+
.max_send_buffer_size(config.max_send_buffer_size);
113117
if let Some(max) = config.max_concurrent_streams {
114118
builder.max_concurrent_streams(max);
115119
}

‎src/server/conn.rs

+15
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,21 @@ impl<E> Http<E> {
543543
self
544544
}
545545

546+
/// Set the maximum write buffer size for each HTTP/2 stream.
547+
///
548+
/// Default is currently ~400KB, but may change.
549+
///
550+
/// # Panics
551+
///
552+
/// The value must be no larger than `u32::MAX`.
553+
#[cfg(feature = "http2")]
554+
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
555+
pub fn http2_max_send_buf_size(&mut self, max: usize) -> &mut Self {
556+
assert!(max <= std::u32::MAX as usize);
557+
self.h2_builder.max_send_buffer_size = max;
558+
self
559+
}
560+
546561
/// Set the maximum buffer size for the connection.
547562
///
548563
/// Default is ~400kb.

‎src/server/server.rs

+14
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,20 @@ impl<I, E> Builder<I, E> {
439439
self
440440
}
441441

442+
/// Set the maximum write buffer size for each HTTP/2 stream.
443+
///
444+
/// Default is currently ~400KB, but may change.
445+
///
446+
/// # Panics
447+
///
448+
/// The value must be no larger than `u32::MAX`.
449+
#[cfg(feature = "http2")]
450+
#[cfg_attr(docsrs, doc(cfg(feature = "http2")))]
451+
pub fn http2_max_send_buf_size(mut self, max: usize) -> Self {
452+
self.protocol.http2_max_send_buf_size(max);
453+
self
454+
}
455+
442456
/// Sets the `Executor` to deal with connection tasks.
443457
///
444458
/// Default is `tokio::spawn`.

0 commit comments

Comments
 (0)
Please sign in to comment.