This follows the completed graduation of stable contrib features into
core, removing 'rocket_contrib' in its entirety in favor of two new
crates. These crates are versioned independently of Rocket's core
libraries, allowing upgrades to dependencies without consideration for
versions in core libraries.
'rocket_dyn_templates' replaces the contrib 'templates' features. While
largely a 1-to-1 copy, it makes the following changes:
* the 'tera_templates' feature is now 'tera'
* the 'handlebars_templates' feature is now 'handlebars'
* fails to compile if neither 'tera' nor 'handlebars' is enabled
'rocket_sync_db_pools' replaces the contrib 'database' features. It
makes no changes to the replaced features except that the `database`
attribute is properly documented at the crate root.
This has the following nice benefits:
* The 'Uuid' wrapper type is gone.
* 'Uuid' implements 'UriDisplay', 'FromUriParam'.
* The 'serialization' example merges in 'uuid'.
Resolves#1299.
The 'SpaceHelmet' fairing is now called 'Shield'. It features the
following changes and improvements:
* Headers which are now ignored by browsers are removed.
* 'XssFilter' is no longer an on-by-default policy.
* A new 'Permission' policy is introduced.
* 'Shield' is attached to all 'Rocket' instances by default.
* Default headers never allocate on 'Clone'.
* Policy headers are rendered once and cached at start-up.
* Improved use of typed URIs in policy types.
This has the following nice benefits:
* The 'JsonValue' wrapper type is gone.
* 'Local{Request, Response}' natively support JSON/MessagePack.
* The 'json' and 'msgpack' limits are officially recognized.
* Soon, Rocket application will not require an explicit 'serde' dep.
This marks the beginning of the end of 'rocket_contrib'.
This commit entirely rewrites Rocket's URI parsing routines and
overhauls the 'uri!' macro resolving all known issues and removing any
potential limitations for compile-time URI creation. This commit:
* Introduces a new 'Reference' URI variant for URI-references.
* Modifies 'Redirect' to accept 'TryFrom<Reference>'.
* Introduces a new 'Asterisk' URI variant for parity.
* Allows creation of any URI type from a string literal via 'uri!'.
* Enables dynamic/static prefixing/suffixing of route URIs in 'uri!'.
* Unifies 'Segments' and 'QuerySegments' into one generic 'Segments'.
* Consolidates URI formatting types/traits into a 'uri::fmt' module.
* Makes APIs more symmetric across URI types.
It also includes the following less-relevant changes:
* Implements 'FromParam' for a single-segment 'PathBuf'.
* Adds 'FileName::is_safe()'.
* No longer reparses upstream request URIs.
Resolves#842.
Resolves#853.
Resolves#998.
This includes one breaking change: the default Content-Type of templates
without an identifying extension is now 'Text'. This is to prevent Tera
templates from rendering as HTML without being escaped.
Resolves#1637.
This has the following positive effects:
1) The lifetime retrieved through 'Deref' is now long-lived.
2) An '&State<T>` can be created via an '&T'.
3) '&State<T>' is shorter to type than 'State<'_, T>'.
One situation where this is noticeable is when initialization failure
leads to `Drop`; unlike in a successful initialization, `postgres`
detects and panics when `Drop` is called from within asynchronous code.
Several other database pools do not panic in this same situation, but
would still block the current thread.
Also sets the minimum version of `tokio` to 1.4 in `rocket_contrib`,
which is the version where `Handle::block_on` (used in `Drop` impls) was
introduced.
Fixes#1610.
This commit includes changes that improve how and what Rocket logs
automatically. Rocket now logs:
* All guard errors, indicating the failing guard kind and type.
* A warning when a 'TempFile' is used as a data guard for a request
that specifies a 'form' Content-Type.
* Only the top/sub of a request's format.
This commit makes the following breaking changes:
* '<T as FromData>::Error' must implement 'Debug'.
Furthermore, this commit restores the previous behavior of always
logging launch info. It further restores the unspecified behavior of
modifying logging state only when the set logger is Rocket's logger.
Sentinels resolve a long-standing usability and functional correctness
issue in Rocket: starting an application with guards and/or responders
that depend on state that isn't available. The canonical example is the
'State' guard. Prior to this commit, an application with routes that
queried unmanaged state via 'State' would fail at runtime. With this
commit, the application refuses to launch with a detailed error message.
The 'Sentinel' docs explains it as:
A sentinel, automatically run on ignition, can trigger a launch
abort should an instance fail to meet arbitrary conditions. Every
type that appears in a mounted route's type signature is eligible to
be a sentinel. Of these, those that implement 'Sentinel' have their
'abort()' method invoked automatically, immediately after ignition,
once for each unique type. Sentinels inspect the finalized instance
of 'Rocket' and can trigger a launch abort by returning 'true'.
The following types are now sentinels:
* 'contrib::databases::Connection' (any '#[database]' type)
* 'contrib::templates::Metadata'
* 'contrib::templates::Template'
* 'core::State'
The following are "specialized" sentinels, which allow sentinel
discovery even through type aliases:
* 'Option<T>', 'Debug<T>' if 'T: Sentinel'
* 'Result<T, E>', 'Either<T, E>' if 'T: Sentinel', 'E: Sentinel'
Closes#464.
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.
...because loading up a Rocket while it's ignited is a bad idea.
More seriously, because 'Rocket.ignite()' will become an "execute
everything up to here" method.
The options set WAL, a 1s busy timeout, and enables foreign keys.
This also adds a focused 'databases::Config::figment()', used to
retrieve a focused figment for a given config.
In particular, 'FromFormField' and 'UriDisplayQuery' now allow any
number of form 'field' attributes. For the former, multiple 'value's are
allowed, all of which are used to match against incoming fields - any
match wins. For the latter, multiple 'name' and 'value's are allowed;
the first of each is used to render the query value.
Additionally, 'UriDisplayQuery' can now be derived for C-like enums.
This brings the derive to parity with 'FromFormValue' and allows their
unified application on C-like enums.
Resolves#843.
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.
While offering some utility, the lifetime did not carry its weight, and
in practice offered no further ability to borrow. This greatly
simplifies request guard implementations.
Previously, an `rx` lock was held for the entirety of the check period,
effectively making request handling serial. The implementation also held
a `write` lock to templating context while an expensive user-callback
was called, limiting template-related concurrency during that period.
This was changed so no lock is held during that period and a write-lock
is held only for the duration of the context field write.
Prior to this commit, it was not possible to test Rocket crates in
production mode without setting a global secret key or bypassing secret
key checking - the testing script did the latter. The consequence is
that it became impossible to test secret key related failures because
the tests passed regardless.
This commit undoes this. As a consequence, all tests are now aware of
the difference between debug and release configurations, the latter of
which validates 'secret_key' by default. New 'Client::debug()' and
'Client::debug_with()' simplify creating an instance of 'Client' with
configuration in debug mode to avoid undesired test failures.
The summary of changes in this commit are:
* Config 'secret_key' success and failure are now tested.
* 'secret_key' validation was moved to pre-launch from 'Config:from()'.
* 'Config::from()' only extracts the config.
* Added 'Config::try_from()' for non-panicking extraction.
* 'Config' now knows the profile it was extracted from.
* The 'Config' provider sets a profile of 'Config.profile'.
* 'Rocket', 'Client', 'Fairings', implement 'Debug'.
* 'fairing::Info' implements 'Copy', 'Clone'.
* 'Fairings' keeps track of, logs attach fairings.
* 'Rocket::reconfigure()' was added to allow modifying a config.
Internally, the testing script was refactored to properly test the
codebase with the new changes. In particular, it no longer sets a rustc
'cfg' to avoid secret-key checking.
Resolves#1543.
Fixes#1564.
This changes core routing so that '<path..>' in a route URI matches zero
or more segments. Previously, '<path..>' matched _1_ or more.
* Routes '$a' and '$b/<p..>' collide if $a and $b previously collided.
* For example, '/' now collides with '/<p..>'.
* Request '$a' matches route '$b/<p..>' if $a previously matched $b.
* For example, request '/' matches route '/<p..>'.
Resolves#985.