Skip to main content

App

Struct App 

Source
pub struct App<G: Gate = Open> { /* private fields */ }
Expand description

A web application: one site, its routes, and its gate. Built once at start-up with App::builder or App::with_gate; immutable after.

It is a serve_net::HttpService, so it runs on serve-net as it is, and it has respond and respond_identified for a wrapper that calls it from its own service.

use web_net::{App, get};

let app = App::builder()
    .route(get("/", |cx| { cx.html(200, "<h1>Hello</h1>"); Ok(()) }).public())
    .route(get("/users/:id", |cx| {
        let id: u64 = cx.param_as("id")?;
        cx.text(200, &format!("user {id}"));
        Ok(())
    }).public())
    .build()?;

let reply = serve_net::testing::respond(&app, b"GET /users/7 HTTP/1.1\r\nHost: a\r\n\r\n");
assert_eq!((reply.status, reply.text()), (200, "user 7"));

let reply = serve_net::testing::respond(&app, b"GET /users/7/ HTTP/1.1\r\nHost: a\r\n\r\n");
assert_eq!(reply.status, 301);
assert_eq!(reply.header("location"), Some(&b"/users/7"[..]));

Implementations§

Source§

impl App<Open>

Source

pub fn builder() -> Builder<Open>

A builder with the Open gate: every visitor is a guest and every route is declared public.

Examples found in repository?
examples/hello.rs (line 15)
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}
Source§

impl<G: Gate> App<G>

Source

pub fn with_gate(gate: G) -> Builder<G>

A builder with gate for authentication and authorization.

Source§

impl<G: Gate> App<G>

Source

pub fn respond( &self, req: &HttpRequest<'_>, env: &Envelope, reply: &mut HttpReply, ) -> Outcome

Runs the whole pipeline for one request, authentication included.

Source

pub fn serve( &self, req: &HttpRequest<'_>, env: &Envelope, who: Option<&G::Identity>, reply: &mut HttpReply, ) -> Served

Runs the pipeline and reports what ran and whether a cache in front may keep the reply for guests. who is Some when the caller authenticated already (as for respond_identified).

Source

pub fn respond_identified( &self, req: &HttpRequest<'_>, env: &Envelope, who: &G::Identity, reply: &mut HttpReply, ) -> Outcome

Runs the pipeline for a request whose caller authenticated it already: web-net takes who as given and does not call the gate’s authenticate. Authorization still runs for every route that is not public.

Source

pub fn classify(&self, head: &HttpHead<'_>) -> Classified

Looks at a head before admission: which route would run and how it behaves. Nothing is answered and no gate is called.

Source

pub fn gate(&self) -> &G

The gate.

Trait Implementations§

Source§

impl<G: Gate> Debug for App<G>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<G: Gate> HttpService for App<G>

Source§

fn call( &self, request: &HttpRequest<'_>, env: &Envelope, reply: &mut HttpReply, ) -> Outcome

The request is complete.
Source§

const WORK: WorkClass = WorkClass::Quick

How the service behaves.
Source§

fn head(&self, head: &HttpHead<'_>, env: &mut Envelope) -> HeadAction

The head is complete; before admission and before any body byte.
Source§

fn upgraded(&self, env: &Envelope, conn: UpgradedConn)

After the 101 for an upgrade this service asked for in head left, and after done for that request. The conversation itself belongs to the upgrade target (a WebSocketService, feature ws).
Source§

fn done(&self, env: &Envelope, finished: &Finished)

Exactly once per request that reached head, on every path.

Auto Trait Implementations§

§

impl<G = Open> !RefUnwindSafe for App<G>

§

impl<G = Open> !UnwindSafe for App<G>

§

impl<G> Forget for App<G>

§

impl<G> Freeze for App<G>
where G: Freeze, Vec<Entry<G>>: Freeze,

§

impl<G> Send for App<G>
where Vec<Entry<G>>: Send,

§

impl<G> Sync for App<G>
where Vec<Entry<G>>: Sync,

§

impl<G> Unpin for App<G>
where G: Unpin, Vec<Entry<G>>: Unpin,

§

impl<G> UnsafeUnpin for App<G>
where G: UnsafeUnpin, Vec<Entry<G>>: UnsafeUnpin,

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<S> Service<HttpFamily> for S
where S: HttpService,

Source§

const WORK: WorkClass = <S as HttpService>::WORK

How the service behaves.
Source§

fn head(&self, head: &HttpHead<'_>, env: &mut Envelope) -> HeadAction

The head is complete; before admission and any body byte.
Source§

fn call( &self, request: &HttpRequest<'_>, env: &Envelope, reply: &mut Reply<HttpFamily>, ) -> Outcome

The request is complete.
Source§

fn upgraded(&self, env: &Envelope, conn: UpgradedConn)

After a switch response the service asked for left.
Source§

fn done(&self, env: &Envelope, finished: &Finished)

Exactly once per request that reached head.
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.