Skip to content

Commit 7bbbb42

Browse files
committed
feat: add https-tunnel feature and improve response handling in AutoProxyClientStream
1 parent 1bdb54a commit 7bbbb42

File tree

3 files changed

+28
-51
lines changed

3 files changed

+28
-51
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ basic = [
6565
"server",
6666
"multi-threaded",
6767
"aead-cipher",
68-
# "https-tunnel",
6968
]
7069

7170
# All Suggested Features
@@ -91,6 +90,7 @@ full = [
9190
"stream-cipher",
9291
"aead-cipher",
9392
"aead-cipher-2022",
93+
"https-tunnel", # arloor modified
9494
]
9595

9696
# Full features with extra (non-stable)

crates/shadowsocks-service/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ https-tunnel = [
7979
"tokio-rustls",
8080
"webpki-roots",
8181
"rustls-native-certs",
82-
"httparse",
8382
"base64",
8483
]
8584
# Enable REDIR protocol for sslocal

crates/shadowsocks-service/src/local/net/tcp/auto_proxy_stream.rs

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -308,58 +308,36 @@ async fn connect_tunnel(
308308
}
309309
#[cfg(feature = "https-tunnel")]
310310
async fn wait_response(tls_stream: &mut tokio_rustls::client::TlsStream<MonProxyStream<TcpStream>>) -> io::Result<()> {
311-
let mut buffer = BytesMut::with_capacity(4096); // 初始化BytesMut缓冲区
311+
let mut reader = tokio::io::BufReader::new(tls_stream);
312+
313+
// 读取响应状态行
314+
let mut response_line = String::new();
315+
use tokio::io::{AsyncBufReadExt};
316+
if let Err(e) = reader.read_line(&mut response_line).await {
317+
warn!("forward_bypass read response error: {}", e);
318+
return Err(io::Error::other(e));
319+
}
320+
321+
// 检查响应是否是200
322+
let status_code = response_line.split_whitespace().nth(1).unwrap_or("");
323+
if status_code != "200" {
324+
warn!("forward_bypass unexpected response: {}", response_line);
325+
return Err(io::Error::other("unexpected response from bypass server"));
326+
}
327+
328+
// 读取并丢弃响应头直到空行
312329
loop {
313-
// 从流中读取数据
314-
match tls_stream.read_buf(&mut buffer).await {
315-
Ok(0) => {
316-
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF"));
317-
}
318-
Ok(_) => {
319-
// 尝试解析累积的数据
320-
let mut headers = [httparse::EMPTY_HEADER; 400];
321-
let mut response: Response<'_, '_> = Response::new(&mut headers);
322-
match response.parse(&buffer) {
323-
Ok(Status::Complete(_)) => {
324-
match response.code {
325-
Some(200) => {
326-
// 连接成功
327-
return Ok(());
328-
}
329-
Some(code) => {
330-
// 连接失败
331-
return Err(io::Error::new(
332-
io::ErrorKind::Other,
333-
format!("failed to connect, response code: {}", code),
334-
));
335-
}
336-
None => {
337-
// 无法解析响应码
338-
return Err(io::Error::new(
339-
io::ErrorKind::Other,
340-
"failed to connect, response code not found",
341-
));
342-
}
343-
}
344-
}
345-
Ok(Status::Partial) => {
346-
// 请求不完整,继续读取更多数据
347-
println!("Received partial HTTP request, waiting for more data...");
348-
// 不清空缓冲区,继续累积数据
349-
}
350-
Err(e) => {
351-
// 解析错误
352-
return Err(io::Error::new(io::ErrorKind::InvalidData, e));
353-
}
354-
}
355-
}
356-
Err(e) => {
357-
// 读取数据时出错
358-
eprintln!("Failed to read from the stream: {:?}", e);
359-
return Err(e);
360-
}
330+
let mut header_line = String::new();
331+
if let Err(e) = reader.read_line(&mut header_line).await {
332+
warn!("forward_bypass read header error: {}", e);
333+
return Err(io::Error::other("unexpected response from bypass server"));
334+
}
335+
if header_line == "\r\n" || header_line == "\n" {
336+
break;
361337
}
362338
}
339+
340+
Ok(())
363341
}
364342

365343
impl AutoProxyIo for AutoProxyClientStream {

0 commit comments

Comments
 (0)