From baf7647ef615ebbf29a6473af3329f4f28f13daf Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sat, 10 Aug 2024 18:06:25 +0800 Subject: [PATCH 1/9] feat(client): Add more Http2 client settings options --- src/client/conn/http2.rs | 57 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index aee135f672..1baf43373a 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -355,6 +355,63 @@ 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>) -> &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 { + 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>) -> &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. /// From 59f4e34bc43628e52916ea1d9bb83684cdd19158 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sat, 10 Aug 2024 18:08:17 +0800 Subject: [PATCH 2/9] cargo fmt --all --- src/client/conn/http2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index 1baf43373a..33988430bf 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -355,7 +355,7 @@ where self } - /// Sets the header table size. + /// 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 From 5f90f664def7660a47ef7345b112002eb752c376 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sat, 10 Aug 2024 18:15:39 +0800 Subject: [PATCH 3/9] Update h2 client config --- src/proto/h2/client.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/proto/h2/client.rs b/src/proto/h2/client.rs index 679b9dfada..c855959a66 100644 --- a/src/proto/h2/client.rs +++ b/src/proto/h2/client.rs @@ -68,7 +68,7 @@ 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, pub(crate) max_header_list_size: u32, pub(crate) keep_alive_interval: Option, pub(crate) keep_alive_timeout: Duration, @@ -76,6 +76,9 @@ pub(crate) struct Config { pub(crate) max_concurrent_reset_streams: Option, pub(crate) max_send_buffer_size: usize, pub(crate) max_pending_accept_reset_streams: Option, + pub(crate) header_table_size: Option, + pub(crate) enable_push: bool, + pub(crate) max_concurrent_streams: Option, } impl Default for Config { @@ -85,7 +88,7 @@ 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), @@ -93,6 +96,9 @@ impl Default for Config { 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, } } } @@ -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 } From fc5a3f406575afbac0ecf8437d4b25fc391aece5 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sat, 10 Aug 2024 18:18:38 +0800 Subject: [PATCH 4/9] Update h2 client config --- src/client/conn/http2.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index 33988430bf..429fe89555 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -341,9 +341,7 @@ where /// /// If not set, hyper will use a default. pub fn max_frame_size(&mut self, sz: impl Into>) -> &mut Self { - if let Some(sz) = sz.into() { - self.h2_builder.max_frame_size = sz; - } + self.h2_builder.max_frame_size = sz.into(); self } From 30ed486d781eaa2e25854f8f742945bf3415ed1e Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Sat, 10 Aug 2024 18:20:10 +0800 Subject: [PATCH 5/9] cargo fmt --- src/client/conn/http2.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index 429fe89555..fc0e9aa2a4 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -409,7 +409,6 @@ where self } - /// Sets an interval for HTTP2 Ping frames should be sent to keep a /// connection alive. /// From f6140cc918851a3b3b32b650f3dae1e4e591e6e8 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Tue, 13 Aug 2024 06:36:36 +0800 Subject: [PATCH 6/9] Enable push default value is `false` --- src/client/conn/http2.rs | 2 +- src/proto/h2/client.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index fc0e9aa2a4..48a1eecdfa 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -375,7 +375,7 @@ where /// 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`. + /// Default value of crate `h2`: `false`. pub fn enable_push(&mut self, enabled: bool) -> &mut Self { self.h2_builder.enable_push = enabled; self diff --git a/src/proto/h2/client.rs b/src/proto/h2/client.rs index 4477a60c37..2e68099d1d 100644 --- a/src/proto/h2/client.rs +++ b/src/proto/h2/client.rs @@ -97,7 +97,7 @@ impl Default for Config { max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE, max_pending_accept_reset_streams: None, header_table_size: None, - enable_push: true, + enable_push: false, max_concurrent_streams: None, } } From 648f9aadc7d551f2d1cd57628fc31f3d865318b2 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Tue, 13 Aug 2024 16:59:15 +0800 Subject: [PATCH 7/9] Added when `enable push` is None --- src/client/conn/http2.rs | 4 ++-- src/proto/h2/client.rs | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index 48a1eecdfa..dc636b604f 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -376,8 +376,8 @@ where /// connection by sending another settings frame updating the value. /// /// Default value of crate `h2`: `false`. - pub fn enable_push(&mut self, enabled: bool) -> &mut Self { - self.h2_builder.enable_push = enabled; + pub fn enable_push(&mut self, enabled: impl Into>) -> &mut Self { + self.h2_builder.enable_push = enabled.into(); self } diff --git a/src/proto/h2/client.rs b/src/proto/h2/client.rs index 2e68099d1d..6ddfaee6bf 100644 --- a/src/proto/h2/client.rs +++ b/src/proto/h2/client.rs @@ -77,7 +77,7 @@ pub(crate) struct Config { pub(crate) max_send_buffer_size: usize, pub(crate) max_pending_accept_reset_streams: Option, pub(crate) header_table_size: Option, - pub(crate) enable_push: bool, + pub(crate) enable_push: Option, pub(crate) max_concurrent_streams: Option, } @@ -97,7 +97,7 @@ impl Default for Config { max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE, max_pending_accept_reset_streams: None, header_table_size: None, - enable_push: false, + enable_push: Some(false), max_concurrent_streams: None, } } @@ -110,8 +110,10 @@ fn new_builder(config: &Config) -> Builder { .initial_window_size(config.initial_stream_window_size) .initial_connection_window_size(config.initial_conn_window_size) .max_header_list_size(config.max_header_list_size) - .max_send_buffer_size(config.max_send_buffer_size) - .enable_push(config.enable_push); + .max_send_buffer_size(config.max_send_buffer_size); + if let Some(enabled) = config.enable_push { + builder.enable_push(enabled); + } if let Some(max) = config.max_frame_size { builder.max_frame_size(max); } From 5bcf313d4f97fa6e19bb5db962b2f73f83c40f27 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Tue, 13 Aug 2024 17:14:54 +0800 Subject: [PATCH 8/9] Update docs --- src/client/conn/http2.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index dc636b604f..7f7d428b4f 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -337,9 +337,7 @@ where /// Sets the maximum frame size to use for HTTP2. /// - /// Passing `None` will do nothing. - /// - /// If not set, hyper will use a default. + /// Default is currently 16KB, but can change. pub fn max_frame_size(&mut self, sz: impl Into>) -> &mut Self { self.h2_builder.max_frame_size = sz.into(); self @@ -375,7 +373,7 @@ where /// 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`: `false`. + /// If not set, hyper will use a default. pub fn enable_push(&mut self, enabled: impl Into>) -> &mut Self { self.h2_builder.enable_push = enabled.into(); self From a793fb30ae2c23aa897fe9eeb5660b84a5af2775 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Wed, 14 Aug 2024 06:23:09 +0800 Subject: [PATCH 9/9] Revert "Added when `enable push` is None" This reverts commit 648f9aadc7d551f2d1cd57628fc31f3d865318b2. --- src/client/conn/http2.rs | 16 ---------------- src/proto/h2/client.rs | 8 ++------ 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/client/conn/http2.rs b/src/client/conn/http2.rs index 7f7d428b4f..ce86c6dcb4 100644 --- a/src/client/conn/http2.rs +++ b/src/client/conn/http2.rs @@ -363,22 +363,6 @@ where 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. - /// - /// If not set, hyper will use a default. - pub fn enable_push(&mut self, enabled: impl Into>) -> &mut Self { - self.h2_builder.enable_push = enabled.into(); - self - } - /// Sets the maximum number of concurrent streams. /// /// The maximum concurrent streams setting only controls the maximum number diff --git a/src/proto/h2/client.rs b/src/proto/h2/client.rs index 6ddfaee6bf..4945626bf7 100644 --- a/src/proto/h2/client.rs +++ b/src/proto/h2/client.rs @@ -77,7 +77,6 @@ pub(crate) struct Config { pub(crate) max_send_buffer_size: usize, pub(crate) max_pending_accept_reset_streams: Option, pub(crate) header_table_size: Option, - pub(crate) enable_push: Option, pub(crate) max_concurrent_streams: Option, } @@ -97,7 +96,6 @@ impl Default for Config { max_send_buffer_size: DEFAULT_MAX_SEND_BUF_SIZE, max_pending_accept_reset_streams: None, header_table_size: None, - enable_push: Some(false), max_concurrent_streams: None, } } @@ -110,10 +108,8 @@ fn new_builder(config: &Config) -> Builder { .initial_window_size(config.initial_stream_window_size) .initial_connection_window_size(config.initial_conn_window_size) .max_header_list_size(config.max_header_list_size) - .max_send_buffer_size(config.max_send_buffer_size); - if let Some(enabled) = config.enable_push { - builder.enable_push(enabled); - } + .max_send_buffer_size(config.max_send_buffer_size) + .enable_push(false); if let Some(max) = config.max_frame_size { builder.max_frame_size(max); }