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 {}));
|
2021-04-08 08:07:52 +00:00
|
|
|
//! let rocket = rocket::build()
|
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
|
2021-05-22 05:51:14 +00:00
|
|
|
//! attached fairing has its callbacks executed before all others. A fairing can
|
|
|
|
//! be attached any number of times. Except for [singleton
|
|
|
|
//! fairings](Fairing#singletons), all attached instances are polled at runtime.
|
|
|
|
//! Fairing callbacks may not be commutative; the order in which fairings are
|
|
|
|
//! attached may be significant. It is thus important to communicate specific
|
|
|
|
//! fairing functionality clearly.
|
2017-06-25 01:31:22 +00:00
|
|
|
//!
|
|
|
|
//! 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
|
|
|
|
2021-05-22 05:51:14 +00:00
|
|
|
use std::any::Any;
|
|
|
|
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
use crate::{Rocket, Request, Response, Data, Build, Orbit};
|
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};
|
|
|
|
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// A type alias for the return `Result` type of [`Fairing::on_ignite()`].
|
|
|
|
pub type Result<T = Rocket<Build>, E = Rocket<Build>> = std::result::Result<T, E>;
|
|
|
|
|
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
|
2021-05-22 05:51:14 +00:00
|
|
|
/// the `kind` field of the [`Info`] structure returned from the `info` method.
|
|
|
|
/// Rocket will only invoke the callbacks identified in the fairing's [`Kind`].
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
2017-05-17 08:39:36 +00:00
|
|
|
/// The four callback kinds are as follows:
|
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// * **Ignite (`on_ignite`)**
|
2017-05-17 08:39:36 +00:00
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// An ignite callback, represented by the [`Fairing::on_ignite()`] method,
|
|
|
|
/// is called just prior to liftoff, during ignition. The state of the
|
|
|
|
/// `Rocket` instance is, at this point, not finalized, as it may be
|
|
|
|
/// modified at will by other ignite fairings.
|
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
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// All ignite callbacks are executed in breadth-first `attach()` order. A
|
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
|
|
|
/// callback `B` executing after a callback `A` can view changes made by `A`
|
|
|
|
/// but not vice-versa.
|
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// An ignite callback can arbitrarily modify the `Rocket` instance being
|
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
|
|
|
/// constructed. It should take care not to introduce infinite recursion by
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// recursively attaching ignite fairings. It returns `Ok` if it would like
|
|
|
|
/// ignition and launch to proceed nominally and `Err` otherwise. If an
|
|
|
|
/// ignite fairing returns `Err`, launch will be aborted. All ignite
|
|
|
|
/// fairings are executed 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
|
|
|
///
|
2021-05-22 05:51:14 +00:00
|
|
|
/// # Singletons
|
|
|
|
///
|
|
|
|
/// In general, any number of instances of a given fairing type can be attached
|
|
|
|
/// to one instance of `Rocket`. If this is not desired, a fairing can request
|
|
|
|
/// to be a singleton by specifying [`Kind::Singleton`]. Only the _last_
|
|
|
|
/// attached instance of a singleton will be preserved at ignite-time. That is,
|
|
|
|
/// an attached singleton instance will replace any previously attached
|
|
|
|
/// instance. The [`Shield`](crate::shield::Shield) fairing is an example of a
|
|
|
|
/// singleton fairing.
|
|
|
|
///
|
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`
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// can also implement any of the available callbacks: `on_ignite`, `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
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// use rocket::{Rocket, Request, Data, Response, Build, Orbit};
|
|
|
|
/// use rocket::fairing::{self, Fairing, Info, Kind};
|
2020-01-31 04:47:57 +00:00
|
|
|
///
|
|
|
|
/// # struct MyType;
|
|
|
|
/// #[rocket::async_trait]
|
|
|
|
/// impl Fairing for MyType {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// async fn on_liftoff(&self, rocket: &Rocket<Orbit>) {
|
2020-01-31 04:47:57 +00:00
|
|
|
/// /* ... */
|
|
|
|
/// # unimplemented!()
|
|
|
|
/// }
|
|
|
|
///
|
2021-06-08 09:13:02 +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
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
2021-06-08 09:13:02 +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.
|
2021-06-08 09:13:02 +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
|
|
|
///
|
2021-06-09 08:53:34 +00:00
|
|
|
/// [request-local state]: https://rocket.rs/v0.5-rc/guide/state/#request-local-state
|
2020-01-31 04:47:57 +00:00
|
|
|
#[crate::async_trait]
|
2021-05-22 05:51:14 +00:00
|
|
|
pub trait Fairing: Send + Sync + Any + '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
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// `Kind::Ignite | Kind::Request` is used, then Rocket will only call the
|
|
|
|
/// `on_ignite` and `on_request` methods of the fairing. Similarly, if
|
2017-05-15 04:46:01 +00:00
|
|
|
/// `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
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// Fairing" that is both an ignite and response fairing.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use rocket::fairing::{Fairing, Info, Kind};
|
|
|
|
///
|
|
|
|
/// struct MyFairing;
|
|
|
|
///
|
|
|
|
/// impl Fairing for MyFairing {
|
|
|
|
/// fn info(&self) -> Info {
|
|
|
|
/// Info {
|
|
|
|
/// name: "My Custom Fairing",
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// kind: Kind::Ignite | Kind::Response
|
2017-05-15 04:46:01 +00:00
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
fn info(&self) -> Info;
|
2017-04-20 20:43:01 +00:00
|
|
|
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// The ignite callback. Returns `Ok` if ignition should proceed and `Err`
|
|
|
|
/// if ignition and launch should be aborted.
|
2017-05-15 04:46:01 +00:00
|
|
|
///
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
/// This method is called during ignition and if `Kind::Ignite` 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)`.
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
async fn on_ignite(&self, rocket: Rocket<Build>) -> Result { 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.
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
async fn on_liftoff(&self, _rocket: &Rocket<Orbit>) { }
|
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.
|
2021-06-08 09:13:02 +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]
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
async fn on_ignite(&self, rocket: Rocket<Build>) -> Result {
|
|
|
|
(self as &T).on_ignite(rocket).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
Introduce statically-enforced 'Rocket' phasing.
The core 'Rocket' type is parameterized: 'Rocket<P: Phase>', where
'Phase' is a newly introduced, sealed marker trait. The trait is
implemented by three new marker types representing the three launch
phases: 'Build', 'Ignite', and 'Orbit'. Progression through these three
phases, in order, is enforced, as are the invariants guaranteed by each
phase. In particular, an instance of 'Rocket' is guaranteed to be in its
final configuration after the 'Build' phase and represent a running
local or public server in the 'Orbit' phase. The 'Ignite' phase serves
as an intermediate, enabling inspection of a finalized but stationary
instance. Transition between phases validates the invariants required
by the transition.
All APIs have been adjusted appropriately, requiring either an instance
of 'Rocket' in a particular phase ('Rocket<Build>', 'Rocket<Ignite>', or
'Rocket<Orbit>') or operating generically on a 'Rocket<P>'.
Documentation is also updated and substantially improved to mention
required and guaranteed invariants.
Additionally, this commit makes the following relevant changes:
* 'Rocket::ignite()' is now a public interface.
* 'Rocket::{build,custom}' methods can no longer panic.
* 'Launch' fairings are now 'ignite' fairings.
* 'Liftoff' fairings are always run, even in local mode.
* All 'ignite' fairings run concurrently at ignition.
* Launch logging occurs on launch, not any point prior.
* Launch log messages have improved formatting.
* A new launch error kind, 'Config', was added.
* A 'fairing::Result' type alias was introduced.
* 'Shutdown::shutdown()' is now 'Shutdown::notify()'.
Some internal changes were also introduced:
* Fairing 'Info' name for 'Templates' is now 'Templating'.
* Shutdown is implemented using 'tokio::sync::Notify'.
* 'Client::debug()' is used nearly universally in tests.
Resolves #1154.
Resolves #1136.
2021-04-14 02:26:45 +00:00
|
|
|
async fn on_liftoff(&self, rocket: &Rocket<Orbit>) {
|
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_liftoff(rocket).await
|
2017-07-07 03:48:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2021-06-08 09:13:02 +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
|
|
|
}
|
|
|
|
}
|