hyper_middleware/
middleware.rs

1//! The middleware and handler system module.
2//!
3//! It's highly inspired by [The Iron middleware & handler system](https://github.com/iron/iron/blob/master/iron/src/middleware/mod.rs) and intended to work with latest [Hyper][`hyper`] `0.14`.
4//!
5//! The middleware and handler system are the fundamental building blocks
6//! for handling HTTP requests and generating responses with Hyper.
7//!
8//! # Handlers
9//!
10//! A `Handler` will produce a `Response` given a `Request`. Most handlers are
11//! functions or closures that accept a `&mut Request` as an argument and return
12//! an `Result` containing a `Response`. An `Result` is returned instead of
13//! directly returning a `Response` in order to indicate a possibility of
14//! failure (e.g. database timeout).
15//!
16//! Here's an example of a `Handler`:
17//!
18//! ```rust
19//! use hyper_middleware::{async_trait, Handler, Request, Response, Result, Body};
20//!
21//! struct Application {}
22//!
23//! #[async_trait]
24//! impl Handler for Application {
25//!     async fn handle(&self, req: &mut Request) -> Result<Response> {
26//!         Ok(Response::builder().body(Body::from("¡Hola!")).unwrap())
27//!     }
28//! }
29//! ```
30//!
31//! # Middleware
32//!
33//! In situations involving more complex logic, it may be desirable to transform
34//! `Request`s passed to a `Handler` or altering `Response`s sent to the
35//! clients. For example, an authorization step could only allow requests sent
36//! by authorized users to be passed to a `Handler` and respond to all other
37//! requests with a 403 status code. To faciliate such use cases, Iron's
38//! middleware system allows `Handler`s to be extended by defining middleware,
39//! which will perform transformations.
40//!
41//! There are three types of middleware:
42//!
43//! * A `BeforeMiddleware` alters a `Request`. It can be useful for handling
44//!   control flow (e.g. routing and authorization).
45//! * An `AroundMiddleware` wraps a `Handler`, changing both the `Response`
46//!   passed to the `Handler` and the returned `Response`.
47//! * An `AfterMiddleware` performs `Response` post-processing. It can be used
48//!   for editing headers or logging `Response`s, but it should _not_ be used for
49//!   changing the body of a `Response`.
50//!
51//! See the documentation for each middleware for more details.
52//!
53//! ## Defining the middleware pipeline
54//!
55//! the `Middlewares` chain is a `Handler` that wraps another `Handler`. It is used to attach
56//! middleware to the wrapped `Handler` using a `link` method corresponding to
57//! each type of middleware. A sample middleware pipeline is shown below:
58//!
59//! ```rust
60//! use hyper::Server;
61//! use hyper_middleware::{async_trait, Handler, BeforeMiddleware, Body, Middlewares, Request, Response, Result, Service};
62//!
63//! struct Application {}
64//!
65//! #[async_trait]
66//! impl Handler for Application {
67//!     async fn handle(&self, req: &mut Request) -> Result<Response> {
68//!         let mut resp = Response::new(Body::from("¡Hola!"));
69//!         resp.headers_mut().insert(
70//!             hyper::header::CONTENT_TYPE,
71//!             "text/html; charset=utf-8".parse().unwrap(),
72//!         );
73//!         Ok(resp)
74//!     }
75//! }
76//!
77//! struct RequestLoggingMiddleware {}
78//!
79//! #[async_trait]
80//! impl BeforeMiddleware for RequestLoggingMiddleware {
81//!     async fn before(&self, req: &mut Request) -> Result {
82//!         println!("{:?}", req);
83//!         Ok(())
84//!     }
85//! }
86//!
87//! #[tokio::main(flavor = "multi_thread")]
88//! async fn main() -> Result {
89//!     let mut middlewares = Middlewares::new(Application {});
90//!     // Plug in the custom middleware(s)
91//!     middlewares.link_before(RequestLoggingMiddleware {});
92//!
93//!     let addr = ([127, 0, 0, 1], 8080).into();
94//!     let service = Service::new(middlewares);
95//!     let server = Server::bind(&addr).serve(service);
96//!     println!("Listening on http://{}", addr);
97//!
98//!     // server.await?;
99//!
100//!     Ok(())
101//! }
102
103//! ```
104//!
105//! # The Request Handling Flow
106//!
107//! A diagram modeling the entire middleware system process is shown below:
108//!
109//! ```plain
110//! [b] = BeforeMiddleware
111//! [a] = AfterMiddleware
112//! [[h]] = AroundMiddleware
113//! [h] = Handler
114//! ```
115//!
116//! With no errors, the flow looks like:
117//!
118//! ```plain
119//! [b] -> [b] -> [b] -> [[[[h]]]] -> [a] -> [a] -> [a] -> [a]
120//! ```
121//!
122//! A request first travels through all `BeforeMiddleware`, then a `Response` is
123//! generated by the `Handler`, which can be an arbitrary nesting of
124//! `AroundMiddleware`, then all `AfterMiddleware` are called with both the
125//! `Request` and `Response`. After all `AfterMiddleware` have been fired, the
126//! response is written back to the client.
127//!
128//! Iron's error handling system is pragmatic and focuses on tracking two pieces
129//! of information for error receivers (other middleware):
130//!
131//! * The cause of the error
132//! * The result (what to do about) the error.
133//!
134//! The cause of the error is represented simply by the error itself, and the
135//! result of the error, representing the action to take in response to the
136//! error, is a complete Response, which will be sent at the end of the error
137//! flow.
138//!
139//! When an error is thrown in Iron by any middleware or handler returning an
140//! `Err` variant with an `Error`, the flow of the `Request` switches to the
141//! error flow, which proceeds to just call the `catch` method of middleware and
142//! sidesteps the `Handler` entirely, since there is already a `Response` in the
143//! error.
144//!
145//! A `Request` can exit the error flow by returning an Ok from any of the catch
146//! methods. This resumes the flow at the middleware immediately following the
147//! middleware which handled the error. It is impossible to "go back" to an
148//! earlier middleware that was skipped.
149//!
150//! Generally speaking, returning a `5xx` error code means that the error flow
151//! should be entered by raising an explicit error. Dealing with `4xx` errors is
152//! trickier, since the server may not want to recognize an error that is
153//! entirely the clients fault; handling of `4xx` error codes is up to to each
154//! application and middleware author.
155//!
156//! Middleware authors should be cognizant that their middleware may be skipped
157//! during the error flow. Anything that *must* be done to each `Request` or
158//! `Response` should be run during both the normal and error flow by
159//! implementing the `catch` method to also do the necessary action.
160
161use async_recursion::async_recursion;
162use async_trait::async_trait;
163use std::sync::Arc;
164
165use crate::{Error, Request, Response, Result};
166
167#[async_trait]
168/// `Handler`s are responsible for handling requests by creating `Response`s from those `Request`s.
169pub trait Handler: Send + Sync + 'static {
170    /// Produce a `Response` from a Request, with the possibility of error.
171    async fn handle(&self, req: &mut Request) -> Result<Response>;
172}
173
174#[async_trait]
175impl<F> Handler for F
176where
177    F: Send + Sync + 'static + Fn(&mut Request) -> Result<Response>,
178{
179    async fn handle(&self, req: &mut Request) -> Result<Response> {
180        (*self)(req)
181    }
182}
183
184#[async_trait]
185impl Handler for Box<dyn Handler> {
186    async fn handle(&self, req: &mut Request) -> Result<Response> {
187        (**self).handle(req).await
188    }
189}
190
191#[async_trait]
192/// `BeforeMiddleware` are fired before a `Handler` is called inside of a Middlewares.
193///
194/// `BeforeMiddleware` are responsible for doing request pre-processing that requires
195/// the ability to change control-flow, such as authorization middleware, or for editing
196/// the request by modifying the headers.
197///
198/// `BeforeMiddleware` only have access to the Request, if you need to modify or read
199/// a Response, you will need `AfterMiddleware`. Middleware which wishes to send an
200/// early response that is not an error cannot be `BeforeMiddleware`, but should
201/// instead be `AroundMiddleware`.
202pub trait BeforeMiddleware: Send + Sync + 'static {
203    /// Do whatever work this middleware should do with a `Request` object.
204    async fn before(&self, _: &mut Request) -> Result<()> {
205        Ok(())
206    }
207
208    /// Respond to an error thrown by a previous `BeforeMiddleware`.
209    ///
210    /// Returning a `Ok` will cause the request to resume the normal flow at the
211    /// next `BeforeMiddleware`, or if this was the last `BeforeMiddleware`,
212    /// at the `Handler`.
213    async fn catch(&self, _: &mut Request, err: Error) -> Result<()> {
214        Err(err)
215    }
216}
217
218#[async_trait]
219/// `AfterMiddleware` are fired after a `Handler` is called inside of the `Middlewares` chain.
220///
221/// `AfterMiddleware` receive both a `Request` and a `Response` and are responsible for doing
222/// any response post-processing.
223///
224/// `AfterMiddleware` should *not* overwrite the contents of a `Response`. In
225/// the common case, a complete response is generated by the Middlewares's `Handler` and
226/// `AfterMiddleware` simply do post-processing of that Response, such as
227/// adding headers or logging.
228pub trait AfterMiddleware: Send + Sync + 'static {
229    /// Do whatever post-processing this middleware should do.
230    async fn after(&self, _: &mut Request, res: Response) -> Result<Response> {
231        Ok(res)
232    }
233
234    /// Respond to an error thrown by previous `AfterMiddleware` or the `Handler`.
235    ///
236    /// Returning `Ok` will cause the request to resume the normal flow at the
237    /// next `AfterMiddleware`.
238    async fn catch(&self, _: &mut Request, err: Error) -> Result<Response> {
239        Err(err)
240    }
241}
242
243#[async_trait(?Send)]
244/// `AroundMiddleware` are used to wrap and replace the `Handler` in the `Middlewares` chain.
245///
246/// `AroundMiddleware` produce `Handler`s through their `around` method, which is
247/// called once on insertion into the `Middlewares` chain or can be called manually outside of a
248/// `Middlewares` chain.
249pub trait AroundMiddleware {
250    /// Produce a `Handler` from this `AroundMiddleware` given another `Handler`.
251    ///
252    /// Usually this means wrapping the handler and editing the `Request` on the
253    /// way in and the `Response` on the way out.
254    ///
255    /// This is called only once, when an `AroundMiddleware` is added to the `Middlewares` chain
256    /// using `Middlewares::around`, it is passed the `Middlewares` chain's current `Handler`.
257    async fn around(self, handler: Box<dyn Handler>) -> Box<dyn Handler>;
258}
259
260/// The middleware chain which can append other middlewares.
261///
262/// This is a canonical implementation of Iron's middleware system,
263/// but Iron's infrastructure is flexible enough to allow alternate
264/// systems.
265pub struct Middlewares {
266    befores: Vec<Box<dyn BeforeMiddleware>>,
267    afters: Vec<Box<dyn AfterMiddleware>>,
268
269    // Internal invariant: this is always Some
270    handler: Option<Box<dyn Handler>>,
271}
272
273impl Middlewares {
274    /// Construct a new middleware chain from a `Handler`.
275    pub fn new<H>(handler: H) -> Self
276    where
277        H: Handler,
278    {
279        Self {
280            befores: vec![],
281            afters: vec![],
282            handler: Some(Box::new(handler) as Box<dyn Handler>),
283        }
284    }
285
286    /// Link both a before and after middleware to the chain at once.
287    ///
288    /// Middleware that have a Before and After piece should have a constructor
289    /// which returns both as a tuple, so it can be passed directly to link.
290    pub fn link<B, A>(&mut self, link: (B, A)) -> &mut Middlewares
291    where
292        A: AfterMiddleware,
293        B: BeforeMiddleware,
294    {
295        let (before, after) = link;
296        self.befores
297            .push(Box::new(before) as Box<dyn BeforeMiddleware>);
298        self.afters
299            .push(Box::new(after) as Box<dyn AfterMiddleware>);
300        self
301    }
302
303    /// Link a `BeforeMiddleware` to the `Middlewares` chain, after all previously linked
304    /// `BeforeMiddleware`s.
305    pub fn link_before<B>(&mut self, before: B) -> &mut Middlewares
306    where
307        B: BeforeMiddleware,
308    {
309        self.befores
310            .push(Box::new(before) as Box<dyn BeforeMiddleware>);
311        self
312    }
313
314    /// Link a `AfterMiddleware` to the `Middlewares` chain, after all previously linked
315    /// `AfterMiddleware`s.
316    pub fn link_after<A>(&mut self, after: A) -> &mut Middlewares
317    where
318        A: AfterMiddleware,
319    {
320        self.afters
321            .push(Box::new(after) as Box<dyn AfterMiddleware>);
322        self
323    }
324
325    /// Apply an `AroundMiddleware` to the `Handler` in this `Middlewares` chain.
326    pub async fn link_around<A>(&mut self, around: A) -> &mut Middlewares
327    where
328        A: AroundMiddleware,
329    {
330        let mut handler = self.handler.take().unwrap();
331        handler = around.around(handler).await;
332        self.handler = Some(handler);
333        self
334    }
335}
336
337#[async_trait]
338impl Handler for Middlewares {
339    async fn handle(&self, req: &mut Request) -> Result<Response> {
340        // Kick off at befores, which will continue into handler
341        // then afters.
342        self.continue_from_before(req, 0).await
343    }
344}
345
346impl Middlewares {
347    #[async_recursion]
348    // Enter the error flow from a before middleware, starting
349    // at the passed index.
350    //
351    // If the index is out of bounds for the before middleware Vec,
352    // this instead behaves the same as fail_from_handler.
353    async fn fail_from_before(
354        &self,
355        req: &mut Request,
356        index: usize,
357        mut err: Error,
358    ) -> Result<Response> {
359        // If this was the last before, yield to next phase.
360        if index >= self.befores.len() {
361            return self.fail_from_handler(req, err).await;
362        }
363
364        for (i, before) in self.befores[index..].iter().enumerate() {
365            err = match before.catch(req, err).await {
366                Err(err) => err,
367                Ok(()) => return self.continue_from_before(req, index + i + 1).await,
368            };
369        }
370
371        // Next phase
372        self.fail_from_handler(req, err).await
373    }
374
375    // Enter the normal flow in the before middleware, starting with the passed
376    // index.
377    async fn continue_from_before(&self, req: &mut Request, index: usize) -> Result<Response> {
378        // If this was the last beforemiddleware, start at the handler.
379        if index >= self.befores.len() {
380            return self.continue_from_handler(req).await;
381        }
382
383        for (i, before) in self.befores[index..].iter().enumerate() {
384            match before.before(req).await {
385                Ok(()) => {}
386                Err(err) => return self.fail_from_before(req, index + i + 1, err).await,
387            }
388        }
389
390        // Yield to next phase.
391        self.continue_from_handler(req).await
392    }
393
394    // Enter the error flow from an errored handle, starting with the
395    // first AfterMiddleware.
396    async fn fail_from_handler(&self, req: &mut Request, err: Error) -> Result<Response> {
397        // Yield to next phase, nothing to do here.
398        self.fail_from_after(req, 0, err).await
399    }
400
401    // Enter the error flow from an errored after middleware, starting
402    // with the passed index.
403    //
404    // If the index is out of bounds for the after middleware Vec,
405    // this instead just returns the passed error.
406    async fn fail_from_after(
407        &self,
408        req: &mut Request,
409        index: usize,
410        mut err: Error,
411    ) -> Result<Response> {
412        // If this was the last after, we're done.
413        if index == self.afters.len() {
414            return Err(err);
415        }
416
417        for (i, after) in self.afters[index..].iter().enumerate() {
418            err = match after.catch(req, err).await {
419                Err(err) => err,
420                Ok(res) => return self.continue_from_after(req, index + i + 1, res).await,
421            }
422        }
423
424        // Done
425        Err(err)
426    }
427
428    // Enter the normal flow at the handler.
429    async fn continue_from_handler(&self, req: &mut Request) -> Result<Response> {
430        // unwrap is safe because it's always Some
431        match self.handler.as_ref().unwrap().handle(req).await {
432            Ok(res) => self.continue_from_after(req, 0, res).await,
433            Err(err) => self.fail_from_handler(req, err).await,
434        }
435    }
436
437    #[async_recursion]
438    // Enter the normal flow in the after middleware, starting with the passed
439    // index.
440    async fn continue_from_after(
441        &self,
442        req: &mut Request,
443        index: usize,
444        mut res: Response,
445    ) -> Result<Response> {
446        // If this was the last after middleware, we're done.
447        if index >= self.afters.len() {
448            return Ok(res);
449        }
450
451        for (i, after) in self.afters[index..].iter().enumerate() {
452            res = match after.after(req, res).await {
453                Ok(res) => res,
454                Err(err) => return self.fail_from_after(req, index + i + 1, err).await,
455            }
456        }
457
458        // We made it with no error!
459        Ok(res)
460    }
461}
462
463#[async_trait]
464impl<F> BeforeMiddleware for F
465where
466    F: Send + Sync + 'static + Fn(&mut Request) -> Result<()>,
467{
468    async fn before(&self, req: &mut Request) -> Result<()> {
469        (*self)(req)
470    }
471}
472
473#[async_trait]
474impl BeforeMiddleware for Box<dyn BeforeMiddleware> {
475    async fn before(&self, req: &mut Request) -> Result<()> {
476        (**self).before(req).await
477    }
478
479    async fn catch(&self, req: &mut Request, err: Error) -> Result<()> {
480        (**self).catch(req, err).await
481    }
482}
483
484#[async_trait]
485impl<T> BeforeMiddleware for Arc<T>
486where
487    T: BeforeMiddleware,
488{
489    async fn before(&self, req: &mut Request) -> Result<()> {
490        (**self).before(req).await
491    }
492
493    async fn catch(&self, req: &mut Request, err: Error) -> Result<()> {
494        (**self).catch(req, err).await
495    }
496}
497
498#[async_trait]
499impl<F> AfterMiddleware for F
500where
501    F: Send + Sync + 'static + Fn(&mut Request, Response) -> Result<Response>,
502{
503    async fn after(&self, req: &mut Request, res: Response) -> Result<Response> {
504        (*self)(req, res)
505    }
506}
507
508#[async_trait]
509impl AfterMiddleware for Box<dyn AfterMiddleware> {
510    async fn after(&self, req: &mut Request, res: Response) -> Result<Response> {
511        (**self).after(req, res).await
512    }
513
514    async fn catch(&self, req: &mut Request, err: Error) -> Result<Response> {
515        (**self).catch(req, err).await
516    }
517}
518
519#[async_trait]
520impl<T> AfterMiddleware for Arc<T>
521where
522    T: AfterMiddleware,
523{
524    async fn after(&self, req: &mut Request, res: Response) -> Result<Response> {
525        (**self).after(req, res).await
526    }
527
528    async fn catch(&self, req: &mut Request, err: Error) -> Result<Response> {
529        (**self).catch(req, err).await
530    }
531}
532
533#[async_trait(?Send)]
534impl<F> AroundMiddleware for F
535where
536    F: FnOnce(Box<dyn Handler>) -> Box<dyn Handler>,
537{
538    async fn around(self, handler: Box<dyn Handler>) -> Box<dyn Handler> {
539        self(handler)
540    }
541}