transparent_proxy/
http.rs1use std::{error::Error, io::ErrorKind};
2
3use tap::Tap;
4use tokio::{
5 io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
6 net::TcpStream,
7};
8
9use crate::Flags;
10
11pub async fn handle_client(
12 mut client: tokio::net::TcpStream,
13 flags: Flags,
14) -> Result<(), Box<dyn Error>> {
15 let auth_line = format!(
16 "Proxy-Authorization: Basic {}\r\n",
17 base64::encode(&format!(
18 "{}:{}",
19 flags
20 .username
21 .unwrap_or_default()
22 .replace("%R", fastrand::u32(0..u32::MAX).to_string().as_str())
23 .tap_dbg(|s| println!("username: {}", s)),
24 flags.password.unwrap_or_default()
25 ))
26 );
27 let mut server = TcpStream::connect(flags.target_addr).await?;
28 let (mut reader, mut writer) = client.split();
29 let buf_reader = BufReader::new(&mut reader);
30 let mut lines = buf_reader.lines();
31 let first_line = lines
32 .next_line()
33 .await?
34 .ok_or_else(|| std::io::Error::new(ErrorKind::InvalidData, "missing init data"))?;
35 dbg!(&first_line);
36 server
37 .write_all(format!("{first_line}\r\n{auth_line}\r\n").as_bytes())
38 .await?;
39 let (mut server_reader, mut server_writer) = server.split();
40 let res = tokio::try_join!(
41 tokio::io::copy(&mut reader, &mut server_writer),
42 tokio::io::copy(&mut server_reader, &mut writer)
43 );
44 if cfg!(debug_assertions) {
45 eprintln!("{res:?}");
46 }
47 Ok(())
48}