An async no_std
HTTP server suitable for bare-metal environments, heavily inspired by axum.
It was designed with embassy on the Raspberry Pi Pico W in mind, but should work with other embedded runtimes and hardware.
Features:
Shortcomings:
0.*.*
, there may be breaking API changesuse std::time::Duration;
use picoserve::routing::get;
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
let port = 8000;
let app =
std::rc::Rc::new(picoserve::Router::new().route("/", get(|| async { "Hello World" })));
let config = picoserve::Config::new(picoserve::Timeouts {
start_read_request: Some(Duration::from_secs(5)),
read_request: Some(Duration::from_secs(1)),
write: Some(Duration::from_secs(1)),
})
.keep_connection_alive();
let socket = tokio::net::TcpListener::bind((std::net::Ipv4Addr::LOCALHOST, 8000)).await?;
println!("http://localhost:{port}/");
tokio::task::LocalSet::new()
.run_until(async {
loop {
let (stream, remote_address) = socket.accept().await?;
println!("Connection from {remote_address}");
let app = app.clone();
let config = config.clone();
tokio::task::spawn_local(async move {
match picoserve::serve(&app, &config, &mut [0; 2048], stream).await {
Ok(handled_requests_count) => {
println!(
"{handled_requests_count} requests handled from {remote_address}"
)
}
Err(err) => println!("{err:?}"),
}
});
}
})
.await
}