Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90af7b9da9 | ||
|
|
f486fc3adc | ||
|
|
7af4adf829 | ||
|
|
4e6d835094 |
@@ -1022,6 +1022,39 @@ impl Builder {
|
||||
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 is 4,096.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use tokio::io::{AsyncRead, AsyncWrite};
|
||||
/// # use h2::client::*;
|
||||
/// # use bytes::Bytes;
|
||||
/// #
|
||||
/// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
|
||||
/// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
|
||||
/// # {
|
||||
/// // `client_fut` is a future representing the completion of the HTTP/2
|
||||
/// // handshake.
|
||||
/// let client_fut = Builder::new()
|
||||
/// .header_table_size(1_000_000)
|
||||
/// .handshake(my_io);
|
||||
/// # client_fut.await
|
||||
/// # }
|
||||
/// #
|
||||
/// # pub fn main() {}
|
||||
/// ```
|
||||
pub fn header_table_size(&mut self, size: u32) -> &mut Self {
|
||||
self.settings.set_header_table_size(Some(size));
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the first stream ID to something other than 1.
|
||||
#[cfg(feature = "unstable")]
|
||||
pub fn initial_stream_id(&mut self, stream_id: u32) -> &mut Self {
|
||||
|
||||
@@ -88,6 +88,12 @@ impl<T> FramedRead<T> {
|
||||
pub fn set_max_header_list_size(&mut self, val: usize) {
|
||||
self.max_header_list_size = val;
|
||||
}
|
||||
|
||||
/// Update the header table size setting.
|
||||
#[inline]
|
||||
pub fn set_header_table_size(&mut self, val: usize) {
|
||||
self.hpack.queue_size_update(val);
|
||||
}
|
||||
}
|
||||
|
||||
/// Decodes a frame.
|
||||
|
||||
@@ -95,6 +95,11 @@ impl<T, B> Codec<T, B> {
|
||||
self.framed_write().set_header_table_size(val)
|
||||
}
|
||||
|
||||
/// Set the decoder header table size size.
|
||||
pub fn set_recv_header_table_size(&mut self, val: usize) {
|
||||
self.inner.set_header_table_size(val)
|
||||
}
|
||||
|
||||
/// Set the max header list size that can be received.
|
||||
pub fn set_max_recv_header_list_size(&mut self, val: usize) {
|
||||
self.inner.set_max_header_list_size(val);
|
||||
|
||||
@@ -686,14 +686,14 @@ impl Iterator for Iter {
|
||||
return Some(Method(method));
|
||||
}
|
||||
|
||||
if let Some(scheme) = pseudo.scheme.take() {
|
||||
return Some(Scheme(scheme));
|
||||
}
|
||||
|
||||
if let Some(authority) = pseudo.authority.take() {
|
||||
return Some(Authority(authority));
|
||||
}
|
||||
|
||||
if let Some(scheme) = pseudo.scheme.take() {
|
||||
return Some(Scheme(scheme));
|
||||
}
|
||||
|
||||
if let Some(path) = pseudo.path.take() {
|
||||
return Some(Path(path));
|
||||
}
|
||||
|
||||
@@ -121,11 +121,9 @@ impl Settings {
|
||||
self.header_table_size
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn set_header_table_size(&mut self, size: Option<u32>) {
|
||||
self.header_table_size = size;
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn load(head: Head, payload: &[u8]) -> Result<Settings, Error> {
|
||||
use self::Setting::*;
|
||||
|
||||
@@ -60,6 +60,10 @@ impl Settings {
|
||||
codec.set_max_recv_header_list_size(max as usize);
|
||||
}
|
||||
|
||||
if let Some(val) = local.header_table_size() {
|
||||
codec.set_recv_header_table_size(val as usize);
|
||||
}
|
||||
|
||||
streams.apply_local_settings(local)?;
|
||||
self.local = Local::Synced;
|
||||
Ok(())
|
||||
|
||||
@@ -372,6 +372,11 @@ impl Mock<frame::Settings> {
|
||||
self.0.set_enable_connect_protocol(Some(val));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn header_table_size(mut self, val: u32) -> Self {
|
||||
self.0.set_header_table_size(Some(val));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Mock<frame::Settings>> for frame::Settings {
|
||||
|
||||
@@ -1452,6 +1452,40 @@ async fn extended_connect_request() {
|
||||
join(srv, h2).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn client_builder_header_table_size() {
|
||||
h2_support::trace_init!();
|
||||
let (io, mut srv) = mock::new();
|
||||
let mut settings = frame::Settings::default();
|
||||
|
||||
settings.set_header_table_size(Some(10000));
|
||||
|
||||
let srv = async move {
|
||||
let recv_settings = srv.assert_client_handshake().await;
|
||||
assert_frame_eq(recv_settings, settings);
|
||||
|
||||
srv.recv_frame(
|
||||
frames::headers(1)
|
||||
.request("GET", "https://example.com/")
|
||||
.eos(),
|
||||
)
|
||||
.await;
|
||||
srv.send_frame(frames::headers(1).response(200).eos()).await;
|
||||
};
|
||||
|
||||
let mut builder = client::Builder::new();
|
||||
builder.header_table_size(10000);
|
||||
|
||||
let h2 = async move {
|
||||
let (mut client, mut h2) = builder.handshake::<_, Bytes>(io).await.unwrap();
|
||||
let request = Request::get("https://example.com/").body(()).unwrap();
|
||||
let (response, _) = client.send_request(request, true).unwrap();
|
||||
h2.drive(response).await.unwrap();
|
||||
};
|
||||
|
||||
join(srv, h2).await;
|
||||
}
|
||||
|
||||
const SETTINGS: &'static [u8] = &[0, 0, 0, 4, 0, 0, 0, 0, 0];
|
||||
const SETTINGS_ACK: &'static [u8] = &[0, 0, 0, 4, 1, 0, 0, 0, 0];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user