💾 Archived View for 80h.dev › projects › gemserv › files › src › revproxy.rs.gemini captured on 2022-03-01 at 15:23:36. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2020-09-24)

🚧 View Differences

-=-=-=-=-=-=-

01 #![cfg(feature = "proxy")]

02 use openssl::ssl::{SslConnector, SslMethod};

03 use std::io;

04 use std::net::ToSocketAddrs;

05 use tokio::io::{AsyncReadExt, AsyncWriteExt};

06 use tokio::net::TcpStream;

07

08 use crate::conn;

09 use crate::logger;

10 use crate::status::Status;

11

12 pub async fn proxy(addr: String, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> {

13 let p: Vec<&str> = u.path().trim_start_matches("/").splitn(2, "/").collect();

14 if p.len() == 1 {

15 logger::logger(con.peer_addr, Status::NotFound, u.as_str());

16 con.send_status(Status::NotFound, None).await?;

17 return Ok(());

18 }

19 if p[1] == "" || p[1] == "/" {

20 logger::logger(con.peer_addr, Status::NotFound, u.as_str());

21 con.send_status(Status::NotFound, None).await?;

22 return Ok(());

23 }

24 let addr = addr

25 .to_socket_addrs()?

26 .next()

27 .ok_or_else(|| io::Error::from(io::ErrorKind::AddrNotAvailable))?;

28

29 let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();

30 connector.set_verify(openssl::ssl::SslVerifyMode::NONE);

31 let config = connector.build().configure().unwrap();

32

33 let stream = match TcpStream::connect(&addr).await {

34 Ok(s) => s,

35 Err(_) => {

36 logger::logger(con.peer_addr, Status::ProxyError, u.as_str());

37 con.send_status(Status::ProxyError, None).await?;

38 return Ok(());

39 }

40 };

41 let mut stream = match tokio_openssl::connect(config, "localhost", stream).await {

42 Ok(s) => s,

43 Err(_) => {

44 logger::logger(con.peer_addr, Status::ProxyError, u.as_str());

45 con.send_status(Status::ProxyError, None).await?;

46 return Ok(());

47 }

48 };

49 stream.write_all(p[1].as_bytes()).await?;

50 stream.flush().await?;

51

52 let mut buf = vec![];

53 stream.read_to_end(&mut buf).await?;

54 // let req = String::from_utf8(buf[..].to_vec()).unwrap();

55 con.send_raw(&buf).await?;

56 Ok(())

57 }

58

59 pub async fn proxy_all(addr: &str, u: url::Url, mut con: conn::Connection) -> Result<(), io::Error> {

60 let mut connector = SslConnector::builder(SslMethod::tls()).unwrap();

61 connector.set_verify(openssl::ssl::SslVerifyMode::NONE);

62 let config = connector.build().configure().unwrap();

63

64 // TCP handshake

65 let stream = match TcpStream::connect(&addr).await {

66 Ok(s) => s,

67 Err(_) => {

68 logger::logger(con.peer_addr, Status::ProxyError, u.as_str());

69 con.send_status(Status::ProxyError, None).await?;

70 return Ok(());

71 }

72 };

73 let domain = addr.splitn(2, ':').next().unwrap();

74

75 // TLS handshake with SNI

76 let mut stream = match tokio_openssl::connect(config, domain, stream).await {

77 Ok(s) => s,

78 Err(_) => {

79 logger::logger(con.peer_addr, Status::ProxyError, u.as_str());

80 con.send_status(Status::ProxyError, None).await?;

81 return Ok(());

82 }

83 };

84

85 // send request: URL + CRLF

86 stream.write_all(u.as_ref().as_bytes()).await?;

87 stream.write_all(b"\r\n").await?;

88 stream.flush().await?;

89

90 // stream to client

91 con.send_stream(&mut stream).await?;

92 Ok(())

93 }