Skip to content

Commit 0f274ae

Browse files
authored
fix(http1): fix intermitent panic parsing partial headers (#3813)
Backports #3812 Closes #3811
1 parent a24f0c0 commit 0f274ae

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

src/proto/h1/io.rs

Lines changed: 4 additions & 0 deletions
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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,6 +2908,63 @@ mod conn {
29082908
assert_eq!(vec, b"bar=foo");
29092909
}
29102910

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

0 commit comments

Comments
 (0)