hello/hello.rs
1//! A small site on serve-net: a home page, a page per user, a form that
2//! redirects after POST, and the site installed under `/app`.
3//!
4//! ```text
5//! cargo run --example hello
6//! curl -i http://127.0.0.1:8091/app/
7//! curl -i http://127.0.0.1:8091/app/users/7
8//! curl -i http://127.0.0.1:8091/app/users/7/ # 301 to the canonical path
9//! curl -i -X DELETE http://127.0.0.1:8091/app/ # 405 with Allow
10//! ```
11
12use web_net::{App, Route, get};
13
14fn main() -> Result<(), Box<dyn std::error::Error>> {
15 let app = App::builder()
16 .host("127.0.0.1:8091")
17 .development()
18 .base("/app")
19 .route(
20 get("/", |cx| {
21 let users = cx.url("/users/7");
22 cx.html(
23 200,
24 &format!("<h1>Hello</h1><a href=\"{users}\">user 7</a>"),
25 );
26 Ok(())
27 })
28 .public(),
29 )
30 .route(
31 get("/users/:id", |cx| {
32 let id: u64 = cx.param_as("id")?;
33 cx.text(200, &format!("user {id}"));
34 Ok(())
35 })
36 .public(),
37 )
38 .route(
39 Route::at("/contact")
40 .get(|cx| {
41 cx.html(200, "<form method=post><button>Send</button></form>");
42 Ok(())
43 })
44 .post(|cx| cx.see_other("/"))
45 .public()
46 // A form that changes state gets Builder::csrf(..) and a gate
47 // whose identities carry a CSRF binding instead.
48 .csrf_exempt("demo: the POST changes nothing"),
49 )
50 .build()?;
51
52 let server = serve_net::Server::builder()
53 .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
54 .serve(app)?;
55 println!("listening on http://127.0.0.1:8091/app/");
56 server.wait();
57 Ok(())
58}