use std::pin::Pin; use hyper::{Request, body::Incoming, service::Service}; use hyper_util::rt::TokioIo; use log::error; use tokio::net::TcpStream; use crate::types::{GeneralResponse, to_general_response}; #[derive(Debug, Clone)] pub struct ProxyService { pub address: String, pub hostname: String, } impl Service> for ProxyService { type Response = GeneralResponse; type Error = hyper::Error; type Future = Pin> + Send>>; fn call(&self, incoming: Request) -> Self::Future { let address = self.address.clone(); let hostname = self.hostname.clone(); Box::pin(async move { let stream = TcpStream::connect(address).await.unwrap(); let io = TokioIo::new(stream); let (mut sender, conn) = hyper::client::conn::http1::Builder::new() .handshake(io) .await .unwrap(); tokio::spawn(async move { if let Err(err) = conn.await { error!("Could not open connection to backend: {err}"); } }); let (mut parts, body_stream) = incoming.into_parts(); parts .headers .insert(hyper::header::HOST, hostname.parse().unwrap()); let req = Request::from_parts(parts, body_stream); Ok(to_general_response(sender.send_request(req).await.unwrap())) }) } }