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