Configure the rank of the injected Fairing error handling route (#36)

* Add option to change the rank of the injected Fairing error handling route

* Document the route
This commit is contained in:
Yong Wen Chua 2018-02-14 14:21:50 +08:00 committed by GitHub
parent 561cc86af5
commit ec04e27a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 6 deletions

View File

@ -30,6 +30,7 @@ fn main() {
max_age: Some(42), max_age: Some(42),
send_wildcard: false, send_wildcard: false,
fairing_route_base: "/mycors".to_string(), fairing_route_base: "/mycors".to_string(),
fairing_route_rank: 0,
}; };
println!("Default settings"); println!("Default settings");

View File

@ -53,8 +53,8 @@ pub(crate) fn fairing_error_route<'r>(
} }
/// Create a new `Route` for Fairing handling /// Create a new `Route` for Fairing handling
fn fairing_route() -> rocket::Route { fn fairing_route(rank: isize) -> rocket::Route {
rocket::Route::new(http::Method::Get, "/<status>", fairing_error_route) rocket::Route::ranked(rank, http::Method::Get, "/<status>", fairing_error_route)
} }
/// Modifies a `Request` to route to Fairing error handler /// Modifies a `Request` to route to Fairing error handler
@ -130,7 +130,10 @@ impl rocket::fairing::Fairing for Cors {
fn on_attach(&self, rocket: rocket::Rocket) -> Result<rocket::Rocket, rocket::Rocket> { fn on_attach(&self, rocket: rocket::Rocket) -> Result<rocket::Rocket, rocket::Rocket> {
match self.validate() { match self.validate() {
Ok(()) => Ok(rocket.mount(&self.fairing_route_base, vec![fairing_route()])), Ok(()) => Ok(rocket.mount(
&self.fairing_route_base,
vec![fairing_route(self.fairing_route_rank)],
)),
Err(e) => { Err(e) => {
error_!("Error attaching CORS fairing: {}", e); error_!("Error attaching CORS fairing: {}", e);
Err(rocket) Err(rocket)

View File

@ -134,6 +134,24 @@
//! } //! }
//! //!
//! ``` //! ```
//! #### Injected Route
//!
//! The fairing implementation will inject a route during attachment to Rocket. This route is used
//! to handle errors during CORS validation.
//!
//! This is due to the limitation in Rocket's Fairing
//! [lifecycle](https://rocket.rs/guide/fairings/). Ideally, we want to validate the CORS request
//! during `on_request`, and if the validation fails, we want to stop the route from even executing
//! to
//!
//! 1) prevent side effects
//! 1) prevent resource usage from unnecessary computation
//!
//! The only way to do this is to hijack the request and route it to our own injected route to
//! handle errors. Rocket does not allow Fairings to stop the processing of a route.
//!
//! You can configure the behaviour of the injected route through a couple of fields in the
//! [`Cors` struct](Cors).
//! //!
//! ### Request Guard //! ### Request Guard
//! //!
@ -916,7 +934,8 @@ impl AllowedHeaders {
/// "expose_headers": [], /// "expose_headers": [],
/// "max_age": null, /// "max_age": null,
/// "send_wildcard": false, /// "send_wildcard": false,
/// "fairing_route_base": "/cors" /// "fairing_route_base": "/cors",
/// "fairing_route_rank": 0
/// } /// }
/// ``` /// ```
/// ### Defined /// ### Defined
@ -1031,13 +1050,20 @@ pub struct Cors {
/// Defaults to `false`. /// Defaults to `false`.
#[cfg_attr(feature = "serialization", serde(default))] #[cfg_attr(feature = "serialization", serde(default))]
pub send_wildcard: bool, pub send_wildcard: bool,
/// When used as Fairing, Cors will need to redirect failed CORS checks to a custom route to /// When used as Fairing, Cors will need to redirect failed CORS checks to a custom route
/// be mounted by the fairing. Specify the base the route so that it doesn't clash with any /// mounted by the fairing. Specify the base of the route so that it doesn't clash with any
/// of your existing routes. /// of your existing routes.
/// ///
/// Defaults to "/cors" /// Defaults to "/cors"
#[cfg_attr(feature = "serialization", serde(default = "Cors::default_fairing_route_base"))] #[cfg_attr(feature = "serialization", serde(default = "Cors::default_fairing_route_base"))]
pub fairing_route_base: String, pub fairing_route_base: String,
/// When used as Fairing, Cors will need to redirect failed CORS checks to a custom route
/// mounted by the fairing. Specify the rank of the route so that it doesn't clash with any
/// of your existing routes. Remember that a higher ranked route has lower priority.
///
/// Defaults to 0
#[cfg_attr(feature = "serialization", serde(default = "Cors::default_fairing_route_rank"))]
pub fairing_route_rank: isize,
} }
impl Default for Cors { impl Default for Cors {
@ -1051,6 +1077,7 @@ impl Default for Cors {
max_age: Default::default(), max_age: Default::default(),
send_wildcard: Default::default(), send_wildcard: Default::default(),
fairing_route_base: Self::default_fairing_route_base(), fairing_route_base: Self::default_fairing_route_base(),
fairing_route_rank: Self::default_fairing_route_rank(),
} }
} }
} }
@ -1076,6 +1103,10 @@ impl Cors {
"/cors".to_string() "/cors".to_string()
} }
fn default_fairing_route_rank() -> isize {
0
}
/// Validates if any of the settings are disallowed or incorrect /// Validates if any of the settings are disallowed or incorrect
/// ///
/// This is run during initial Fairing attachment /// This is run during initial Fairing attachment