diff --git a/poem-grpc/CHANGELOG.md b/poem-grpc/CHANGELOG.md index 490e3f4792..e495c2361f 100644 --- a/poem-grpc/CHANGELOG.md +++ b/poem-grpc/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [0.5.2] 2024-11-20 + +- Add `ClientConfigBuilder::http2_max_header_list_size` method to set the max size of received header frames. + # [0.5.1] 2024-09-12 - set the correct `content-type` for `GrpcClient` diff --git a/poem-grpc/Cargo.toml b/poem-grpc/Cargo.toml index 6094f48ca3..216acde75c 100644 --- a/poem-grpc/Cargo.toml +++ b/poem-grpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poem-grpc" -version = "0.5.1" +version = "0.5.2" authors.workspace = true edition.workspace = true license.workspace = true @@ -42,7 +42,7 @@ thiserror.workspace = true fastrand = "2.0.0" http.workspace = true hyper = { version = "1.0.0", features = ["http1", "http2"] } -hyper-util = { version = "0.1.3", features = ["client-legacy", "tokio"] } +hyper-util = { version = "0.1.10", features = ["client-legacy", "tokio"] } http-body-util = "0.1.0" tokio-rustls.workspace = true tower-service = "0.3.2" diff --git a/poem-grpc/src/client.rs b/poem-grpc/src/client.rs index da9861e2a9..560ac58068 100644 --- a/poem-grpc/src/client.rs +++ b/poem-grpc/src/client.rs @@ -27,19 +27,25 @@ use crate::{ pub(crate) type BoxBody = http_body_util::combinators::BoxBody; /// A configuration for GRPC client -#[derive(Default)] pub struct ClientConfig { uris: Vec, origin: Option, user_agent: Option, tls_config: Option, + max_header_list_size: u32, } impl ClientConfig { /// Create a `ClientConfig` builder pub fn builder() -> ClientConfigBuilder { ClientConfigBuilder { - config: Ok(ClientConfig::default()), + config: Ok(ClientConfig { + uris: vec![], + origin: None, + user_agent: None, + tls_config: None, + max_header_list_size: 16384, + }), } } } @@ -146,6 +152,16 @@ impl ClientConfigBuilder { self } + /// Sets the max size of received header frames. + /// + /// Default is `16384` bytes. + pub fn http2_max_header_list_size(mut self, max: u32) -> Self { + if let Ok(config) = &mut self.config { + config.max_header_list_size = max; + } + self + } + /// Consumes this builder and returns the `ClientConfig` pub fn build(self) -> Result { self.config @@ -451,6 +467,7 @@ fn create_client_endpoint( let mut config = config; let cli = Client::builder(TokioExecutor::new()) .http2_only(true) + .http2_max_header_list_size(config.max_header_list_size) .build(HttpsConnector::new(config.tls_config.take())); let config = Arc::new(config); diff --git a/poem/CHANGELOG.md b/poem/CHANGELOG.md index 54e93bb5cf..e0f290284b 100644 --- a/poem/CHANGELOG.md +++ b/poem/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [3.1.4] 2024-11-20 + +- Add `Server::http2_max_header_list_size` method to set the max size of received header frames. + # [3.1.3] 2024-10-21 - Add `Middlware::combine_if` method. diff --git a/poem/Cargo.toml b/poem/Cargo.toml index ddf1f0a177..ba51e6815e 100644 --- a/poem/Cargo.toml +++ b/poem/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poem" -version = "3.1.3" +version = "3.1.4" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/poem/src/server.rs b/poem/src/server.rs index 8113c96495..551e5ed3d9 100644 --- a/poem/src/server.rs +++ b/poem/src/server.rs @@ -44,6 +44,7 @@ pub struct Server { idle_timeout: Option, http2_max_concurrent_streams: Option, http2_max_pending_accept_reset_streams: Option, + http2_max_header_list_size: u32, } impl Server { @@ -55,6 +56,7 @@ impl Server { idle_timeout: None, http2_max_concurrent_streams: None, http2_max_pending_accept_reset_streams: Some(20), + http2_max_header_list_size: 16384, } } } @@ -68,6 +70,7 @@ impl Server { idle_timeout: None, http2_max_concurrent_streams: None, http2_max_pending_accept_reset_streams: Some(20), + http2_max_header_list_size: 16384, } } } @@ -110,6 +113,16 @@ where } } + /// Sets the max size of received header frames. + /// + /// Default is `16384` bytes. + pub fn http2_max_header_list_size(self, max: u32) -> Self { + Self { + http2_max_header_list_size: max, + ..self + } + } + /// Configures the maximum number of pending reset streams allowed before a /// GOAWAY will be sent. /// @@ -150,6 +163,7 @@ where idle_timeout, http2_max_concurrent_streams, http2_max_pending_accept_reset_streams, + http2_max_header_list_size, } = self; let name = name.as_deref(); let alive_connections = Arc::new(AtomicUsize::new(0)); @@ -212,6 +226,7 @@ where idle_connection_close_timeout: idle_timeout, http2_max_concurrent_streams, http2_max_pending_accept_reset_streams, + http2_max_header_list_size, }); if timeout.is_some() { @@ -376,10 +391,14 @@ struct ConnectionOptions { idle_connection_close_timeout: Option, http2_max_concurrent_streams: Option, http2_max_pending_accept_reset_streams: Option, + http2_max_header_list_size: u32, } -async fn serve_connection( - ConnectionOptions { +async fn serve_connection(opts: ConnectionOptions) +where + Io: AsyncRead + AsyncWrite + Send + Unpin + 'static, +{ + let ConnectionOptions { socket, local_addr, remote_addr, @@ -389,10 +408,9 @@ async fn serve_connection( idle_connection_close_timeout, http2_max_concurrent_streams, http2_max_pending_accept_reset_streams, - }: ConnectionOptions, -) where - Io: AsyncRead + AsyncWrite + Send + Unpin + 'static, -{ + http2_max_header_list_size, + } = opts; + let connection_shutdown_token = CancellationToken::new(); let service = hyper::service::service_fn({ @@ -435,7 +453,8 @@ async fn serve_connection( .max_concurrent_streams(http2_max_concurrent_streams) .max_pending_accept_reset_streams( http2_max_pending_accept_reset_streams.map(|x| x as usize), - ); + ) + .max_header_list_size(http2_max_header_list_size); let conn = builder.serve_connection_with_upgrades(hyper_util::rt::TokioIo::new(socket), service);