Skip to main content

Application

Trait Application 

Source
pub trait Application {
    // Required method
    fn execute(
        &self,
        request: &Request,
        connection: &ConnectionInfo,
    ) -> Result<Response, String>;

    // Provided methods
    fn runs_inline(
        &self,
        _request: &Request,
        _connection: &ConnectionInfo,
    ) -> bool { ... }
    fn execute_async<'a>(
        &'a self,
        _request: &'a Request,
        _connection: &'a ConnectionInfo,
    ) -> Option<AsyncResponse<'a>> { ... }
    fn streams_body(
        &self,
        _request: &Request,
        _connection: &ConnectionInfo,
    ) -> bool { ... }
}
Expand description

Dispatch trait that wires controllers into a request-handling loop.

Implement this to define which controllers run and in what order. Pass the implementation to [Server::run] or [Server::run_tls].

The built-in App implementation covers static files, favicons, forms, and file uploads. Embed it or replace it entirely.

Required Methods§

Source

fn execute( &self, request: &Request, connection: &ConnectionInfo, ) -> Result<Response, String>

Receives a parsed request and returns a fully-built response. Walk your controller list with is_matching / process and return the first match.

Provided Methods§

Source

fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool

true when executing request is quick and never waits on anything but the local filesystem — health checks, metrics, small static files. The async servers (HTTP/1.1, HTTP/2, HTTP/3) then call execute directly on the event loop, as nginx does, instead of handing the request to tokio’s blocking pool: that handoff (a shared lock and two cross-thread wake-ups) costs more than serving a small file.

Default false, and it must stay false for anything that can wait: a database query, an upstream request, a lock held across I/O. Run on the event loop, those would stall every other connection on that worker. Wrappers answer true only when every layer agrees.

Source

fn execute_async<'a>( &'a self, _request: &'a Request, _connection: &'a ConnectionInfo, ) -> Option<AsyncResponse<'a>>

An asynchronous version of execute for this request, when the application has one: the async servers await it on the connection’s task instead of tying up a blocking-pool thread while it waits (the config-driven proxy uses this to wait for a backend without holding a thread). None (the default) means “use execute”. Wrappers return Some only when they add no synchronous work of their own.

Source

fn streams_body(&self, _request: &Request, _connection: &ConnectionInfo) -> bool

true to receive this request’s body as a stream (Body::Stream) instead of read into memory first: execute then runs while the body is still arriving, on a blocking-pool thread, and reads it with std::io::Read — a multi-gigabyte upload in a few chunks of memory. Asked after the head is read, so request.body is empty here; decide from the method, path and headers.

Default false: the body is read first, as always. Async HTTP/1.1 and HTTP/2 honour it (HTTP/2 credits the stream’s window back as the handler reads); the HTTP/1.1-only build and HTTP/3 read the body first regardless. Wrappers answer true only when every layer leaves the body alone (Middleware::accepts_streamed_body).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§