Respect SETTINGS_HEADER_TABLE_SIZE (#459)

This commit is contained in:
Sean McArthur
2020-03-30 11:53:22 -07:00
committed by GitHub
parent 20efc46597
commit e41a1f130c
7 changed files with 121 additions and 3 deletions

View File

@@ -52,6 +52,8 @@ pub use tokio::io::{AsyncRead, AsyncWrite};
pub use std::thread;
pub use std::time::Duration;
pub static MAGIC_PREFACE: &[u8] = b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
// ===== Everything under here shouldn't be used =====
// TODO: work on deleting this code
@@ -62,14 +64,20 @@ use std::pin::Pin;
pub trait MockH2 {
fn handshake(&mut self) -> &mut Self;
fn handshake_read_settings(&mut self, settings: &[u8]) -> &mut Self;
}
impl MockH2 for tokio_test::io::Builder {
fn handshake(&mut self) -> &mut Self {
self.write(b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
self.handshake_read_settings(frames::SETTINGS)
}
fn handshake_read_settings(&mut self, settings: &[u8]) -> &mut Self {
self.write(MAGIC_PREFACE)
// Settings frame
.write(frames::SETTINGS)
.read(frames::SETTINGS)
.read(settings)
.read(frames::SETTINGS_ACK)
}
}

View File

@@ -51,3 +51,90 @@ async fn write_continuation_frames() {
join(srv, client).await;
}
#[tokio::test]
async fn client_settings_header_table_size() {
// A server sets the SETTINGS_HEADER_TABLE_SIZE to 0, test that the
// client doesn't send indexed headers.
let _ = env_logger::try_init();
let io = mock_io::Builder::new()
// Read SETTINGS_HEADER_TABLE_SIZE = 0
.handshake_read_settings(&[
0, 0, 6, // len
4, // type
0, // flags
0, 0, 0, 0, // stream id
0, 0x1, // id = SETTINGS_HEADER_TABLE_SIZE
0, 0, 0, 0, // value = 0
])
// Write GET / (1st)
.write(&[
0, 0, 0x10, 1, 5, 0, 0, 0, 1, 0x82, 0x87, 0x41, 0x8B, 0x9D, 0x29, 0xAC, 0x4B, 0x8F,
0xA8, 0xE9, 0x19, 0x97, 0x21, 0xE9, 0x84,
])
.write(frames::SETTINGS_ACK)
// Read response
.read(&[0, 0, 1, 1, 5, 0, 0, 0, 1, 137])
// Write GET / (2nd, doesn't use indexed headers)
// - Sends 0x20 about size change
// - Sends :authority as literal instead of indexed
.write(&[
0, 0, 0x11, 1, 5, 0, 0, 0, 3, 0x20, 0x82, 0x87, 0x1, 0x8B, 0x9D, 0x29, 0xAC, 0x4B,
0x8F, 0xA8, 0xE9, 0x19, 0x97, 0x21, 0xE9, 0x84,
])
.read(&[0, 0, 1, 1, 5, 0, 0, 0, 3, 137])
.build();
let (mut client, mut conn) = client::handshake(io).await.expect("handshake");
let req1 = client.get("https://http2.akamai.com");
conn.drive(req1).await.expect("req1");
let req2 = client.get("https://http2.akamai.com");
conn.drive(req2).await.expect("req1");
}
#[tokio::test]
async fn server_settings_header_table_size() {
// A client sets the SETTINGS_HEADER_TABLE_SIZE to 0, test that the
// server doesn't send indexed headers.
let _ = env_logger::try_init();
let io = mock_io::Builder::new()
.read(MAGIC_PREFACE)
// Read SETTINGS_HEADER_TABLE_SIZE = 0
.read(&[
0, 0, 6, // len
4, // type
0, // flags
0, 0, 0, 0, // stream id
0, 0x1, // id = SETTINGS_HEADER_TABLE_SIZE
0, 0, 0, 0, // value = 0
])
.write(frames::SETTINGS)
.write(frames::SETTINGS_ACK)
.read(frames::SETTINGS_ACK)
// Write GET /
.read(&[
0, 0, 0x10, 1, 5, 0, 0, 0, 1, 0x82, 0x87, 0x41, 0x8B, 0x9D, 0x29, 0xAC, 0x4B, 0x8F,
0xA8, 0xE9, 0x19, 0x97, 0x21, 0xE9, 0x84,
])
// Read response
//.write(&[0, 0, 6, 1, 5, 0, 0, 0, 1, 136, 64, 129, 31, 129, 143])
.write(&[0, 0, 7, 1, 5, 0, 0, 0, 1, 32, 136, 0, 129, 31, 129, 143])
.build();
let mut srv = server::handshake(io).await.expect("handshake");
let (_req, mut stream) = srv.accept().await.unwrap().unwrap();
let rsp = http::Response::builder()
.status(200)
.header("a", "b")
.body(())
.unwrap();
stream.send_response(rsp, true).unwrap();
assert!(srv.accept().await.is_none());
}