The primary aim of this commit is to reduce confusion between
'content::Json' and 'rocket::serde::json::Json' be renaming the former
to 'content::RawJson'. The complete changes in this PR are:
* All responders in the 'content' module are prefixed with 'Raw'.
* The 'content::Custom' responder was removed entirely.
* The 'Plain' responder is now 'RawText'.
* The 'content' API docs point to the 'serde' responders.
* The docs and examples were updated accordingly.
Previously, TLS, via 'Config::tls', was configurable even if the 'tls'
feature was disabled. This commit changes this so that the 'Config::tls'
field and TLS config structures are only available if 'tls' is enabled.
Instead of a constructor, 'MediaType::with_params()' and
'ContentType::with_params()' are now both builder methods. This allow
chaining the method to associated constants.
As 'FromForm' doesn't provide access to the raw, undecoded string,
'MsgPack' cannot implement 'FromForm::from_value()'. This means that it
is not presently possible to parse a MessagePack form from a query
string. As such, the 'UriDisplay<Query>' implementation was removed.
The 'UriDisplay<Query>' for JSON was fixed such that a round-trip of a
'Json<T>' as a form works as expected.
The 'FromFrom' derive now allows type generics in all positions using
the same automatic discovery technique as with 'Responder'. (In fact,
the technique was created for this derive.) Furthermore, 'FromForm' can
now be derived for unit structs.
Also adds a new 'try_with' form field validator.
Resolves#1695.
This commit presents and applies a new technique for bounding type
generics in derives. In short, for a generic `T` used in a field type of
`Field<T>`, where an eventual bound of `Responder` required, the derive
generates a bound of `Field<T>: Responder`. This removes the need for
any manually provided bounds while simultaneously allowing more
structures to typecheck. For example, generics in header components are
now fully supported.
The 'Json' type now implements:
* Clone
* PartialEq
* Eq
* PartialOrd
* Ord
* Hash
* UriDisplay<Query>
Method calls that resolve to a method in the set of traits above
previously resolved to the `Deref` target. For example, `foo.clone()`,
where `foo: Json<T>`, previously resolved to `<T as Clone>::clone()` but
now resolves to `<Json<T> as Clone>::clone()`.
'Missing' allows constructing a 'FileServer' even if the supplied path
does not exist. 'IndexFile' allows serving a single file as the index of
the mount path.
The syntax 'TypedStream![T + '_]' expands to:
impl TypedStream<Item = T> + '_
This allows seamlessly borrowing in typed streams.
Also adds 'Event::empty()', for convenience.
The improvements are:
* Point directly and immediately to the 'Responder' derive.
* Provide more discussion on lifetimes.
* Format documentation for easier scanning.
Previously, recursion into rewriting 'self' in field validations would
cease after the first function call. This meant that internal uses of
'self' were not properly rewritten. This commit ameliorates the
situation.
This allows responses to be sent to the client even when data is only
partially read, significantly improving the experience for the client
from one with a "connection closed" error to one with a proper response.
The consequence is a lifetime in 'Data'.
Though other non-lifetime-introducing solutions exist, the introduction
of a lifetime to 'Data' is a longstanding desire as it prevents
smuggling 'Data' into a longer-lived context. Use of 'Data' in that
context was unspecified with various runtime consequences. The addition
of a lifetime bound by the request prevents this error statically.
In summary, the changes are:
* Clients receive responses even when data isn't fully read.
* 'Data' becomes 'Data<'r>'. 'FromData' changes accordingly.
* Route 'Outcome's are strictly tied to the request lifetime.
Tangentially, the invalid length form field validation error message has
improved to format length in byte units if it exceeds 1024.
If stars aligned properly, we might imagine writing this:
#[non_exhaustive]
struct Config {
pub field: Foo,
pub other: Bar,
}
...with semantics that would allow the defining crate (here, Rocket), to
construct the structure directly while consumers would need to use
public constructors or struct update syntax:
Config {
field: Foo,
other: Bar,
..Default::default()
}
Alas, this is not the way `non_exhaustive` works on structs. You cannot
use field-update syntax to construct `Config` above. You must use public
constructors. This means builder methods or mutating an already built
struct. This is not what we want.
I don't know why it works this way. I don't see why it must. Something
something Drop.
So we have this hack from the pre-non_exhaustive era.
This resolves syntax ambiguity issues with public typed-stream macros.
Prior to this commit, greedy single-token matching by macro-rules macros
would result in certain tokens at the beginning of the macro input, such
as 'for', inadvertently triggering a '$ty' matching case resulting in
incorrect expansion.
This commit makes the following improvements to core request handling:
* Absolute target URIs are not rejected. Instead, the path and query
parts are passed through the application. This resolves an issue
where certain HTTP/2 requests would be rejected by Rocket.
* Data is never copied from the request. Previously, Rocket would copy
and allocate for incoming headers.
* Non-UTF-8 headers are dropped with a warning instead of being
lossily, and thus perhaps incorrectly, decoded as UTF-8. The final
fix is to properly support non-UTF-8 headers, no matter how in the
minority they are.
Resolves#1498.
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.
This surfaced a dormant concurrency related issue. Prior to this commit,
the router used `routed_segments()` to retrieve the path segments of the
request. This was okay as there was no route in the request, and matched
segments were retrieved eagerly.
This commit makes segment matching lazy, so no matching occurs if
unnecessary. Between two matches, a `route` is atomically set of
`Request`. This is now visible in `routed_segments()`, which should not
have considered the current route in the first place. This was fixed.
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.
This prevents printing a secret key warning if a secret key was
generated, as is done by Rocket itself. This does not change any
behaviors in non-debug profiles.
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 commit makes the `Config.secret_key` conditionally compile on the
`secrets` feature. The net effect is simplified internal code, fewer
corner-cases, and easier to write tests.
This commit removes the `Provider::profile()` implementation of
`Config`. This means that the `Config` provider no longer sets a
profile, a likely confusing behavior. The `Config::figment()` continues
to function as before.
This changes core routing so that panics in all handlers are handled by
emitting a long message explaining that panics are bad and invoking the
500 error catcher. If the 500 error catcher fails, Rocket's default 500
catcher is used.
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.
The iterator may be empty. This changes the return type of
'Request::segments()' from 'Option<Segments>' to simply 'Segments'.
Internally also adds a 'Client::debug()' for easier request testing.
* Add a `msg!()` macro to easily change a field validation message.
* Allow a field to refer to itself via `self.field`.
* Improve the various field validation traits.