use axum::{ routing::{ get, post }, Router, handler::Handler, http::header::HeaderMap, extract::Query, }; use tokio::{ net::{ UnixListener, UnixStream }, }; use std::{ path::PathBuf, pin::Pin, task::{ Context, Poll }, collections::HashMap, }; use tower::BoxError; use futures::ready; use hyper::server::accept::Accept; use nix::sys::stat::{ Mode, umask }; use askama::Template; use axum_macros::debug_handler; #[tokio::main] async fn main() -> Result<(), Box> { println!("main starting"); start_web().await; println!("main stopping"); Ok(()) } struct ServerAccept { uds: UnixListener, } impl Accept for ServerAccept { type Conn = UnixStream; type Error = BoxError; fn poll_accept( self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { let (stream, _addr) = ready!(self.uds.poll_accept(cx))?; Poll::Ready(Some(Ok(stream))) } } async fn start_web() { println!("In start_web"); // build our application with a route let app = Router::new() .route("/rust-test", get(root_handler)) .route("/rust-test", post(root_handler)) .fallback(fallback.into_service()); let socketpath = PathBuf::from("/run/miscrunner/axum-tests/socket"); let _ = std::fs::remove_file(&socketpath); let _ = std::fs::create_dir_all(socketpath.parent().unwrap()); let mode = Mode::from_bits_truncate(0o111); let prev_umask = umask(mode); let uds = UnixListener::bind(socketpath).unwrap(); let _ = umask(prev_umask); axum::Server::builder(ServerAccept { uds }) .serve(app.into_make_service()) .with_graceful_shutdown(signal_shutdown()) .await .unwrap(); println!("After spawn"); } async fn signal_shutdown() { tokio::signal::ctrl_c() .await .expect("expect tokio signal ctrl-c"); println!("signal shutdown"); } #[debug_handler] async fn root_handler( Query(mut params): Query>, headers: HeaderMap ) -> RootTemplate { params.insert("Troels added".to_string(), "this: ".to_string()); RootTemplate{ params, headers } } #[derive(Template)] #[template(path = "root.jinja.html")] struct RootTemplate { params: HashMap, headers: HeaderMap } async fn fallback( uri: axum::http::Uri ) -> impl axum::response::IntoResponse { (axum::http::StatusCode::NOT_FOUND, format!("No route {}", uri)) }