basic/middleware.rs
1use afire::{
2 middleware::{MiddleResult, Middleware},
3 Content, Header, Method, Request, Response, Server,
4};
5
6use crate::Example;
7
8// In afire Middleware is a trait that is implemented and can modify Requests and Response before and after Routes
9// You can use Middleware to Log Requests, Ratelimit Requests, add Analytics, etc.
10// The Middleware functions for this are `pre` and `post` for before and after the routes, there is also `end` which is called after the response is sent to the client
11//
12// There are two types of hooks: raw and non-raw.
13// The raw hooks are passed a Result, and their default implementation calls the non-raw hooks if the Result is Ok.
14// This allows you to handle errors (like page not found), while maintaining a clean API for middleware that doesn't need to handle errors.
15//
16// In the different middleware hooks you can return a MiddleResult, which is an enum with 3 variants:
17// - Continue: Continue to the next middleware or route
18// - Abort: Stop the middleware chain
19// - Send: Immediately send this response to the client and stop the middleware chain
20//
21// For more info, checkout the documentation for Middleware here: https://docs.rs/afire/latest/afire/middleware/trait.Middleware.html
22
23// Lets make a Middleware that will log the request to the console
24// And to show how to modify the response, we will add a header to the response
25
26struct Log;
27
28// Now we will Implement Middleware for Log
29impl Middleware for Log {
30 // Redefine the `pre` function
31 // (Runs before Routes)
32 fn pre(&self, req: &mut Request) -> MiddleResult {
33 // Print some info
34 println!("[{}] {} {}", req.address.ip(), req.method, req.path);
35
36 // Continue to forward the request to the next middleware or route
37 MiddleResult::Continue
38 }
39
40 // Lets also modify the outgoing response by adding a header
41 fn post(&self, _req: &Request, res: &mut Response) -> MiddleResult {
42 res.headers.push(Header::new("X-Example", "Middleware"));
43 MiddleResult::Continue
44 }
45}
46
47pub struct MiddlewareExample;
48
49impl Example for MiddlewareExample {
50 fn name(&self) -> &'static str {
51 "middleware"
52 }
53
54 fn exec(&self) {
55 // Create a new Server instance on localhost port 8080
56 let mut server = Server::<()>::new("localhost", 8080);
57
58 // Define a basic route
59 server.route(Method::GET, "/", |_req| {
60 Response::new().text("Hello World!").content(Content::TXT)
61 });
62
63 // Here is where we will attach our Middleware to the Server
64 // This is super easy
65 Log.attach(&mut server);
66
67 // You can now goto http://localhost:8080 you should see that the request is printed to the console
68 // It should look something like this: `[127.0.0.1] GET `
69
70 // Start the server
71 // This will block the current thread
72 server.start().unwrap();
73 }
74}