From 6a11efcc59e37fa5c1af8959681ee8a3cbeaab7b Mon Sep 17 00:00:00 2001 From: Abdul Wahab Date: Wed, 16 Sep 2026 14:35:18 +0500 Subject: [PATCH] Test: read SOCKS handshake frames with read_exact The mock proxy now reassembles greeting and CONNECT across TCP fragments so the ALL_PROXY regression cannot flake on a short read. AI assistance disclosure: this commit was prepared with AI assistance under maintainer direction. Co-authored-by: Cursor --- crates/context/src/http.rs | 49 ++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/crates/context/src/http.rs b/crates/context/src/http.rs index 46d25bee6..2081b2764 100644 --- a/crates/context/src/http.rs +++ b/crates/context/src/http.rs @@ -234,24 +234,53 @@ tB0WGTOG3QIgdJa8gBPU9Y6WsrursItsnUeGTYHKDCZZ6MjlekLFuoc= use std::time::Duration; fn socks5_then_http(stream: &mut std::net::TcpStream) -> Option> { - let mut buf = [0u8; 4096]; - let n = stream.read(&mut buf).unwrap_or(0); - if n < 2 || buf[0] != 5 { + fn read_n(stream: &mut std::net::TcpStream, n: usize) -> Option> { + let mut buf = vec![0u8; n]; + stream.read_exact(&mut buf).ok()?; + Some(buf) + } + + let greet = read_n(stream, 2)?; + if greet[0] != 5 { return None; } + let _ = read_n(stream, greet[1] as usize)?; stream.write_all(&[0x05, 0x00]).ok()?; - let n = stream.read(&mut buf).unwrap_or(0); - if n < 7 || buf[0] != 5 || buf[1] != 1 { + + let req = read_n(stream, 4)?; + if req[0] != 5 || req[1] != 1 { return None; } + match req[3] { + 1 => { + let _ = read_n(stream, 6)?; + } + 3 => { + let len = read_n(stream, 1)?; + let _ = read_n(stream, len[0] as usize + 2)?; + } + 4 => { + let _ = read_n(stream, 18)?; + } + _ => return None, + } stream .write_all(&[0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0]) .ok()?; - let n = stream.read(&mut buf).unwrap_or(0); - let chunk = buf[..n].to_vec(); - if chunk.is_empty() - || !String::from_utf8_lossy(&chunk).contains("proxy-test.invalid") - { + + let mut chunk = Vec::new(); + let mut buf = [0u8; 4096]; + loop { + let n = stream.read(&mut buf).ok()?; + if n == 0 { + break; + } + chunk.extend_from_slice(&buf[..n]); + if String::from_utf8_lossy(&chunk).contains("proxy-test.invalid") { + break; + } + } + if !String::from_utf8_lossy(&chunk).contains("proxy-test.invalid") { return None; } let _ = stream.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nok");