Trait afire::middleware::Middleware

source ·
pub trait Middleware {
    // Provided methods
    fn pre_raw(&self, req: &mut Result<Request>) -> MiddleResult { ... }
    fn pre(&self, _req: &mut Request) -> MiddleResult { ... }
    fn post_raw(
        &self,
        req: Result<Rc<Request>>,
        res: &mut Result<Response>
    ) -> MiddleResult { ... }
    fn post(&self, _req: &Request, _res: &mut Response) -> MiddleResult { ... }
    fn end_raw(&self, req: &Result<Request>, res: &Result<Response>) { ... }
    fn end(&self, _req: &Request, _res: &Response) { ... }
    fn attach<State>(self, server: &mut Server<State>)
       where Self: 'static + Send + Sync + Sized,
             State: 'static + Send + Sync { ... }
}
Expand description

Trait used to implement Middleware, which is code that runs before and after the routes - potentially modifying the request and response. You can use Middleware to Log Requests, Ratelimit Requests, add Analytics, etc.

There are two types of hooks: raw and non-raw. The raw hooks are passed a Result, and their default implementation calls the non-raw hooks if the Result is Ok. This allows you to handle errors (like page not found), while maintaining a clean API for middleware that doesn’t need to handle errors.

Hooks

Provided Methods§

source

fn pre_raw(&self, req: &mut Result<Request>) -> MiddleResult

Middleware to run before routes. Because this is the raw version of Middleware::pre, it is passed a Result. The default implementation calls Middleware::pre if the Result is Ok.

source

fn pre(&self, _req: &mut Request) -> MiddleResult

Middleware to run Before Routes

source

fn post_raw( &self, req: Result<Rc<Request>>, res: &mut Result<Response> ) -> MiddleResult

Middleware to run after routes. Because this is the raw version of Middleware::post, it is passed a Result. The default implementation calls Middleware::post if the Result is Ok.

source

fn post(&self, _req: &Request, _res: &mut Response) -> MiddleResult

Middleware to run After Routes

source

fn end_raw(&self, req: &Result<Request>, res: &Result<Response>)

Middleware to run after the response has been handled. Because this is the raw version of Middleware::end, it is passed a Result. The default implementation calls Middleware::end if the Result is Ok.

source

fn end(&self, _req: &Request, _res: &Response)

Middleware ot run after the response has been handled

source

fn attach<State>(self, server: &mut Server<State>)where Self: 'static + Send + Sync + Sized, State: 'static + Send + Sync,

Attach Middleware to a Server. If you want to get a reference to the server’s state in your middleware state, you should override this method.

Examples found in repository?
examples/middle_bench.rs (line 28)
23
24
25
26
27
28
29
30
31
32
33
34
35
fn main() {
    set_log_level(Level::Debug);
    let mut server = Server::<()>::new([127, 0, 0, 1], 8080);
    server.route(Method::ANY, "**", |_req| Response::new());

    Middleware1.attach(&mut server);
    Middleware2.attach(&mut server);
    Middleware3.attach(&mut server);
    Middleware4.attach(&mut server);
    Middleware5.attach(&mut server);

    server.start().unwrap();
}
More examples
Hide additional examples
examples/basic/middleware.rs (line 65)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a basic route
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // Here is where we will attach our Middleware to the Server
        // This is super easy
        Log.attach(&mut server);

        // You can now goto http://localhost:8080 you should see that the request is printed to the console
        // It should look something like this: `[127.0.0.1] GET `

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/rate_limit.rs (line 44)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new().text("Hello World!").content(Content::TXT)
        });

        // For this example, we'll limit requests to 1 every 2 seconds

        // Make a new Ratelimater
        // Default Limit is 10
        // Default Timeout is 60 sec
        RateLimiter::new()
            // Override the Limit to 1
            .limit(1)
            // Override the timeout to 2
            .timeout(2)
            // Override the Handler
            .handler(Box::new(|_req| {
                Some(
                    Response::new()
                        .status(Status::TooManyRequests)
                        .text("AHHHH!!! Too Many Requests")
                        .content(Content::TXT),
                )
            }))
            // Attach to the server
            .attach(&mut server);

        // Now if you goto http://localhost:8080/ and reload a bunch of times,
        // you'll see the rate limiter kicking in.

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/serve_static.rs (line 46)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Make a new static file server with a path
        extension::ServeStatic::new(STATIC_DIR)
            // The middleware priority is by most recently defined.
            // The middleware function takes 3 parameters: the request, the response, and weather the file was loaded successfully.
            // In your middleware you can modify the response and the bool.
            .middleware(|req, res, _suc| {
                // Print path served
                println!("Served: {}", req.path);
                // Return none to not mess with response
                // Or in this case add a header and pass through the success value
                res.headers.push(Header::new("X-Static", "true"));
            })
            // Function that runs when no file is found to serve
            // This will run before middleware
            .not_found(|_req, _dis| {
                Response::new()
                    .status(Status::NotFound)
                    .text("Page Not Found!")
            })
            // Add an extra mime type to the server
            // It has a lot already
            .mime_type("key", "value")
            // Set serve path
            .path(STATIC_PATH)
            // Attach the middleware to the server
            .attach(&mut server);

        // View the file at http://localhost:8080
        // You should also see a favicon in the browser tab

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }
examples/basic/logging.rs (line 50)
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    fn exec(&self) {
        // Create a new Server instance on localhost port 8080
        let mut server = Server::<()>::new("localhost", 8080);

        // Define a handler for GET "/"
        server.route(Method::GET, "/", |_req| {
            Response::new()
                .text("Hello World!\nThis request has been logged!")
                .content(Content::TXT)
        });

        // Make a logger and attach it to the server

        // By default Log Level is INFO, File is None and Console is true
        // This could be condensed to `Logger::new().attach(&mut server);` as it uses al default values
        Logger::new()
            // The level of logging this can be Debug or Info
            // Debug will give a lot more information about the request
            .level(Level::Info)
            // This will have Logger make use of the RealIp extention,
            // which will allow logging the correct IP when using a reverse proxy.
            .real_ip(HeaderType::XForwardedFor)
            // The file argument tells the logger if it should save to a file
            // Only one file can be defined per logger
            // With logging to file it will write to the file on every request... (for now)
            .file("example.log")
            .unwrap()
            // Tells the Logger it should log to the console as well
            .console(true)
            // This must be put at the end of your Logger Construction
            // It adds the Logger to your Server as Middleware
            .attach(&mut server);

        // Now if you goto http://localhost:8080/ you should see the log message in console.

        // Start the server
        // This will block the current thread
        server.start().unwrap();
    }

Implementors§