Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
//! Fairings: callbacks at launch, liftoff, request, and response time.
|
2017-04-20 20:43:01 +00:00
|
|
|
//!
|
|
|
|
//! Fairings allow for structured interposition at various points in the
|
|
|
|
//! application lifetime. Fairings can be seen as a restricted form of
|
2017-05-15 04:46:01 +00:00
|
|
|
//! "middleware". A fairing is an arbitrary structure with methods representing
|
|
|
|
//! callbacks that Rocket will run at requested points in a program. You can use
|
|
|
|
//! fairings to rewrite or record information about requests and responses, or
|
|
|
|
//! to perform an action once a Rocket application has launched.
|
2017-04-20 20:43:01 +00:00
|
|
|
//!
|
2017-06-25 01:31:22 +00:00
|
|
|
//! To learn more about writing a fairing, see the [`Fairing`] trait
|
2020-05-31 18:31:57 +00:00
|
|
|
//! documentation. You can also use [`AdHoc`] to create a fairing on-the-fly
|
|
|
|
//! from a closure or function.
|
2017-06-20 00:20:10 +00:00
|
|
|
//!
|
2017-04-20 20:43:01 +00:00
|
|
|
//! ## Attaching
|
|
|
|
//!
|
|
|
|
//! You must inform Rocket about fairings that you wish to be active by calling
|
2018-10-06 13:25:17 +00:00
|
|
|
//! [`Rocket::attach()`] method on the application's [`Rocket`] instance and
|
|
|
|
//! passing in the appropriate [`Fairing`]. For instance, to attach fairings
|
|
|
|
//! named `req_fairing` and `res_fairing` to a new Rocket instance, you might
|
|
|
|
//! write:
|
2017-04-20 20:43:01 +00:00
|
|
|
//!
|
|
|
|
//! ```rust
|
2017-05-15 04:46:01 +00:00
|
|
|
//! # use rocket::fairing::AdHoc;
|
2019-12-11 00:34:32 +00:00
|
|
|
//! # let req_fairing = AdHoc::on_request("Request", |_, _| Box::pin(async move {}));
|
2019-08-07 00:08:00 +00:00
|
|
|
//! # let res_fairing = AdHoc::on_response("Response", |_, _| Box::pin(async move {}));
|
2017-04-20 20:43:01 +00:00
|
|
|
//! let rocket = rocket::ignite()
|
2017-05-15 04:46:01 +00:00
|
|
|
//! .attach(req_fairing)
|
|
|
|
//! .attach(res_fairing);
|
2017-04-20 20:43:01 +00:00
|
|
|
//! ```
|
|
|
|
//!
|
2018-07-12 03:44:09 +00:00
|
|
|
//! Once a fairing is attached, Rocket will execute it at the appropriate time,
|
2017-06-25 01:31:22 +00:00
|
|
|
//! which varies depending on the fairing implementation. See the [`Fairing`]
|
|
|
|
//! trait documentation for more information on the dispatching of fairing
|
|
|
|
//! methods.
|
|
|
|
//!
|
2019-06-13 01:48:02 +00:00
|
|
|
//! [`Fairing`]: crate::fairing::Fairing
|
2017-05-15 04:46:01 +00:00
|
|
|
//!
|
|
|
|
//! ## Ordering
|
|
|
|
//!
|
2017-06-25 01:31:22 +00:00
|
|
|
//! `Fairing`s are executed in the order in which they are attached: the first
|
|
|
|
//! attached fairing has its callbacks executed before all others. Because
|
|
|
|
//! fairing callbacks may not be commutative, the order in which fairings are
|
|
|
|
//! attached may be significant. Because of this, it is important to communicate
|
|
|
|
//! to the user every consequence of a fairing.
|
|
|
|
//!
|
|
|
|
//! Furthermore, a `Fairing` should take care to act locally so that the actions
|
|
|
|
//! of other `Fairings` are not jeopardized. For instance, unless it is made
|
|
|
|
//! abundantly clear, a fairing should not rewrite every request.
|
2018-02-04 10:07:28 +00:00
|
|
|
|
2020-10-22 10:27:04 +00:00
|
|
|
use crate::{Rocket, Request, Response, Data};
|
2017-04-20 20:43:01 +00:00
|
|
|
|
2017-05-15 04:46:01 +00:00
|
|
|
mod fairings;
|
|
|
|
mod ad_hoc;
|
|
|
|
mod info_kind;
|
|
|
|
|
2019-09-20 20:43:05 +00:00
|
|
|
pub(crate) use self::fairings::Fairings;
|
2017-05-15 04:46:01 +00:00
|
|
|
pub use self::ad_hoc::AdHoc;
|
|
|
|
pub use self::info_kind::{Info, Kind};
|
|
|
|
|
2017-04-20 20:43:01 +00:00
|
|
|
// We might imagine that a request fairing returns an `Outcome`. If it returns
|
|
|
|
// `Success`, we don't do any routing and use that response directly. Same if it
|
|
|
|
// returns `Failure`. We only route if it returns `Forward`. I've chosen not to
|
|
|
|
// go this direction because I feel like request guards are the correct
|
|
|
|
// mechanism to use here. In other words, enabling this at the fairing level
|
|
|
|
// encourages implicit handling, a bad practice. Fairings can still, however,
|
|
|
|
// return a default `Response` if routing fails via a response fairing. For
|
|
|
|
// instance, to automatically handle preflight in CORS, a response fairing can
|
|
|
|
// check that the user didn't handle the `OPTIONS` request (404) and return an
|
|
|
|
// appropriate response. This allows the users to handle `OPTIONS` requests
|
|
|
|
// when they'd like but default to the fairing when they don't want to.
|
|
|
|
|
2017-05-15 04:46:01 +00:00
|
|
|
/// Trait implemented by fairings: Rocket's structured middleware.
|
2017-04-20 20:43:01 +00:00
|
|
|
///
|
2017-06-25 01:31:22 +00:00
|
|
|
/// # Considerations
|
2017-04-20 20:43:01 +00:00
|
|
|
///
|
2017-06-25 01:31:22 +00:00
|
|
|
/// Fairings are a large hammer that can easily be abused and misused. If you
|
|
|
|
/// are considering writing a `Fairing` implementation, first consider if it is
|
2017-07-07 03:48:25 +00:00
|
|
|
/// appropriate to do so. While middleware is often the best solution to some
|
2017-06-25 01:31:22 +00:00
|
|
|
/// problems in other frameworks, it is often a suboptimal solution in Rocket.
|
|
|
|
/// This is because Rocket provides richer mechanisms such as [request guards]
|
|
|
|
/// and [data guards] that can be used to accomplish the same objective in a
|
|
|
|
/// cleaner, more composable, and more robust manner.
|
2017-04-20 20:43:01 +00:00
|
|
|
///
|
2017-06-25 01:31:22 +00:00
|
|
|
/// As a general rule of thumb, only _globally applicable actions_ should be
|
|
|
|
/// implemented via fairings. For instance, you should _not_ use a fairing to
|
|
|
|
/// implement authentication or authorization (preferring to use a [request
|
2017-07-07 03:48:25 +00:00
|
|
|
/// guard] instead) _unless_ the authentication or authorization applies to the
|
2017-06-25 01:31:22 +00:00
|
|
|
/// entire application. On the other hand, you _should_ use a fairing to record
|
|
|
|
/// timing and/or usage statistics or to implement global security policies.
|
2017-04-20 20:43:01 +00:00
|
|
|
///
|
2019-06-13 01:48:02 +00:00
|
|
|
/// [request guard]: crate::request::FromRequest
|
|
|
|
/// [request guards]: crate::request::FromRequest
|
UTF-8 routes. Forms revamp. Temp files. Capped.
So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves #106)
* Collections are supported in forms and queries. (resolves #205)
* Nested structures in forms and queries are supported. (resolves #313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves #972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves #1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
2020-10-30 03:50:06 +00:00
|
|
|
/// [data guards]: crate::data::FromData
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// ## Fairing Callbacks
|
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// There are four kinds of fairing callbacks: launch, liftoff, request, and
|
2017-06-25 01:31:22 +00:00
|
|
|
/// response. A fairing can request any combination of these callbacks through
|
|
|
|
/// the `kind` field of the `Info` structure returned from the `info` method.
|
|
|
|
/// Rocket will only invoke the callbacks set in the `kind` field.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
2017-05-17 08:39:36 +00:00
|
|
|
/// The four callback kinds are as follows:
|
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// * **Launch (`on_launch`)**
|
2017-05-17 08:39:36 +00:00
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// A launch callback, represented by the [`Fairing::on_launch()`] method,
|
|
|
|
/// is called just prior to liftoff, while launching the application. The
|
|
|
|
/// state of the `Rocket` instance is, at this point, not finalized, as it
|
|
|
|
/// may be modified at will by other launch fairings. As a result, it is
|
|
|
|
/// unwise to depend on the state of the `Rocket` instance.
|
|
|
|
///
|
|
|
|
/// All launch callbacks are executed in breadth-first `attach()` order. A
|
|
|
|
/// callback `B` executing after a callback `A` can view changes made by `A`
|
|
|
|
/// but not vice-versa.
|
|
|
|
///
|
|
|
|
/// A launch callback can arbitrarily modify the `Rocket` instance being
|
|
|
|
/// constructed. It should take care not to introduce infinite recursion by
|
|
|
|
/// recursively attaching launch fairings. It returns `Ok` if it would like
|
|
|
|
/// launching to proceed nominally and `Err` otherwise. If a launch fairing
|
|
|
|
/// returns `Err`, launch will be aborted. All launch fairings are executed
|
2017-05-17 08:39:36 +00:00
|
|
|
/// even if one or more signal a failure.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// * **Liftoff (`on_liftoff`)**
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// A liftoff callback, represented by the [`Fairing::on_liftoff()`] method,
|
|
|
|
/// is called immediately after a Rocket application has launched. At this
|
|
|
|
/// point, Rocket has opened a socket for listening but has not yet begun
|
|
|
|
/// accepting connections. A liftoff callback can inspect the `Rocket`
|
|
|
|
/// instance that has launched but not otherwise gracefully abort launch.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// * **Request (`on_request`)**
|
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// A request callback, represented by the [`Fairing::on_request()`] method,
|
|
|
|
/// is called just after a request is received, immediately after
|
2018-04-08 23:14:15 +00:00
|
|
|
/// pre-processing the request with method changes due to `_method` form
|
|
|
|
/// fields. At this point, Rocket has parsed the incoming HTTP request into
|
2018-10-06 13:25:17 +00:00
|
|
|
/// [`Request`] and [`Data`] structures but has not routed the request. A
|
|
|
|
/// request callback can modify the request at will and [`Data::peek()`]
|
|
|
|
/// into the incoming data. It may not, however, abort or respond directly
|
|
|
|
/// to the request; these issues are better handled via [request guards] or
|
|
|
|
/// via response callbacks. Any modifications to a request are persisted and
|
|
|
|
/// can potentially alter how a request is routed.
|
2020-01-31 04:47:57 +00:00
|
|
|
///
|
2017-05-15 04:46:01 +00:00
|
|
|
/// * **Response (`on_response`)**
|
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// A response callback, represented by the [`Fairing::on_response()`]
|
|
|
|
/// method, is called when a response is ready to be sent to the client. At
|
|
|
|
/// this point, Rocket has completed all routing, including to error
|
|
|
|
/// catchers, and has generated the would-be final response. A response
|
|
|
|
/// callback can modify the response at will. For example, a response
|
|
|
|
/// callback can provide a default response when the user fails to handle
|
|
|
|
/// the request by checking for 404 responses. Note that a given `Request`
|
|
|
|
/// may have changed between `on_request` and `on_response` invocations.
|
|
|
|
/// Apart from any change made by other fairings, Rocket sets the method for
|
|
|
|
/// `HEAD` requests to `GET` if there is no matching `HEAD` handler for that
|
|
|
|
/// request. Additionally, Rocket will automatically strip the body for
|
|
|
|
/// `HEAD` requests _after_ response fairings have run.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// # Implementing
|
|
|
|
///
|
2017-06-25 01:31:22 +00:00
|
|
|
/// A `Fairing` implementation has one required method: [`info`]. A `Fairing`
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// can also implement any of the available callbacks: `on_launch`, `on_liftoff`,
|
2017-05-17 08:39:36 +00:00
|
|
|
/// `on_request`, and `on_response`. A `Fairing` _must_ set the appropriate
|
|
|
|
/// callback kind in the `kind` field of the returned `Info` structure from
|
2017-06-25 01:31:22 +00:00
|
|
|
/// [`info`] for a callback to actually be called by Rocket.
|
|
|
|
///
|
|
|
|
/// ## Fairing `Info`
|
|
|
|
///
|
|
|
|
/// Every `Fairing` must implement the [`info`] method, which returns an
|
2018-10-06 13:25:17 +00:00
|
|
|
/// [`Info`] structure. This structure is used by Rocket to:
|
2017-06-25 01:31:22 +00:00
|
|
|
///
|
|
|
|
/// 1. Assign a name to the `Fairing`.
|
|
|
|
///
|
2017-09-05 16:40:41 +00:00
|
|
|
/// This is the `name` field, which can be any arbitrary string. Name your
|
|
|
|
/// fairing something illustrative. The name will be logged during the
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// application's ignition procedures.
|
2017-06-25 01:31:22 +00:00
|
|
|
///
|
|
|
|
/// 2. Determine which callbacks to actually issue on the `Fairing`.
|
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// This is the `kind` field of type [`Kind`]. This field is a bitset that
|
2017-09-05 16:40:41 +00:00
|
|
|
/// represents the kinds of callbacks the fairing wishes to receive. Rocket
|
|
|
|
/// will only invoke the callbacks that are flagged in this set. `Kind`
|
|
|
|
/// structures can be `or`d together to represent any combination of kinds
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// of callbacks. For instance, to request liftoff and response callbacks,
|
|
|
|
/// return a `kind` field with the value `Kind::Liftoff | Kind::Response`.
|
2017-06-25 01:31:22 +00:00
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// [`info`]: Fairing::info()
|
2017-06-25 01:31:22 +00:00
|
|
|
///
|
|
|
|
/// ## Restrictions
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
2018-10-06 13:25:17 +00:00
|
|
|
/// A `Fairing` must be [`Send`] + [`Sync`] + `'static`. This means that the
|
|
|
|
/// fairing must be sendable across thread boundaries (`Send`), thread-safe
|
|
|
|
/// (`Sync`), and have only `'static` references, if any (`'static`). Note that
|
|
|
|
/// these bounds _do not_ prohibit a `Fairing` from holding state: the state
|
|
|
|
/// need simply be thread-safe and statically available or heap allocated.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
2020-01-31 04:47:57 +00:00
|
|
|
/// ## Async Trait
|
|
|
|
///
|
|
|
|
/// [`Fairing`] is an _async_ trait. Implementations of `Fairing` must be
|
|
|
|
/// decorated with an attribute of `#[rocket::async_trait]`:
|
|
|
|
///
|
|
|
|
/// ```rust
|
2020-10-22 10:27:04 +00:00
|
|
|
/// use rocket::{Rocket, Request, Data, Response};
|
2020-01-31 04:47:57 +00:00
|
|
|
/// use rocket::fairing::{Fairing, Info, Kind};
|
|
|
|
///
|
|
|
|
/// # struct MyType;
|
|
|
|
/// #[rocket::async_trait]
|
|
|
|
/// impl Fairing for MyType {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// async fn on_launch(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// async fn on_liftoff(&self, rocket: &Rocket) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
2020-10-21 03:22:32 +00:00
|
|
|
/// async fn on_request(&self, req: &mut Request<'_>, data: &mut Data) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
2020-07-23 20:08:49 +00:00
|
|
|
/// async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
2017-06-25 01:31:22 +00:00
|
|
|
/// ## Example
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// As an example, we want to record the number of `GET` and `POST` requests
|
|
|
|
/// that our application has received. While we could do this with [request
|
|
|
|
/// guards] and [managed state](crate::State), it would require us to annotate
|
|
|
|
/// every `GET` and `POST` request with custom types, polluting handler
|
|
|
|
/// signatures. Instead, we can create a simple fairing that acts globally.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// The `Counter` fairing below records the number of all `GET` and `POST`
|
|
|
|
/// requests received. It makes these counts available at a special `'/counts'`
|
|
|
|
/// path.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2019-08-07 00:08:00 +00:00
|
|
|
/// use std::future::Future;
|
2017-05-15 04:46:01 +00:00
|
|
|
/// use std::io::Cursor;
|
2019-08-07 00:08:00 +00:00
|
|
|
/// use std::pin::Pin;
|
2017-05-15 04:46:01 +00:00
|
|
|
/// use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
///
|
|
|
|
/// use rocket::{Request, Data, Response};
|
|
|
|
/// use rocket::fairing::{Fairing, Info, Kind};
|
|
|
|
/// use rocket::http::{Method, ContentType, Status};
|
|
|
|
///
|
|
|
|
/// #[derive(Default)]
|
|
|
|
/// struct Counter {
|
|
|
|
/// get: AtomicUsize,
|
|
|
|
/// post: AtomicUsize,
|
|
|
|
/// }
|
|
|
|
///
|
2020-01-31 04:47:57 +00:00
|
|
|
/// #[rocket::async_trait]
|
2017-05-15 04:46:01 +00:00
|
|
|
/// impl Fairing for Counter {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// Info {
|
|
|
|
/// name: "GET/POST Counter",
|
|
|
|
/// kind: Kind::Request | Kind::Response
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
2020-10-21 03:22:32 +00:00
|
|
|
/// async fn on_request(&self, req: &mut Request<'_>, _: &mut Data) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// if req.method() == Method::Get {
|
|
|
|
/// self.get.fetch_add(1, Ordering::Relaxed);
|
|
|
|
/// } else if req.method() == Method::Post {
|
|
|
|
/// self.post.fetch_add(1, Ordering::Relaxed);
|
|
|
|
/// }
|
2017-05-15 04:46:01 +00:00
|
|
|
/// }
|
|
|
|
///
|
2020-07-23 20:08:49 +00:00
|
|
|
/// async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// // Don't change a successful user's response, ever.
|
|
|
|
/// if res.status() != Status::NotFound {
|
|
|
|
/// return
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// if req.method() == Method::Get && req.uri().path() == "/counts" {
|
|
|
|
/// let get_count = self.get.load(Ordering::Relaxed);
|
|
|
|
/// let post_count = self.post.load(Ordering::Relaxed);
|
|
|
|
///
|
|
|
|
/// let body = format!("Get: {}\nPost: {}", get_count, post_count);
|
|
|
|
/// res.set_status(Status::Ok);
|
|
|
|
/// res.set_header(ContentType::Plain);
|
2020-06-19 13:01:10 +00:00
|
|
|
/// res.set_sized_body(body.len(), Cursor::new(body));
|
2020-01-31 04:47:57 +00:00
|
|
|
/// }
|
2017-05-15 04:46:01 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2018-08-01 01:22:36 +00:00
|
|
|
///
|
2018-08-08 05:29:38 +00:00
|
|
|
/// ## Request-Local State
|
2018-08-01 01:22:36 +00:00
|
|
|
///
|
2018-08-08 05:29:38 +00:00
|
|
|
/// Fairings can use [request-local state] to persist or carry data between
|
|
|
|
/// requests and responses, or to pass data to a request guard.
|
2018-08-01 01:22:36 +00:00
|
|
|
///
|
2018-08-08 05:29:38 +00:00
|
|
|
/// As an example, the following fairing uses request-local state to time
|
|
|
|
/// requests, setting an `X-Response-Time` header on all responses with the
|
|
|
|
/// elapsed time. It also exposes the start time of a request via a `StartTime`
|
|
|
|
/// request guard.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2019-08-07 00:08:00 +00:00
|
|
|
/// # use std::future::Future;
|
|
|
|
/// # use std::pin::Pin;
|
2018-08-01 01:22:36 +00:00
|
|
|
/// # use std::time::{Duration, SystemTime};
|
|
|
|
/// # use rocket::{Request, Data, Response};
|
|
|
|
/// # use rocket::fairing::{Fairing, Info, Kind};
|
|
|
|
/// # use rocket::http::Status;
|
|
|
|
/// # use rocket::request::{self, FromRequest};
|
|
|
|
/// #
|
2018-08-08 05:29:38 +00:00
|
|
|
/// /// Fairing for timing requests.
|
|
|
|
/// pub struct RequestTimer;
|
|
|
|
///
|
|
|
|
/// /// Value stored in request-local state.
|
2018-08-01 01:22:36 +00:00
|
|
|
/// #[derive(Copy, Clone)]
|
2018-08-08 05:29:38 +00:00
|
|
|
/// struct TimerStart(Option<SystemTime>);
|
2018-08-01 01:22:36 +00:00
|
|
|
///
|
2020-01-31 04:47:57 +00:00
|
|
|
/// #[rocket::async_trait]
|
2018-08-01 01:22:36 +00:00
|
|
|
/// impl Fairing for RequestTimer {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// Info {
|
|
|
|
/// name: "Request Timer",
|
|
|
|
/// kind: Kind::Request | Kind::Response
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
2018-08-08 05:29:38 +00:00
|
|
|
/// /// Stores the start time of the request in request-local state.
|
2020-10-21 03:22:32 +00:00
|
|
|
/// async fn on_request(&self, request: &mut Request<'_>, _: &mut Data) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// // Store a `TimerStart` instead of directly storing a `SystemTime`
|
|
|
|
/// // to ensure that this usage doesn't conflict with anything else
|
|
|
|
/// // that might store a `SystemTime` in request-local cache.
|
|
|
|
/// request.local_cache(|| TimerStart(Some(SystemTime::now())));
|
2018-08-01 01:22:36 +00:00
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// /// Adds a header to the response indicating how long the server took to
|
2018-08-08 05:29:38 +00:00
|
|
|
/// /// process the request.
|
2020-07-23 20:08:49 +00:00
|
|
|
/// async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// let start_time = req.local_cache(|| TimerStart(None));
|
|
|
|
/// if let Some(Ok(duration)) = start_time.0.map(|st| st.elapsed()) {
|
|
|
|
/// let ms = duration.as_secs() * 1000 + duration.subsec_millis() as u64;
|
|
|
|
/// res.set_raw_header("X-Response-Time", format!("{} ms", ms));
|
|
|
|
/// }
|
2018-08-01 01:22:36 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
2018-08-08 05:29:38 +00:00
|
|
|
/// /// Request guard used to retrieve the start time of a request.
|
|
|
|
/// #[derive(Copy, Clone)]
|
|
|
|
/// pub struct StartTime(pub SystemTime);
|
|
|
|
///
|
|
|
|
/// // Allows a route to access the time a request was initiated.
|
2020-01-31 09:34:15 +00:00
|
|
|
/// #[rocket::async_trait]
|
2021-03-15 02:57:59 +00:00
|
|
|
/// impl<'r> FromRequest<'r> for StartTime {
|
2018-08-01 01:22:36 +00:00
|
|
|
/// type Error = ();
|
|
|
|
///
|
2021-03-15 02:57:59 +00:00
|
|
|
/// async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, ()> {
|
2018-08-08 05:29:38 +00:00
|
|
|
/// match *request.local_cache(|| TimerStart(None)) {
|
2020-07-22 23:10:02 +00:00
|
|
|
/// TimerStart(Some(time)) => request::Outcome::Success(StartTime(time)),
|
|
|
|
/// TimerStart(None) => request::Outcome::Failure((Status::InternalServerError, ())),
|
2018-08-01 01:22:36 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
2018-08-08 05:29:38 +00:00
|
|
|
///
|
2020-10-21 11:54:24 +00:00
|
|
|
/// [request-local state]: https://rocket.rs/master/guide/state/#request-local-state
|
2020-01-31 04:47:57 +00:00
|
|
|
#[crate::async_trait]
|
2017-05-15 04:46:01 +00:00
|
|
|
pub trait Fairing: Send + Sync + 'static {
|
2018-10-06 13:25:17 +00:00
|
|
|
/// Returns an [`Info`] structure containing the `name` and [`Kind`] of this
|
|
|
|
/// fairing. The `name` can be any arbitrary string. `Kind` must be an `or`d
|
|
|
|
/// set of `Kind` variants.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// This is the only required method of a `Fairing`. All other methods have
|
|
|
|
/// no-op default implementations.
|
|
|
|
///
|
|
|
|
/// Rocket will only dispatch callbacks to this fairing for the kinds in the
|
|
|
|
/// `kind` field of the returned `Info` structure. For instance, if
|
|
|
|
/// `Kind::Launch | Kind::Request` is used, then Rocket will only call the
|
|
|
|
/// `on_launch` and `on_request` methods of the fairing. Similarly, if
|
|
|
|
/// `Kind::Response` is used, Rocket will only call the `on_response` method
|
|
|
|
/// of this fairing.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// An `info` implementation for `MyFairing`: a fairing named "My Custom
|
|
|
|
/// Fairing" that is both a launch and response fairing.
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::fairing::{Fairing, Info, Kind};
|
|
|
|
///
|
|
|
|
/// struct MyFairing;
|
|
|
|
///
|
|
|
|
/// impl Fairing for MyFairing {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// Info {
|
|
|
|
/// name: "My Custom Fairing",
|
2017-07-14 20:01:57 +00:00
|
|
|
/// kind: Kind::Launch | Kind::Response
|
2017-05-15 04:46:01 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
fn info(&self) -> Info;
|
2017-04-20 20:43:01 +00:00
|
|
|
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// The launch callback. Returns `Ok` if launch should proceed and `Err` if
|
2017-05-15 04:46:01 +00:00
|
|
|
/// launch should be aborted.
|
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// This method is called when the application is being launched if
|
|
|
|
/// `Kind::Launch` is in the `kind` field of the `Info` structure for this
|
|
|
|
/// fairing. The `rocket` parameter is the `Rocket` instance that is
|
|
|
|
/// currently being built for this application.
|
2017-05-17 08:39:36 +00:00
|
|
|
///
|
|
|
|
/// ## Default Implementation
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// The default implementation of this method simply returns `Ok(rocket)`.
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_launch(&self, rocket: Rocket) -> Result<Rocket, Rocket> { Ok(rocket) }
|
2017-05-17 08:39:36 +00:00
|
|
|
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// The liftoff callback.
|
2017-05-17 08:39:36 +00:00
|
|
|
///
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
/// This method is called just after launching the application if
|
|
|
|
/// `Kind::Liftoff` is in the `kind` field of the `Info` structure for this
|
|
|
|
/// fairing. The `Rocket` parameter corresponds to the lauched application.
|
2017-05-17 08:39:36 +00:00
|
|
|
///
|
|
|
|
/// ## Default Implementation
|
|
|
|
///
|
|
|
|
/// The default implementation of this method does nothing.
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_liftoff(&self, _rocket: &Rocket) { }
|
2017-04-20 20:43:01 +00:00
|
|
|
|
2017-05-15 04:46:01 +00:00
|
|
|
/// The request callback.
|
|
|
|
///
|
|
|
|
/// This method is called when a new request is received if `Kind::Request`
|
|
|
|
/// is in the `kind` field of the `Info` structure for this fairing. The
|
|
|
|
/// `&mut Request` parameter is the incoming request, and the `&Data`
|
|
|
|
/// parameter is the incoming data in the request.
|
|
|
|
///
|
2017-05-17 08:39:36 +00:00
|
|
|
/// ## Default Implementation
|
|
|
|
///
|
2017-05-15 04:46:01 +00:00
|
|
|
/// The default implementation of this method does nothing.
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_request(&self, _req: &mut Request<'_>, _data: &mut Data) {}
|
2017-04-20 20:43:01 +00:00
|
|
|
|
2017-05-15 04:46:01 +00:00
|
|
|
/// The response callback.
|
|
|
|
///
|
|
|
|
/// This method is called when a response is ready to be issued to a client
|
|
|
|
/// if `Kind::Response` is in the `kind` field of the `Info` structure for
|
|
|
|
/// this fairing. The `&Request` parameter is the request that was routed,
|
|
|
|
/// and the `&mut Response` parameter is the resulting response.
|
|
|
|
///
|
2017-05-17 08:39:36 +00:00
|
|
|
/// ## Default Implementation
|
|
|
|
///
|
2017-05-15 04:46:01 +00:00
|
|
|
/// The default implementation of this method does nothing.
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_response<'r>(&self, _req: &'r Request<'_>, _res: &mut Response<'r>) {}
|
2017-04-20 20:43:01 +00:00
|
|
|
}
|
2017-07-07 03:48:25 +00:00
|
|
|
|
2020-01-31 04:47:57 +00:00
|
|
|
#[crate::async_trait]
|
2019-06-13 01:48:02 +00:00
|
|
|
impl<T: Fairing> Fairing for std::sync::Arc<T> {
|
2017-07-07 03:48:25 +00:00
|
|
|
#[inline]
|
|
|
|
fn info(&self) -> Info {
|
|
|
|
(self as &T).info()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_launch(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
|
|
|
|
(self as &T).on_launch(rocket).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_liftoff(&self, rocket: &Rocket) {
|
|
|
|
(self as &T).on_liftoff(rocket).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2020-10-21 03:22:32 +00:00
|
|
|
async fn on_request(&self, req: &mut Request<'_>, data: &mut Data) {
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
(self as &T).on_request(req, data).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2020-07-23 20:08:49 +00:00
|
|
|
async fn on_response<'r>(&self, req: &'r Request<'_>, res: &mut Response<'r>) {
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
(self as &T).on_response(req, res).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
}
|