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§
sourcefn pre_raw(&self, req: &mut Result<Request>) -> MiddleResult
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
.
sourcefn pre(&self, _req: &mut Request) -> MiddleResult
fn pre(&self, _req: &mut Request) -> MiddleResult
Middleware to run Before Routes
sourcefn post_raw(
&self,
req: Result<Rc<Request>>,
res: &mut Result<Response>
) -> MiddleResult
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
.
sourcefn post(&self, _req: &Request, _res: &mut Response) -> MiddleResult
fn post(&self, _req: &Request, _res: &mut Response) -> MiddleResult
Middleware to run After Routes
sourcefn end_raw(&self, req: &Result<Request>, res: &Result<Response>)
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
.
sourcefn end(&self, _req: &Request, _res: &Response)
fn end(&self, _req: &Request, _res: &Response)
Middleware ot run after the response has been handled
sourcefn attach<State>(self, server: &mut Server<State>)where
Self: 'static + Send + Sync + Sized,
State: 'static + Send + Sync,
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?
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
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();
}
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();
}
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();
}
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();
}