use std::net::SocketAddr; use axum::{ Extension, Json, Router, extract::DefaultBodyLimit, routing::{get, post}, }; use tokio::{net::TcpListener, sync::mpsc}; use tower_http::limit::RequestBodyLimitLayer; use crate::{ Config, JoecalState, discovery::register_device, transfer::{register_prepare_upload, register_upload}, }; impl JoecalState { pub async fn start_http_server( &self, stop_rx: mpsc::Receiver<()>, config: &Config, ) -> crate::error::Result<()> { let app = self.create_router(config); // TODO: make addr config let addr = SocketAddr::from(([0, 0, 0, 0], config.port)); let listener = TcpListener::bind(&addr).await?; axum::serve( listener, app.into_make_service_with_connect_info::(), ) .with_graceful_shutdown(shutdown(stop_rx)) .await?; Ok(()) } fn create_router(&self, config: &Config) -> Router { let device = self.device.clone(); Router::new() .route("/api/localsend/v2/register", post(register_device)) .route( "/api/localsend/v2/info", get(move || async move { Json(device) }), ) .route( "/api/localsend/v2/prepare-upload", post(register_prepare_upload), ) .route("/api/localsend/v2/upload", post(register_upload)) .layer(DefaultBodyLimit::disable()) .layer(RequestBodyLimitLayer::new(1024 * 1024 * 1024)) .layer(Extension(config.download_dir.clone())) .with_state(self.clone()) } } async fn shutdown(mut rx: mpsc::Receiver<()>) { rx.recv().await.unwrap_or_default() }