1+ mod insecure_verifier;
2+
13use clap:: Parser ;
24use colored:: * ;
35use std:: sync:: Arc ;
@@ -65,10 +67,13 @@ async fn main() -> anyhow::Result<()> {
6567
6668 let listener = tokio:: net:: TcpListener :: bind ( & args. listen ) . await ?;
6769 let mut id: u64 = 0 ;
70+ let sep = "=" . repeat ( 120 ) . bright_yellow ( ) ;
6871 loop {
6972 id = id + 1 ;
7073 let ( client, addr) = listener. accept ( ) . await ?;
74+ println ! ( "{}" , sep) ;
7175 println ! ( "{}{} {}" , "#" . red( ) , id. to_string( ) . red( ) , addr. to_string( ) . red( ) ) ;
76+ println ! ( "{}" , sep) ;
7277 let cfg = args. clone ( ) ;
7378 tokio:: spawn ( async move {
7479 if let Err ( e) = proxy ( id, client, cfg. clone ( ) ) . await {
@@ -82,65 +87,16 @@ trait AsyncStream: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send +
8287
8388impl < T : tokio:: io:: AsyncRead + tokio:: io:: AsyncWrite + Unpin + Send + ' static > AsyncStream for T { }
8489
85- use tokio_rustls:: rustls;
86- use tokio_rustls:: rustls:: client:: danger:: { HandshakeSignatureValid , ServerCertVerified , ServerCertVerifier } ;
87- use tokio_rustls:: rustls:: pki_types:: { CertificateDer , ServerName , UnixTime } ;
88- use tokio_rustls:: rustls:: { DigitallySignedStruct , SignatureScheme } ;
89-
90- #[ derive( Debug ) ]
91- struct NoCertificateVerification ;
92-
93- impl ServerCertVerifier for NoCertificateVerification {
94- fn verify_server_cert (
95- & self ,
96- _end_entity : & CertificateDer < ' _ > ,
97- _intermediates : & [ CertificateDer < ' _ > ] ,
98- _server_name : & ServerName < ' _ > ,
99- _ocsp_response : & [ u8 ] ,
100- _now : UnixTime ,
101- ) -> Result < ServerCertVerified , rustls:: Error > {
102- // This is the "magic" line that bypasses the check
103- Ok ( ServerCertVerified :: assertion ( ) )
104- }
105-
106- fn verify_tls12_signature (
107- & self ,
108- _message : & [ u8 ] ,
109- _cert : & CertificateDer < ' _ > ,
110- _dss : & DigitallySignedStruct ,
111- ) -> Result < HandshakeSignatureValid , rustls:: Error > {
112- Ok ( HandshakeSignatureValid :: assertion ( ) )
113- }
114-
115- fn verify_tls13_signature (
116- & self ,
117- _message : & [ u8 ] ,
118- _cert : & CertificateDer < ' _ > ,
119- _dss : & DigitallySignedStruct ,
120- ) -> Result < HandshakeSignatureValid , rustls:: Error > {
121- Ok ( HandshakeSignatureValid :: assertion ( ) )
122- }
123-
124- fn supported_verify_schemes ( & self ) -> Vec < SignatureScheme > {
125- // Support common schemes to ensure compatibility
126- vec ! [
127- SignatureScheme :: RSA_PSS_SHA256 ,
128- SignatureScheme :: ECDSA_NISTP256_SHA256 ,
129- SignatureScheme :: ED25519 ,
130- SignatureScheme :: RSA_PKCS1_SHA256 ,
131- ]
132- }
133- }
13490async fn connect ( cfg : Args ) -> anyhow:: Result < Box < dyn AsyncStream > > {
13591 let upstream = tokio:: net:: TcpStream :: connect ( cfg. dest . clone ( ) ) . await ?;
13692 if !cfg. tls {
13793 return Ok ( Box :: new ( upstream) ) ;
13894 }
13995
14096 // Set up the TLS config without verification
141- let config = rustls:: ClientConfig :: builder ( )
97+ let config = tokio_rustls :: rustls:: ClientConfig :: builder ( )
14298 . dangerous ( )
143- . with_custom_certificate_verifier ( Arc :: new ( NoCertificateVerification ) )
99+ . with_custom_certificate_verifier ( Arc :: new ( insecure_verifier :: NoCertificateVerification ) )
144100 . with_no_client_auth ( ) ;
145101
146102 let connector = tokio_rustls:: TlsConnector :: from ( Arc :: new ( config) ) ;
@@ -184,6 +140,8 @@ async fn connect(cfg: Args) -> anyhow::Result<Box<dyn AsyncStream>> {
184140const BUFFER_SIZE : usize = 102400 ; // 100 KB
185141
186142async fn proxy ( id : u64 , mut client : tokio:: net:: TcpStream , cfg : Args ) -> anyhow:: Result < ( ) > {
143+ let start = std:: time:: Instant :: now ( ) ;
144+
187145 let upstream = connect ( cfg. clone ( ) ) . await ?;
188146
189147 let ( mut cr, mut cw) = client. split ( ) ;
@@ -227,6 +185,10 @@ async fn proxy(id: u64, mut client: tokio::net::TcpStream, cfg: Args) -> anyhow:
227185
228186 tokio:: try_join!( client_to_server, server_to_client) ?;
229187
188+ let elapsed = start. elapsed ( ) ;
189+ let msg = format ! ( "#{} connection closed, elapsed: {:?}" , id, elapsed) ;
190+ println ! ( "{}" , msg. bright_red( ) ) ;
191+
230192 Ok ( ( ) )
231193}
232194
@@ -247,19 +209,33 @@ fn fix_header(bf: &[u8], cfg: Args) -> Vec<u8> {
247209 }
248210 let ( headers, body) = content. split_at ( header_end_idx. unwrap ( ) ) ;
249211 let mut lines: Vec < String > = headers. lines ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ;
250- let mut host_found = false ;
251212
252213 let domain = cfg. domain ( ) ;
253-
214+ let mut host_found = false ;
254215 // 遍历每一行查找 Host
255216 for line in lines. iter_mut ( ) {
256217 if line. to_lowercase ( ) . starts_with ( "host:" ) {
218+ let msg = format ! ( "[DEBUG] [FixHeader] replace ({} --> {})" , line, domain) ;
219+ eprintln ! ( "{}" , msg. dimmed( ) ) ;
257220 * line = format ! ( "Host: {}" , domain) ;
258221 host_found = true ;
259222 break ;
260223 }
261224 }
262225
226+ // 禁用 Connection:keep-alive
227+ let mut connection_fount = false ;
228+ for line in lines. iter_mut ( ) {
229+ if line. to_lowercase ( ) . starts_with ( "connection:" ) {
230+ let msg = format ! ( "[DEBUG] [FixHeader] replace ({} --> close)" , line) ;
231+ eprintln ! ( "{}" , msg. dimmed( ) ) ;
232+ * line = "Connection: close" . to_string ( ) ;
233+ connection_fount = true ;
234+ break ;
235+ }
236+ }
237+
238+ // 禁用 gzip
263239 if cfg. strip_compression {
264240 for line in lines. iter_mut ( ) {
265241 if line. to_lowercase ( ) . starts_with ( "accept-encoding:" ) {
@@ -273,7 +249,19 @@ fn fix_header(bf: &[u8], cfg: Args) -> Vec<u8> {
273249
274250 // 如果没找到 Host 字段,在第一行(请求行)之后插入
275251 if !host_found && lines. len ( ) > 0 {
276- lines. insert ( 1 , format ! ( "Host: {}" , domain) ) ;
252+ let new_line = format ! ( "Host: {}" , domain) ;
253+ lines. insert ( 1 , new_line. clone ( ) ) ;
254+
255+ let msg = format ! ( "[DEBUG] [FixHeader] Append ({})" , new_line) ;
256+ eprintln ! ( "{}" , msg. dimmed( ) ) ;
257+ }
258+
259+ if !connection_fount && lines. len ( ) > 0 {
260+ let new_line = "Connection: close" . to_string ( ) ;
261+ lines. insert ( 1 , new_line. clone ( ) ) ;
262+
263+ let msg = format ! ( "[DEBUG] [FixHeader] Append ({})" , new_line) ;
264+ eprintln ! ( "{}" , msg. dimmed( ) ) ;
277265 }
278266
279267 // 重新拼接 Request
@@ -372,38 +360,3 @@ fn print_binary(data: &[u8]) {
372360 println ! ( "{}" , "-" . repeat( CHUNK_SIZE + 8 ) . dimmed( ) ) ;
373361 }
374362}
375-
376- // todo: 修改为按照长度截取,每120个字符打印一次,分别打印为 Char 类型和 Hex 类型
377- // fn print_binary(data: &[u8]){
378- // // 按换行符 \n 切分,保留换行符在每一行末尾
379- // let lines = data.split_inclusive(|&b| b == b'\n');
380- //
381- // for (idx, line) in lines.enumerate() {
382- // // 1. 生成 Lossy 字符串预览
383- // // 将不可见字符(除换行外)替换为点,防止终端控制符乱跳
384- // let mut text_view = String::new();
385- // for &b in line {
386- // if b.is_ascii_graphic() || b == b' ' {
387- // text_view.push(b as char);
388- // } else if b == b'\n' {
389- // text_view.push_str("\\n");
390- // } else if b == b'\r' {
391- // text_view.push_str("\\r");
392- // } else {
393- // text_view.push('·'); // 不可打印字符用弱化的点表示
394- // }
395- // }
396- //
397- // // 2. 生成 Hex 预览
398- // let hex_view: String = line.iter()
399- // .map(|b| format!("{:02x}", b))
400- // .collect::<Vec<String>>()
401- // .join(" ");
402- //
403- // // 3. 格式化输出
404- // // 行号用灰色,文本部分用绿色,Hex 部分用黄色
405- // println!("{:>3} | {:<40}",idx.to_string().dimmed(),text_view.green());
406- // println!("{:>3} | {}", idx.to_string().dimmed(),hex_view.yellow().dimmed());
407- // }
408- // println!("{}", "--- End of Data ---".dimmed());
409- // }
0 commit comments