From a1b2b107e593bc0668e4373db0158788c71c74a4 Mon Sep 17 00:00:00 2001 From: Gerhard de Clercq <11624490+Gerharddc@users.noreply.github.com> Date: Fri, 7 Feb 2025 10:28:09 +0100 Subject: [PATCH] Add Query Example This example shows how to extract query string parameters. --- Cargo.toml | 1 + examples/query/Cargo.toml | 13 ++++++++ examples/query/src/index.html | 18 ++++++++++ examples/query/src/main.rs | 63 +++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 examples/query/Cargo.toml create mode 100644 examples/query/src/index.html create mode 100644 examples/query/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index a289d1a..bb67f17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "examples/conditional_routing", "examples/custom_extractor", "examples/form", + "examples/query", "examples/hello_world", "examples/hello_world_single_thread", "examples/huge_requests", diff --git a/examples/query/Cargo.toml b/examples/query/Cargo.toml new file mode 100644 index 0000000..407e722 --- /dev/null +++ b/examples/query/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "query" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +heapless = { workspace = true } +picoserve = { path = "../../picoserve", features = ["tokio"] } +serde = { workspace = true } +tokio = { workspace = true } diff --git a/examples/query/src/index.html b/examples/query/src/index.html new file mode 100644 index 0000000..0e3c981 --- /dev/null +++ b/examples/query/src/index.html @@ -0,0 +1,18 @@ + + + + + + + Form Demo + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/examples/query/src/main.rs b/examples/query/src/main.rs new file mode 100644 index 0000000..5560e28 --- /dev/null +++ b/examples/query/src/main.rs @@ -0,0 +1,63 @@ +use std::time::Duration; + +use picoserve::routing::{get, get_service}; + +#[derive(serde::Deserialize)] +struct QueryParams { + a: i32, + b: heapless::String<32>, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { + let port = 8000; + + let app = std::rc::Rc::new( + picoserve::Router::new() + .route( + "/", + get_service(picoserve::response::File::html(include_str!("index.html"))), + ) + .route( + "/get-thing", + get(|picoserve::extract::Query(QueryParams { a, b })| { + picoserve::response::DebugValue((("a", a), ("b", b))) + }), + ), + ); + + 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, port)).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 +}