backend: refactor proxy code

This commit is contained in:
2025-07-20 16:44:23 -06:00
parent a11b4deb31
commit fae7971f2b
5 changed files with 201 additions and 148 deletions
@@ -0,0 +1,106 @@
use anyhow::{Result, anyhow};
use salvo::{
prelude::*,
proto::quic::BidiStream,
webtransport::{self},
};
use serde::{Deserialize, Serialize};
use tracing::{error, info};
use crate::{
backend,
common::{AppError, AppResult},
};
#[derive(Serialize, Deserialize)]
pub struct ProxySetupParams {
pub stream: backend::Stream,
}
#[derive(Serialize, Deserialize)]
pub struct ProxySetupResponse {
pub cert_hash: [u8; 32],
//pub cert_hash: String,
}
async fn setup_webtransport(
req: &mut Request,
) -> Result<(
impl tokio::io::AsyncWrite + Send + Sync + 'static,
impl tokio::io::AsyncRead + Send + Sync + 'static,
//salvo::webtransport::stream::SendStream<
// impl salvo::proto::quic::SendStream<salvo::hyper::body::Bytes>,
// salvo::hyper::body::Bytes,
//>,
//salvo::webtransport::stream::RecvStream<
// impl salvo::proto::quic::RecvStream,
// salvo::hyper::body::Bytes,
//>,
)> {
let session = req.web_transport_mut().await?;
let bidirectional_stream = session
.accept_bi()
.await?
.ok_or(anyhow!("No bidirectional stream"))?;
if let webtransport::server::AcceptedBi::BidiStream(_, stream) = bidirectional_stream {
Ok(stream.split())
} else {
Err(anyhow!("bidirectional stream was of the wrong type"))
}
}
#[craft]
impl crate::proxy::Proxy {
#[craft(handler)]
pub async fn stream_setup(
self: ::std::sync::Arc<Self>,
body: salvo::oapi::extract::JsonBody<ProxySetupParams>,
) -> AppResult<Json<ProxySetupResponse>> {
let mut writer = self.stream.write().await;
*writer = Some(body.stream.clone());
info!("Configured proxy with config: {:?}", body.stream);
Ok(Json(ProxySetupResponse {
cert_hash: self.cert_hash,
}))
}
#[craft(handler)]
pub async fn stream_connect(self: ::std::sync::Arc<Self>, req: &mut Request) -> AppResult<()> {
let standard_error = Err(crate::common::AppError {
status_code: StatusCode::INTERNAL_SERVER_ERROR,
description: "Could not start stream".to_string(),
});
info!("WebTransport connection initiated");
let (wt_send, wt_recv) = match setup_webtransport(req).await {
Ok(w) => w,
Err(e) => {
error!("Could not upgrade connection to WebTransport: {e}");
return standard_error;
}
};
let stream = match self.stream.read().await.clone() {
Some(s) => s,
None => {
error!("Stream has not been configured, cannot connect to server");
return Err(AppError {
status_code: StatusCode::BAD_REQUEST,
description: "Proxy has not been configured yet: THIS IS A BUG".to_string(),
});
}
};
match super::proxy_main(stream, wt_send, wt_recv).await {
Ok(()) => Ok(()),
Err(e) => {
error!("Proxy main loop failed: {e}");
standard_error
}
}
}
}