use axum::extract::State; use axum::{ body::Body, extract::Host, http::Request, response::Html, routing::any, Extension, Router, }; use std::sync::Arc; use std::{ net::SocketAddr, sync::atomic::{AtomicUsize, Ordering}, }; use tower::ServiceExt; struct AppState { api_requests: AtomicUsize, website_requests: AtomicUsize, } #[tokio::main] async fn main() { let api_router = Router::new().route("/*path", any(api_handler)); let website_router = Router::new().route("/*path", any(website_handler)); let state = Arc::new(AppState { website_requests: AtomicUsize::new(0), api_requests: AtomicUsize::new(0), }); let app = Router::new() .route( "/*path", any(|Host(hostname): Host, request: Request| async move { println!("{}", hostname); match hostname.as_str() { "apps4u.local" => api_router.oneshot(request).await, _ => website_router.oneshot(request).await, } }), ) .with_state(Arc::new(state)) //.layer(Extension(state)) ; let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); println!("listening on {}", addr); axum::serve(listener, app).await.unwrap(); } //async fn api_handler(Extension(state): Extension>) -> Html { async fn api_handler(State(state): State>) -> Html { state.api_requests.fetch_add(1, Ordering::SeqCst); Html(format!( "api: {}", state.api_requests.load(Ordering::SeqCst) )) } //async fn website_handler(Extension(state): Extension>) -> Html { async fn website_handler(State(state): State>) -> Html { state.website_requests.fetch_add(1, Ordering::SeqCst); Html(format!( "website: {}", state.website_requests.load(Ordering::SeqCst) )) }