use anyhow::{Context, Result}; use hyper::{body::Incoming, server::conn::http1}; use hyper_util::{rt::TokioIo, service::TowerToHyperService}; use serve_esm::{Handler, create_handler}; use tokio::{ io::{AsyncRead, AsyncWrite}, net::{TcpListener, UnixListener}, }; #[tokio::main] async fn main() -> Result<()> { let root = std::env::var_os("TARGET_DIR").context("TARGET_DIR is required")?; let handler = create_handler(root).context("opening TARGET_DIR")?; if let Some(path) = std::env::var_os("SOCKET_PATH") { let listener = UnixListener::bind(&path)?; eprintln!("listening on {}", std::path::Path::new(&path).display()); loop { serve(listener.accept().await?.0, handler.clone()); } } else { let address = std::env::var("LISTEN").unwrap_or_else(|_| "0.0.0.0:8000".into()); let listener = TcpListener::bind(address).await?; eprintln!("listening on http://{}", listener.local_addr()?); loop { serve(listener.accept().await?.0, handler.clone()); } } } fn serve(io: I, handler: Handler) where I: AsyncRead + AsyncWrite + Unpin + Send + 'static, { tokio::spawn(async move { let connection = http1::Builder::new() .serve_connection(TokioIo::new(io), TowerToHyperService::new(handler)); if let Err(error) = connection.await { eprintln!("HTTP connection failed: {error}"); } }); }