From 845301cb036db150044287a0cd49ac57e95240a6 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 29 Oct 2024 10:30:11 -0400 Subject: [PATCH 1/3] style: rustfmt the mutlipart file --- src/async_impl/multipart.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/async_impl/multipart.rs b/src/async_impl/multipart.rs index ac4b8b981..df4dc1272 100644 --- a/src/async_impl/multipart.rs +++ b/src/async_impl/multipart.rs @@ -270,8 +270,9 @@ impl Part { let len = file.metadata().await.map(|m| m.len()).ok(); let field = match len { Some(len) => Part::stream_with_length(file, len), - None => Part::stream(file) - }.mime(mime); + None => Part::stream(file), + } + .mime(mime); Ok(if let Some(file_name) = file_name { field.file_name(file_name) From 449f251bd2311a8ba73d550c6da3d3ff39d04ce8 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 29 Oct 2024 11:09:47 -0400 Subject: [PATCH 2/3] test: fix multipart async file knowing length instead of TE --- tests/multipart.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/multipart.rs b/tests/multipart.rs index bac6da314..78e170cbc 100644 --- a/tests/multipart.rs +++ b/tests/multipart.rs @@ -208,8 +208,11 @@ async fn async_impl_file_part() { async move { assert_eq!(req.method(), "POST"); assert_eq!(req.headers()["content-type"], ct); - assert_eq!(req.headers()["transfer-encoding"], "chunked"); - + // files know their exact size + assert_eq!( + req.headers()["content-length"], + expected_body.len().to_string() + ); let full = req.collect().await.unwrap().to_bytes(); assert_eq!(full, expected_body.as_bytes()); From 3f28983659ebff48bef8b2bd4af12ba9f9a15a55 Mon Sep 17 00:00:00 2001 From: Daniel Sharifi <40335219+DSharifi@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:24:33 +0100 Subject: [PATCH 3/3] feat: Add `http2_max_header_list_size` to the client builder (#2465) --- Cargo.toml | 4 ++-- src/async_impl/client.rs | 17 +++++++++++++++++ src/blocking/client.rs | 9 +++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9f8af88ef..39ff48424 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -122,7 +122,7 @@ encoding_rs = { version = "0.8", optional = true } http-body = "1" http-body-util = "0.1" hyper = { version = "1.1", features = ["http1", "client"] } -hyper-util = { version = "0.1.3", features = ["http1", "client", "client-legacy", "tokio"] } +hyper-util = { version = "0.1.10", features = ["http1", "client", "client-legacy", "tokio"] } h2 = { version = "0.4", optional = true } once_cell = "1.18" log = "0.4.17" @@ -173,7 +173,7 @@ futures-channel = { version = "0.3", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] env_logger = "0.10" hyper = { version = "1.1.0", default-features = false, features = ["http1", "http2", "client", "server"] } -hyper-util = { version = "0.1.3", features = ["http1", "http2", "client", "client-legacy", "server-auto", "tokio"] } +hyper-util = { version = "0.1.10", features = ["http1", "http2", "client", "client-legacy", "server-auto", "tokio"] } serde = { version = "1.0", features = ["derive"] } libflate = "2.1" brotli_crate = { package = "brotli", version = "6.0.0" } diff --git a/src/async_impl/client.rs b/src/async_impl/client.rs index 318217836..65e53ae26 100644 --- a/src/async_impl/client.rs +++ b/src/async_impl/client.rs @@ -145,6 +145,8 @@ struct Config { #[cfg(feature = "http2")] http2_max_frame_size: Option, #[cfg(feature = "http2")] + http2_max_header_list_size: Option, + #[cfg(feature = "http2")] http2_keep_alive_interval: Option, #[cfg(feature = "http2")] http2_keep_alive_timeout: Option, @@ -246,6 +248,8 @@ impl ClientBuilder { #[cfg(feature = "http2")] http2_max_frame_size: None, #[cfg(feature = "http2")] + http2_max_header_list_size: None, + #[cfg(feature = "http2")] http2_keep_alive_interval: None, #[cfg(feature = "http2")] http2_keep_alive_timeout: None, @@ -741,6 +745,9 @@ impl ClientBuilder { if let Some(http2_max_frame_size) = config.http2_max_frame_size { builder.http2_max_frame_size(http2_max_frame_size); } + if let Some(http2_max_header_list_size) = config.http2_max_header_list_size { + builder.http2_max_header_list_size(http2_max_header_list_size); + } if let Some(http2_keep_alive_interval) = config.http2_keep_alive_interval { builder.http2_keep_alive_interval(http2_keep_alive_interval); } @@ -1308,6 +1315,16 @@ impl ClientBuilder { self } + /// Sets the maximum size of received header frames for HTTP2. + /// + /// Default is currently 16KB, but can change. + #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] + pub fn http2_max_header_list_size(mut self, max_header_size_bytes: u32) -> ClientBuilder { + self.config.http2_max_header_list_size = Some(max_header_size_bytes); + self + } + /// Sets an interval for HTTP2 Ping frames should be sent to keep a connection alive. /// /// Pass `None` to disable HTTP2 keep-alive. diff --git a/src/blocking/client.rs b/src/blocking/client.rs index 7b5cafff1..fe7574689 100644 --- a/src/blocking/client.rs +++ b/src/blocking/client.rs @@ -502,6 +502,15 @@ impl ClientBuilder { self.with_inner(|inner| inner.http2_max_frame_size(sz)) } + /// Sets the maximum size of received header frames for HTTP2. + /// + /// Default is currently 16KB, but can change. + #[cfg(feature = "http2")] + #[cfg_attr(docsrs, doc(cfg(feature = "http2")))] + pub fn http2_max_header_list_size(self, max_header_size_bytes: u32) -> ClientBuilder { + self.with_inner(|inner| inner.http2_max_header_list_size(max_header_size_bytes)) + } + /// This requires the optional `http3` feature to be /// enabled. #[cfg(feature = "http3")]