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 changes 'TempFile' doctests so that different file names are used
across them, avoiding race conditions where one test deletes a file
another test just created and thus expects to subsequently exist.
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.
A singleton fairing is guaranteed to be the only instance of its type at
launch time. If more than one instance of a singleton fairing is
attached, only the last instance is retained.
Previously, if a panic occurred with an 'Error' on the stack, 'Error'
would panic as usual during unwinding. This resulted in a double panic.
This commit makes 'Error' detect if a panic is already occurring and
omits its own panic if it is.
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 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>'.
The crux of the implementation is as follows:
* Configurable ctrl-c, signals that trigger a graceful shutdown.
* Configurable grace period before forced I/O termination.
* Programatic triggering via an application-wide method.
* A future (`Shutdown`) that resolves only when shutdown is requested.
Resolves#180.
This is a breaking change for many consumers of the 'Response' and all
consumers of the 'Body' API. The summary of breaking changes is:
* 'Response::body()', 'Response::body_mut()' are infallible.
* A 'Body' can represent an empty body in more cases.
* 'ResponseBuilder' is now simply 'Builder'.
* Direct body read methods on 'Response' were removed in favor of
chaining through 'body_mut()': 'r.body_mut().to_string()'.
* Notion of a 'chunked_body' was removed as it was inaccurate.
* Maximum chunk size can be set on any body.
* 'Response' no longer implements 'Responder'.
A few bugs were fixed in the process. Specifically, 'Body' will emit an
accurate size even for bodies that are partially read, and the size of
seek-determined bodies is emitted on HEAD request where it wasn't
before. Specifics on transport were clarified, and 'Body' docs greatly
improved as a result.
This removes the export of each of these macros from the root, limiting
their export-scope to their respective module. This is accomplished
using a new internal macro, 'export!', which does some "magic" to work
around rustdoc deficiencies.
Changes codegen to use an instance method on the route proxy struct
rather than implementing a trait on the proxy struct. This helps rustc
identify unused routes.
Resolves#1598.
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 new examples directory...
* Contains a `README.md` explaining each example.
* Consolidates examples into more complete chunks.
* Is just better.
Resolves#1447.
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.
This is now consistent with the serialization of 'Flash' and better
illustrates the purpose of the late 'name' property.
Additionally, take 'Into<String>' instead of 'AsRef<str>' so we only
allocate when necessary.
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.
Catchers can now be scoped to paths, with preference given to the
longest-prefix, then the status code. This a breaking change for all
applications that register catchers:
* `Rocket::register()` takes a base path to scope catchers under.
- The previous behavior is recovered with `::register("/", ...)`.
* Catchers now fallibly, instead of silently, collide.
* `ErrorKind::Collision` is now `ErrorKind::Collisions`.
Related changes:
* `Origin` implements `TryFrom<String>`, `TryFrom<&str>`.
* All URI variants implement `TryFrom<Uri>`.
* Added `Segments::prefix_of()`.
* `Rocket::mount()` takes a `TryInto<Origin<'_>>` instead of `&str`
for the base mount point.
* Extended `errors` example with scoped catchers.
* Added scoped sections to catchers guide.
Internal changes:
* Moved router code to `router/router.rs`.
The new benchmarks use routes from real-world project. This is much more
realistic than the previous benchmarks.
The new benchmarks use `criterion` and exist in their own Cargo project.