Skip to content

Commit 02c01c7

Browse files
authored
Allow setting the HTTP/2 client header table size (#2582)
Adds a new `Endpoint` builder method which forwards the HTTP2 header table size setting to `h2`. Follows in the footsteps of other `http_` builder methods.
1 parent 3185354 commit 02c01c7

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use std::time::Duration;
2+
3+
use integration_tests::pb::{test_client, test_server, Input, Output};
4+
use tokio::sync::oneshot;
5+
use tonic::{
6+
transport::{Endpoint, Server},
7+
Request, Response, Status,
8+
};
9+
10+
#[tokio::test]
11+
async fn http2_header_table_size_zero() {
12+
struct Svc;
13+
14+
#[tonic::async_trait]
15+
impl test_server::Test for Svc {
16+
async fn unary_call(&self, _: Request<Input>) -> Result<Response<Output>, Status> {
17+
Ok(Response::new(Output {}))
18+
}
19+
}
20+
21+
let svc = test_server::TestServer::new(Svc);
22+
23+
let (tx, rx) = oneshot::channel::<()>();
24+
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
25+
let addr = format!("http://{}", listener.local_addr().unwrap());
26+
27+
let jh = tokio::spawn(async move {
28+
let listener =
29+
tonic::transport::server::TcpIncoming::from(listener).with_nodelay(Some(true));
30+
Server::builder()
31+
.add_service(svc)
32+
.serve_with_incoming_shutdown(listener, async { drop(rx.await) })
33+
.await
34+
.unwrap();
35+
});
36+
37+
tokio::time::sleep(Duration::from_millis(100)).await;
38+
39+
let channel = Endpoint::from_shared(addr)
40+
.unwrap()
41+
.http2_header_table_size(0)
42+
.connect()
43+
.await
44+
.unwrap();
45+
46+
let mut client = test_client::TestClient::new(channel);
47+
48+
client.unary_call(Request::new(Input {})).await.unwrap();
49+
50+
tx.send(()).unwrap();
51+
jh.await.unwrap();
52+
}

tonic/src/transport/channel/endpoint.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub struct Endpoint {
4949
pub(crate) http2_keep_alive_interval: Option<Duration>,
5050
pub(crate) http2_keep_alive_timeout: Option<Duration>,
5151
pub(crate) http2_keep_alive_while_idle: Option<bool>,
52+
pub(crate) http2_header_table_size: Option<u32>,
5253
pub(crate) http2_max_header_list_size: Option<u32>,
5354
pub(crate) connect_timeout: Option<Duration>,
5455
pub(crate) http2_adaptive_window: Option<bool>,
@@ -96,6 +97,7 @@ impl Endpoint {
9697
http2_keep_alive_interval: None,
9798
http2_keep_alive_timeout: None,
9899
http2_keep_alive_while_idle: None,
100+
http2_header_table_size: None,
99101
http2_max_header_list_size: None,
100102
connect_timeout: None,
101103
http2_adaptive_window: None,
@@ -125,6 +127,7 @@ impl Endpoint {
125127
http2_keep_alive_interval: None,
126128
http2_keep_alive_timeout: None,
127129
http2_keep_alive_while_idle: None,
130+
http2_header_table_size: None,
128131
http2_max_header_list_size: None,
129132
connect_timeout: None,
130133
http2_adaptive_window: None,
@@ -458,6 +461,19 @@ impl Endpoint {
458461
}
459462
}
460463

464+
/// Sets the `SETTINGS_HEADER_TABLE_SIZE` option for HTTP2 connections.
465+
///
466+
/// Informs the peer of the maximum size of the header compression
467+
/// table used to decode header blocks, in octets.
468+
///
469+
/// Default is 4,096.
470+
pub fn http2_header_table_size(self, size: u32) -> Self {
471+
Endpoint {
472+
http2_header_table_size: Some(size),
473+
..self
474+
}
475+
}
476+
461477
/// Sets the max size of received header frames.
462478
///
463479
/// This will default to whatever the default in hyper is. As of v1.4.1, it is 16 KiB.

tonic/src/transport/channel/service/connection.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ impl Connection {
5151
settings.adaptive_window(val);
5252
}
5353

54+
if let Some(val) = endpoint.http2_header_table_size {
55+
settings.header_table_size(val);
56+
}
57+
5458
if let Some(val) = endpoint.http2_max_header_list_size {
5559
settings.max_header_list_size(val);
5660
}

0 commit comments

Comments
 (0)