Skip to content

Commit a131111

Browse files
authored
fix(http1): fix intermitent panic parsing partial headers (#3812)
Closes #3811
1 parent a3bda62 commit a131111

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/proto/h1/io.rs

+4
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,11 @@ where
205205
return Poll::Ready(Err(crate::Error::new_too_large()));
206206
}
207207
if curr_len > 0 {
208+
trace!("partial headers; {} bytes so far", curr_len);
208209
self.partial_len = Some(curr_len);
210+
} else {
211+
// 1xx gobled some bytes
212+
self.partial_len = None;
209213
}
210214
}
211215
}

tests/client.rs

+57
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,63 @@ mod conn {
20412041
assert_eq!(vec, b"bar=foo");
20422042
}
20432043

2044+
#[tokio::test]
2045+
async fn client_100_then_http09() {
2046+
let (server, addr) = setup_std_test_server();
2047+
2048+
thread::spawn(move || {
2049+
let mut sock = server.accept().unwrap().0;
2050+
sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
2051+
sock.set_write_timeout(Some(Duration::from_secs(5)))
2052+
.unwrap();
2053+
let mut buf = [0; 4096];
2054+
sock.read(&mut buf).expect("read 1");
2055+
sock.write_all(
2056+
b"\
2057+
HTTP/1.1 100 Continue\r\n\
2058+
Content-Type: text/plain\r\n\
2059+
Server: BaseHTTP/0.6 Python/3.12.5\r\n\
2060+
Date: Mon, 16 Dec 2024 03:08:27 GMT\r\n\
2061+
",
2062+
)
2063+
.unwrap();
2064+
// That it's separate writes is important to this test
2065+
thread::sleep(Duration::from_millis(50));
2066+
sock.write_all(
2067+
b"\
2068+
\r\n\
2069+
",
2070+
)
2071+
.expect("write 2");
2072+
thread::sleep(Duration::from_millis(50));
2073+
sock.write_all(
2074+
b"\
2075+
This is a sample text/plain document, without final headers.\
2076+
\n\n\
2077+
",
2078+
)
2079+
.expect("write 3");
2080+
});
2081+
2082+
let tcp = tcp_connect(&addr).await.unwrap();
2083+
2084+
let (mut client, conn) = conn::http1::Builder::new()
2085+
.http09_responses(true)
2086+
.handshake(tcp)
2087+
.await
2088+
.unwrap();
2089+
2090+
tokio::spawn(async move {
2091+
let _ = conn.await;
2092+
});
2093+
2094+
let req = Request::builder()
2095+
.uri("/a")
2096+
.body(Empty::<Bytes>::new())
2097+
.unwrap();
2098+
let _res = client.send_request(req).await.expect("send_request");
2099+
}
2100+
20442101
#[tokio::test]
20452102
async fn test_try_send_request() {
20462103
use std::future::Future;

0 commit comments

Comments
 (0)