Skip to content

Commit 7879782

Browse files
committed
fix(http1): fix intermitent panic parsing partial headers (#3812)
Closes #3811
1 parent a24f0c0 commit 7879782

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/proto/h1/io.rs

+4
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,11 @@ where
248248
}
249249
}
250250
if curr_len > 0 {
251+
trace!("partial headers; {} bytes so far", curr_len);
251252
self.partial_len = Some(curr_len);
253+
} else {
254+
// 1xx gobled some bytes
255+
self.partial_len = None;
252256
}
253257
}
254258
}

tests/client.rs

+54
Original file line numberDiff line numberDiff line change
@@ -2908,6 +2908,60 @@ mod conn {
29082908
assert_eq!(vec, b"bar=foo");
29092909
}
29102910

2911+
#[tokio::test]
2912+
async fn client_100_then_http09() {
2913+
let (server, addr) = setup_std_test_server();
2914+
2915+
thread::spawn(move || {
2916+
let mut sock = server.accept().unwrap().0;
2917+
sock.set_read_timeout(Some(Duration::from_secs(5))).unwrap();
2918+
sock.set_write_timeout(Some(Duration::from_secs(5)))
2919+
.unwrap();
2920+
let mut buf = [0; 4096];
2921+
sock.read(&mut buf).expect("read 1");
2922+
sock.write_all(
2923+
b"\
2924+
HTTP/1.1 100 Continue\r\n\
2925+
Content-Type: text/plain\r\n\
2926+
Server: BaseHTTP/0.6 Python/3.12.5\r\n\
2927+
Date: Mon, 16 Dec 2024 03:08:27 GMT\r\n\
2928+
",
2929+
)
2930+
.unwrap();
2931+
// That it's separate writes is important to this test
2932+
thread::sleep(Duration::from_millis(50));
2933+
sock.write_all(
2934+
b"\
2935+
\r\n\
2936+
",
2937+
)
2938+
.expect("write 2");
2939+
thread::sleep(Duration::from_millis(50));
2940+
sock.write_all(
2941+
b"\
2942+
This is a sample text/plain document, without final headers.\
2943+
\n\n\
2944+
",
2945+
)
2946+
.expect("write 3");
2947+
});
2948+
2949+
let tcp = tcp_connect(&addr).await.unwrap();
2950+
2951+
let (mut client, conn) = conn::Builder::new()
2952+
.http09_responses(true)
2953+
.handshake(tcp)
2954+
.await
2955+
.unwrap();
2956+
2957+
tokio::spawn(async move {
2958+
let _ = conn.await;
2959+
});
2960+
2961+
let req = Request::builder().uri("/a").body(Body::empty()).unwrap();
2962+
let _res = client.send_request(req).await.expect("send_request");
2963+
}
2964+
29112965
#[tokio::test]
29122966
async fn http2_detect_conn_eof() {
29132967
use futures_util::future;

0 commit comments

Comments
 (0)