boxy/src/services/proxy.rs

50 lines
1.5 KiB
Rust

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::server::{GeneralResponse, to_general_response};
#[derive(Debug, Clone)]
pub struct ProxyService {
pub address: String,
pub hostname: String,
}
impl Service<Request<Incoming>> for ProxyService {
type Response = GeneralResponse;
type Error = hyper::Error;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn call(&self, incoming: Request<Incoming>) -> 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()))
})
}
}