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}