Skip to main content

Cx

Struct Cx 

Source
pub struct Cx<'r, I> { /* private fields */ }
Expand description

The context a handler receives: proof that the request passed its route’s access check, the identity it carries, and the reply.

There is no public way to make one: web-net builds it only after the gate cleared the request.

Implementations§

Source§

impl<'r, I> Cx<'r, I>

Source

pub fn request(&self) -> &Request<'r>

The request.

Source

pub fn method(&self) -> Method

The method.

Source

pub fn path(&self) -> &'r str

The canonical path inside the site.

Source

pub fn header(&self, name: &str) -> Option<&'r [u8]>

The first value of a request field.

Source

pub fn identity(&self) -> &'r I

Who the request comes from: always present, possibly a guest.

Source

pub fn id(&self) -> RequestId

The request’s reference, as shown on error pages.

Source

pub fn param(&self, name: &str) -> Option<Cow<'r, str>>

A route parameter (:id or *rest), percent-decoded.

Source

pub fn param_as<T: FromStr>(&self, name: &str) -> Result<T>

A route parameter parsed as T. A value that does not parse means the page does not exist (/users/abc for a numeric id): 404.

§Errors

404 route.param when the parameter is missing or does not parse.

Examples found in repository?
examples/hello.rs (line 32)
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        )
47        .build()?;
48
49    let server = serve_net::Server::builder()
50        .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
51        .serve(app)?;
52    println!("listening on http://127.0.0.1:8091/app/");
53    server.wait();
54    Ok(())
55}
Source

pub fn query(&self, name: &str) -> Result<Option<Cow<'r, str>>>

The first value of a query parameter, decoded (+ is a space).

§Errors

400 query.duplicate when the name appears twice (parameter pollution is refused, never resolved by picking one), 400 query.invalid when the value does not decode to UTF-8.

Source

pub fn body(&self) -> Result<&'r [u8]>

The request body.

§Errors

None today; reading the body is fallible so CSRF and body inspection can refuse it in later versions without changing handlers.

Source

pub fn status(&mut self, status: u16) -> &mut Self

Sets the status (default 200).

Source

pub fn set_header(&mut self, name: &str, value: impl AsRef<[u8]>) -> &mut Self

Adds a reply field. A name that is not a token, a value with a control character, or a framing field (content-length, …) turns the reply into a 500 when the handler returns.

Source

pub fn body_bytes(&mut self, bytes: &[u8]) -> &mut Self

Sets the body.

Source

pub fn html(&mut self, status: u16, html: &str) -> &mut Self

Status, content-type: text/html; charset=utf-8, and the HTML.

Examples found in repository?
examples/hello.rs (lines 22-25)
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        )
47        .build()?;
48
49    let server = serve_net::Server::builder()
50        .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
51        .serve(app)?;
52    println!("listening on http://127.0.0.1:8091/app/");
53    server.wait();
54    Ok(())
55}
Source

pub fn text(&mut self, status: u16, text: &str) -> &mut Self

Status, content-type: text/plain; charset=utf-8, and the text.

Examples found in repository?
examples/hello.rs (line 33)
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        )
47        .build()?;
48
49    let server = serve_net::Server::builder()
50        .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
51        .serve(app)?;
52    println!("listening on http://127.0.0.1:8091/app/");
53    server.wait();
54    Ok(())
55}
Source

pub fn url(&self, path: &str) -> String

The site-relative path as a URL path: the site’s base path in front (/blog + /posts/1). Every link a page writes goes through this, so the site works installed in a folder.

Examples found in repository?
examples/hello.rs (line 21)
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        )
47        .build()?;
48
49    let server = serve_net::Server::builder()
50        .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
51        .serve(app)?;
52    println!("listening on http://127.0.0.1:8091/app/");
53    server.wait();
54    Ok(())
55}
Source

pub fn see_other(&mut self, path: &str) -> Result

303 See Other to a site-relative path: the answer to a form that was accepted, so a reload does not post it again.

§Errors

500 redirect.not_local when path is not a local path (it must start with one /): redirects to other hosts are never built from a string a handler passes along.

Examples found in repository?
examples/hello.rs (line 44)
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        )
47        .build()?;
48
49    let server = serve_net::Server::builder()
50        .listener(serve_net::ListenerSpec::tcp("web", "127.0.0.1:8091"))
51        .serve(app)?;
52    println!("listening on http://127.0.0.1:8091/app/");
53    server.wait();
54    Ok(())
55}
Source

pub fn redirect(&mut self, status: u16, path: &str) -> Result

A redirect with status (301, 302, 303, 307, 308) to a site-relative path.

§Errors

As see_other; 500 redirect.status for a status that is not a redirect.

Source

pub fn render(&mut self, view: &dyn View) -> Result

Renders the route’s template (declared with Route::template) against view into the body. The status stays as set (200 by default); content-type is HTML unless the handler set one.

§Errors

500 render.no_engine or render.no_template when nothing can render; the engine’s own RenderError as a 500; a checkpoint’s denial.

Source

pub fn render_named(&mut self, name: &str, view: &dyn View) -> Result

Renders the template name against view. The name is resolved by the engine on every call; prefer render with a template declared on the route, resolved once at build.

§Errors

As render.

Trait Implementations§

Source§

impl<I> Debug for Cx<'_, I>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'r, I> !RefUnwindSafe for Cx<'r, I>

§

impl<'r, I> !UnwindSafe for Cx<'r, I>

§

impl<'r, I> Forget for Cx<'r, I>

§

impl<'r, I> Freeze for Cx<'r, I>
where &'r I: Freeze,

§

impl<'r, I> Send for Cx<'r, I>
where &'r I: Send,

§

impl<'r, I> Sync for Cx<'r, I>
where &'r I: Sync,

§

impl<'r, I> Unpin for Cx<'r, I>
where &'r I: Unpin,

§

impl<'r, I> UnsafeUnpin for Cx<'r, I>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.