Skip to content

Commit 90ede30

Browse files
authored
fix(http1): more strictly enforce max_buf_size when parsing (#4093)
Closes #4081
1 parent b80c77d commit 90ede30

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

src/proto/h1/io.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,14 @@ where
222222

223223
pub(crate) fn poll_read_from_io(&mut self, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
224224
self.read_blocked = false;
225-
let next = self.read_buf_strategy.next();
225+
// Get the next amount to allocate, but make sure we don't go over
226+
// the max read buf size configured.
227+
let next = cmp::min(
228+
self.read_buf_strategy.next(),
229+
self.read_buf_strategy
230+
.max()
231+
.saturating_sub(self.read_buf.len()),
232+
);
226233
if self.read_buf_remaining_mut() < next {
227234
self.read_buf.reserve(next);
228235
}

tests/server.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,38 @@ async fn max_buf_size() {
23872387
.expect_err("should TooLarge error");
23882388
}
23892389

2390+
#[cfg(feature = "http1")]
2391+
#[tokio::test]
2392+
async fn max_buf_size_split_header_boundary() {
2393+
let (listener, addr) = setup_tcp_listener();
2394+
2395+
const MAX: usize = 8192;
2396+
2397+
thread::spawn(move || {
2398+
let mut tcp = connect(&addr);
2399+
tcp.write_all(b"GET / HTTP/1.1\r\nHost: x\r\nConnection: close\r\nX: ")
2400+
.expect("write 1");
2401+
tcp.write_all(&[b'a'; 7000]).expect("write 2");
2402+
thread::sleep(Duration::from_millis(100));
2403+
tcp.write_all(&[b'a'; 5000]).expect("write 3");
2404+
tcp.write_all(b"\r\n\r\n").expect("write 4");
2405+
2406+
let mut buf = String::new();
2407+
tcp.read_to_string(&mut buf).expect("read response");
2408+
2409+
let expected = "HTTP/1.1 431 ";
2410+
assert_eq!(&buf[..expected.len()], expected);
2411+
});
2412+
2413+
let (socket, _) = listener.accept().await.unwrap();
2414+
let socket = TokioIo::new(socket);
2415+
http1::Builder::new()
2416+
.max_buf_size(MAX)
2417+
.serve_connection(socket, HelloWorld)
2418+
.await
2419+
.expect_err("should TooLarge error");
2420+
}
2421+
23902422
#[cfg(feature = "http1")]
23912423
#[tokio::test]
23922424
async fn graceful_shutdown_before_first_request_no_block() {

0 commit comments

Comments
 (0)