2018-12-08 18:29:43 +00:00
|
|
|
# Rocket v0.4: Typed URIs, Database Support, Revamped Queries, & More!
|
2018-12-08 16:45:06 +00:00
|
|
|
|
|
|
|
<p class="metadata"><strong>
|
|
|
|
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on December 08, 2018
|
|
|
|
</strong></p>
|
|
|
|
|
|
|
|
I am elated to announce that the next major release of Rocket is now available!
|
|
|
|
Rocket 0.4 is a step forward in every direction: it is **packed** with features
|
|
|
|
and improvements that increase developer productivity, improve application
|
|
|
|
security and robustness, provide new opportunities for extensibility, and
|
|
|
|
deliver a renewed degree of toolchain stability.
|
|
|
|
|
|
|
|
Rocket 0.4 is the culmination of more than a year of development. During this
|
|
|
|
time, more than 600 changes were committed, almost 400 issues were closed, and
|
|
|
|
over 165 pull requests were submitted. The Rocket community has proved steadfast
|
|
|
|
in its support: a sincere thank you to everyone involved!
|
|
|
|
|
|
|
|
## About Rocket
|
|
|
|
|
|
|
|
Rocket is a web framework for Rust with a focus on usability, security, and
|
|
|
|
performance. Rocket makes it simple to write fast, secure web applications
|
|
|
|
without sacrificing flexibility or type safety.
|
|
|
|
|
|
|
|
Not already using Rocket? Join the tens of thousands of users and hundreds of
|
|
|
|
companies happily using Rocket today! Rocket's extensive documentation makes it
|
|
|
|
easy. Get started now by [reading through the guide](../../guide) or learning
|
|
|
|
more from [the overview](../../overview).
|
|
|
|
|
|
|
|
## What's New?
|
|
|
|
|
|
|
|
Rocket 0.4 is the largest release to date by a _wide_ margin. It is packed with
|
|
|
|
hundreds of changes. We highlight the largest of them here. For a complete
|
|
|
|
description of everything new and different in 0.4, please see the [CHANGELOG].
|
|
|
|
|
|
|
|
[CHANGELOG]: https://github.com/SergioBenitez/Rocket/blob/v0.4.0/CHANGELOG.md#version-040-dec-06-2018
|
|
|
|
|
|
|
|
### Maintainers += 1
|
|
|
|
|
|
|
|
An open source project is as much about the people as it is about the code. This
|
|
|
|
is why I am delighted to welcome [@jebrosen] as Rocket's first co-maintainer!
|
|
|
|
Jeb is directly responsible for several of the new features in 0.4, has
|
|
|
|
painstakingly code reviewed many other changes, and actively answers questions
|
|
|
|
and resolves issues on GitHub, IRC, and offline.
|
|
|
|
|
|
|
|
Needless to say, Rocket is a better project thanks to you, Jeb. Welcome!
|
|
|
|
|
|
|
|
[@jebrosen]: https://github.com/jebrosen
|
|
|
|
|
|
|
|
### Codegen Rewrite
|
|
|
|
|
|
|
|
In 0.4, the [`rocket_codegen`] crate has been entirely rewritten to use
|
|
|
|
to-be-stable procedural macro APIs where it previously used private, unstable
|
|
|
|
`rustc` APIs. While this is largely an internal change, it has big, positive
|
|
|
|
implications for all Rocket users.
|
|
|
|
|
|
|
|
First and foremost, the path to Rocket on stable is now clearly in sight. While
|
|
|
|
there are still hurdles to overcome, we are actively working with the Rust team
|
|
|
|
to make Rocket on stable a reality as soon as possible. We expect the next major
|
|
|
|
Rocket release to support the stable channel.
|
|
|
|
|
|
|
|
Second, but equally important, we expect breakages due to nightly changes to
|
|
|
|
drop dramatically, likely to zero. This means that Rocket is largely already
|
|
|
|
_de-facto_ toolchain stable.
|
|
|
|
|
|
|
|
The new prelude import for Rocket applications is:
|
|
|
|
|
|
|
|
```diff
|
|
|
|
- #![feature(plugin)]
|
|
|
|
- #![plugin(rocket_codegen)]
|
|
|
|
+ #![feature(proc_macro_hygiene, decl_macro)]
|
|
|
|
|
|
|
|
- extern crate rocket;
|
|
|
|
+ #[macro_use] extern crate rocket;
|
|
|
|
```
|
|
|
|
|
|
|
|
[`rocket_codegen`] should **_not_** be a direct dependency. Remove it from your
|
|
|
|
`Cargo.toml`:
|
|
|
|
|
|
|
|
```diff
|
|
|
|
[dependencies]
|
|
|
|
- rocket = "0.3"
|
|
|
|
+ rocket = "0.4"
|
|
|
|
- rocket_codegen = "0.3"
|
|
|
|
```
|
|
|
|
|
|
|
|
[`rocket_codegen`]: https://api.rocket.rs/v0.4/rocket_codegen/index.html
|
|
|
|
|
|
|
|
### Typed URIs
|
|
|
|
|
|
|
|
Rocket 0.4 introduces the [`uri!`] macro, allowing you to construct URIs to
|
|
|
|
routes in a robust, type-safe, and URI-safe manner. Type or route parameter
|
|
|
|
mismatches are caught at compile-time, and changes to route URIs are
|
|
|
|
automatically reflected in the generated URIs.
|
|
|
|
|
|
|
|
To illustrate, consider the following route:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
#[get("/person/<name>?<age>")]
|
|
|
|
fn person(name: String, age: Option<u8>)
|
|
|
|
```
|
|
|
|
|
|
|
|
URIs to this `person` route can be created as follows:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
// with unnamed parameters, in route URI declaration order
|
|
|
|
let uri = uri!(person: "Mike Smith", 28);
|
|
|
|
assert_eq!(uri.to_string(), "/person/Mike%20Smith?age=28");
|
|
|
|
|
|
|
|
// with named parameters, order irrelevant
|
|
|
|
let uri = uri!(person: name = "Mike", age = 28);
|
|
|
|
let uri = uri!(person: age = 28, name = "Mike");
|
|
|
|
assert_eq!(uri.to_string(), "/person/Mike?age=28");
|
|
|
|
|
|
|
|
// with a specific mount-point
|
|
|
|
let uri = uri!("/api", person: name = "Mike", age = 28);
|
|
|
|
assert_eq!(uri.to_string(), "/api/person/Mike?age=28");
|
|
|
|
|
|
|
|
// with optional query parameters ignored
|
|
|
|
let uri = uri!(person: "Mike", _);
|
|
|
|
let uri = uri!(person: name = "Mike", age = _);
|
|
|
|
assert_eq!(uri.to_string(), "/person/Mike");
|
|
|
|
```
|
|
|
|
|
|
|
|
Should your route's URI change in an incompatible manner, or should you mistype
|
|
|
|
parameters, Rocket informs you of the error at compile-time with a helpful
|
|
|
|
message:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
error: person route uri expects 2 parameters but 1 was supplied
|
|
|
|
--> examples/uri/src/main.rs:9:29
|
|
|
|
|
|
|
|
|
9 | uri!(person: "Mike Smith");
|
|
|
|
| ^^^^^^^^^^^^
|
|
|
|
|
|
|
|
|
= note: expected parameters: name: String, age: Option<u8>
|
|
|
|
```
|
|
|
|
|
|
|
|
The same applies to type errors: Rocket informs you of any type errors at
|
|
|
|
compile-time as well:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
error: the trait bound u8: FromUriParam<Query, &str> is not satisfied
|
|
|
|
--> examples/uri/src/main.rs:9:35
|
|
|
|
|
|
|
|
|
9 | uri!(person: age = "10", name = "Mike");
|
|
|
|
| ^^^^ FromUriParam<Query, &str> is not implemented for u8
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
We recommend that `uri!` is exclusively used when constructing route URIs. For
|
|
|
|
more information on typed URIs, see the new [Typed URIs] guide section and the
|
|
|
|
[`uri!`] macro documentation.
|
|
|
|
|
|
|
|
[`uri!`]: @api/rocket_codegen/macro.uri.html
|
|
|
|
[Typed URIs]: ../../guide/responses/#typed-uris
|
|
|
|
|
|
|
|
### Database Support
|
|
|
|
|
|
|
|
Rocket now includes built-in, ORM-agnostic support for database connection
|
|
|
|
pooling. More specifically, Rocket allows you to easily configure and connect
|
|
|
|
your Rocket application to databases through connection pools in three simple,
|
|
|
|
largely automated steps:
|
|
|
|
|
|
|
|
1. Configure databases in `Rocket.toml`.
|
|
|
|
2. Associate a request guard type and fairing with each database.
|
|
|
|
3. Use the request guard to retrieve a connection in a handler.
|
|
|
|
|
|
|
|
As an example, for a Diesel-based SQLite database named `sqlite_logs`, your
|
|
|
|
`Rocket.toml` would record the URL to the database in the `databases` table:
|
|
|
|
|
|
|
|
```toml
|
|
|
|
[global.databases]
|
|
|
|
sqlite_logs = { url = "/path/to/database.sqlite" }
|
|
|
|
```
|
|
|
|
|
|
|
|
In the application, a unit-like `struct` with one internal type (the database
|
|
|
|
connection) is decorated with the `#[database]` attribute and the name of the
|
|
|
|
configured database. This generates a fairing which must then be attached:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
#[database("sqlite_logs")]
|
|
|
|
struct LogsDbConn(diesel::SqliteConnection);
|
|
|
|
|
|
|
|
rocket::ignite().attach(LogsDbConn::fairing())
|
|
|
|
```
|
|
|
|
|
|
|
|
That's it! Whenever a connection to the database is needed, the type can be used
|
|
|
|
as a request guard:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
#[get("/logs/<id>")]
|
|
|
|
fn get_logs(conn: LogsDbConn, id: usize) -> Result<Logs> {
|
|
|
|
logs::filter(id.eq(log_id)).load(&conn)
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
For more information on Rocket's database support, see the new [Database] guide
|
|
|
|
section and the [`rocket_contrib::databases`] module documentation.
|
|
|
|
|
|
|
|
[Database]: ../../guide/state/#databases
|
|
|
|
[`rocket_contrib::databases`]: @api/rocket_contrib/databases/index.html
|
|
|
|
|
2018-12-08 18:29:43 +00:00
|
|
|
### Revamped Queries
|
2018-12-08 16:45:06 +00:00
|
|
|
|
|
|
|
In Rocket 0.4, query string handling has been completely overhauled, resolving
|
|
|
|
some of the most called for requests in Rocket's history ([#608]). The new query
|
|
|
|
handling route syntax and semantics were designed with the following goals in
|
|
|
|
mind:
|
|
|
|
|
|
|
|
* Enable matching of static query components.
|
|
|
|
* No special-casing of any kind, preferring type-driven flows.
|
|
|
|
* Ad-hoc matching of specific query key/value pairs.
|
|
|
|
* Lenient parsing by default, allowing missing parameters.
|
|
|
|
* Order-independent matching of query parameters.
|
|
|
|
|
|
|
|
To illustrate the new system in action, consider the following route:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
#[derive(FromForm)]
|
|
|
|
struct DogDetails {
|
|
|
|
color: Color,
|
|
|
|
height: Inches,
|
|
|
|
weight: Pounds
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/animal?dog&<name>&<nickname>&<rest..>")]
|
|
|
|
fn dog(name: String, nickname: Option<String>, rest: Form<DogDetails>)
|
|
|
|
```
|
|
|
|
|
|
|
|
This route matches any `GET` request with a path of `/animal`, a static query
|
|
|
|
component of `dog`, and key/value parameters of `color`, `height`, and `weight`
|
|
|
|
that validate as `Color`, `Inches`, and `Pounds`, respectively. Furthermore, it
|
|
|
|
optionally accepts a key/value parameter of `nickname`. If the value is present,
|
|
|
|
`nickname` will be `Some`; if it is not, `nickname` will be `None`.
|
|
|
|
|
|
|
|
Single parameters (`<param>`) like `name` and `nickname` are validated using the
|
|
|
|
existing [`FromFormValue`] trait while trailing parameters (`<param..>`) are
|
|
|
|
validated using the new [`FromQuery`] trait. Both traits are user implementable,
|
2018-12-08 18:29:43 +00:00
|
|
|
and [`FromFormValue`] can be derived.
|
2018-12-08 16:45:06 +00:00
|
|
|
|
|
|
|
For more details on handling query strings, see the new [Query Strings] guide
|
|
|
|
section and the updated [`route` attribute] documentation.
|
|
|
|
|
|
|
|
[`FromFormValue`]: @api/rocket/request/trait.FromFormValue.html
|
|
|
|
[`FromQuery`]: @api/rocket/request/trait.FromQuery.html
|
|
|
|
[`route` attribute]: @api/rocket_codegen/attr.get.html
|
|
|
|
[Query Strings]: ../../guide/requests/#query-strings
|
|
|
|
[#608]: https://github.com/SergioBenitez/Rocket/issues/608
|
|
|
|
|
|
|
|
### Stateful Handlers
|
|
|
|
|
|
|
|
The type of a handler has been generalized in 0.4 to any type that implements
|
|
|
|
the new [`Handler`] trait. Among other things, this allows handlers to refer to
|
|
|
|
internal state during request handling.
|
|
|
|
|
|
|
|
The new [`StaticFiles`] `contrib` type uses this functionality to provide
|
|
|
|
easier-than-ever static file serving. For example, to make local files from a
|
|
|
|
`/static` directory accessible at `/public`, you need simply write:
|
|
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
fn main() {
|
|
|
|
rocket::ignite()
|
|
|
|
.mount("/public", StaticFiles::from("/static"))
|
|
|
|
.launch();
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
We encourage users to explore the new `Handler` API and contribute libraries
|
|
|
|
with pluggable handlers! For more details, see the [`Handler`] documentation.
|
|
|
|
|
|
|
|
[`Handler`]: @api/rocket/trait.Handler.html
|
|
|
|
[`StaticFiles`]: @api/rocket_contrib/serve/struct.StaticFiles.html
|
|
|
|
|
|
|
|
### Responder Derive
|
|
|
|
|
|
|
|
In Rocket 0.4, the [`Responder`] trait can be derived for `enum`s and `struct`s
|
|
|
|
with named fields. This greatly simplifies returning multiple types of responses
|
|
|
|
from a single handler.
|
|
|
|
|
|
|
|
To illustrate, consider a route that returns either a `Json<Info>` structure for
|
|
|
|
401 (unauthorized) errors or a `NamedFile` with a dynamic Content-Type for 404
|
|
|
|
(not found) errors. To accomplish this previously, `Result` values could be
|
|
|
|
arbitrarily nested, an unappealing and semantically incorrect approach.
|
|
|
|
Alternatively, an `enum` could be declared with the appropriate variants, and
|
|
|
|
`Responder` could be manually implemented for the `enum`. As of 0.4, that
|
|
|
|
implementation can be automatically derived:
|
|
|
|
|
|
|
|
```rust
|
2018-12-12 08:04:48 +00:00
|
|
|
#[derive(Responder, Debug)]
|
2018-12-08 16:45:06 +00:00
|
|
|
enum Error {
|
2018-12-08 20:00:58 +00:00
|
|
|
#[response(status = 401)]
|
2018-12-08 16:45:06 +00:00
|
|
|
Unauthorized(Json<Info>),
|
|
|
|
#[response(status = 404)]
|
|
|
|
NotFound(NamedFile, ContentType),
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
A value of this type can then be returned from a hander or used as part of
|
|
|
|
wrapping responders:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
#[get("/<item>")]
|
|
|
|
fn handler(user: Option<User>, item: Option<Item>) -> Result<T, Error> {
|
|
|
|
if user.is_none() {
|
|
|
|
Err(Error::Unauthorized(..))
|
|
|
|
} else if item.is_none() {
|
|
|
|
Err(Error::NotFound(..))
|
|
|
|
} else {
|
|
|
|
Ok(..)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The status for each variant will be automatically set to the value of the
|
|
|
|
`status` variant attribute, and fields beyond the first will be added as
|
|
|
|
headers to the response (here, `ContentType`).
|
|
|
|
|
|
|
|
For more on using the `Responder` derive, see the new [Custom Responders] guide
|
|
|
|
section and the [`Responder` derive] documentation.
|
|
|
|
|
|
|
|
[Custom Responders]: ../../guide/responses/#custom-responders
|
|
|
|
[`Responder` derive]: @api/rocket_codegen/derive.Responder.html
|
|
|
|
[`Responder`]: @api/rocket/response/trait.Responder.html
|
|
|
|
|
|
|
|
### Live Template Reloading
|
|
|
|
|
|
|
|
Rocket 0.4 automatically reloads changed templates at runtime without requiring
|
|
|
|
recompilation. This works on all major platforms. For security and performance
|
|
|
|
reasons, live template reloading is only enabled when the application is
|
|
|
|
compiled in debug mode.
|
|
|
|
|
|
|
|
There is no configuration necessary: this _just works_ out of the box!
|
|
|
|
|
|
|
|
### And Plenty More!
|
|
|
|
|
2018-12-08 18:19:00 +00:00
|
|
|
In addition to the features highlighted above, Rocket 0.4 also contains the
|
2018-12-08 16:45:06 +00:00
|
|
|
following new features:
|
|
|
|
|
|
|
|
* Introduced [Request-Local State].
|
|
|
|
* Introduced [transforming] data guards via [`FromData::transform()`].
|
|
|
|
* Introduced the [`SpaceHelmet`] security and privacy headers fairing.
|
|
|
|
* Private cookies are gated behind a `private-cookies` default feature.
|
|
|
|
* Added [derive for `FromFormValue`].
|
|
|
|
* Added [`Template::custom()`] for customizing templating engines.
|
|
|
|
* Cookies are automatically tracked and propagated by [`Client`].
|
|
|
|
* Private cookies can be added to local requests with
|
|
|
|
[`LocalRequest::private_cookie()`].
|
|
|
|
* Release builds default to the `production` environment.
|
|
|
|
* Keep-alive can be configured via the `keep_alive` configuration parameter.
|
|
|
|
* Allow CLI colors and emoji to be disabled with `ROCKET_CLI_COLORS=off`.
|
|
|
|
* Route `format` accepts [shorthands] such as `json` and `html`.
|
|
|
|
* Implemented [`Responder` for `Status`].
|
|
|
|
* Added [`Response::cookies()`] for retrieving response cookies.
|
|
|
|
* All logging is disabled when `log` is set to `off`.
|
|
|
|
* Added [`Metadata`] guard for retrieving templating information.
|
|
|
|
* The [`Uri`] type parses according to RFC 7230 into one of [`Origin`],
|
|
|
|
[`Absolute`], or [`Authority`].
|
|
|
|
* Added [`Outcome::and_then()`], [`Outcome::failure_then()`], and
|
|
|
|
[`Outcome::forward_then()`].
|
|
|
|
* Implemented `Responder` for `&[u8]`.
|
|
|
|
* Any `T: Into<Vec<Route>>` can be [`mount()`]ed.
|
|
|
|
* Added [`Request::get_query_value()`] for retrieving a query value by key.
|
|
|
|
* Applications can launch without a working directory.
|
|
|
|
* Added [`State::from()`] for constructing `State` values.
|
|
|
|
|
|
|
|
[`SpaceHelmet`]: https://api.rocket.rs/v0.4/rocket_contrib/helmet/index.html
|
|
|
|
[`State::from()`]: https://api.rocket.rs/v0.4/rocket/struct.State.html#method.from
|
|
|
|
[Typed URIs]: https://rocket.rs/v0.4/guide/responses/#typed-uris
|
|
|
|
[ORM agnostic database support]: https://rocket.rs/v0.4/guide/state/#databases
|
|
|
|
[`Template::custom()`]: https://api.rocket.rs/v0.4/rocket_contrib/templates/struct.Template.html#method.custom
|
|
|
|
[`LocalRequest::private_cookie()`]: https://api.rocket.rs/v0.4/rocket/local/struct.LocalRequest.html#method.private_cookie
|
|
|
|
[`LocalRequest`]: https://api.rocket.rs/v0.4/rocket/local/struct.LocalRequest.html
|
|
|
|
[shorthands]: https://api.rocket.rs/v0.4/rocket/http/struct.ContentType.html#method.parse_flexible
|
|
|
|
[derive for `FromFormValue`]: https://api.rocket.rs/v0.4/rocket_codegen/derive.FromFormValue.html
|
|
|
|
[derive for `Responder`]: https://api.rocket.rs/v0.4/rocket_codegen/derive.Responder.html
|
|
|
|
[`Response::cookies()`]: https://api.rocket.rs/v0.4/rocket/struct.Response.html#method.cookies
|
|
|
|
[`Client`]: https://api.rocket.rs/v0.4/rocket/local/struct.Client.html
|
|
|
|
[Request-Local State]: https://rocket.rs/v0.4/guide/state/#request-local-state
|
|
|
|
[`Metadata`]: https://api.rocket.rs/v0.4/rocket_contrib/templates/struct.Metadata.html
|
|
|
|
[`Uri`]: https://api.rocket.rs/v0.4/rocket/http/uri/enum.Uri.html
|
|
|
|
[`Origin`]: https://api.rocket.rs/v0.4/rocket/http/uri/struct.Origin.html
|
|
|
|
[`Absolute`]: https://api.rocket.rs/v0.4/rocket/http/uri/struct.Absolute.html
|
|
|
|
[`Authority`]: https://api.rocket.rs/v0.4/rocket/http/uri/struct.Authority.html
|
|
|
|
[`Outcome::and_then()`]: https://api.rocket.rs/v0.4/rocket/enum.Outcome.html#method.and_then
|
|
|
|
[`Outcome::forward_then()`]: https://api.rocket.rs/v0.4/rocket/enum.Outcome.html#method.forward_then
|
|
|
|
[`Outcome::failure_then()`]: https://api.rocket.rs/v0.4/rocket/enum.Outcome.html#method.failure_then
|
|
|
|
[`StaticFiles`]: https://api.rocket.rs/v0.4/rocket_contrib/serve/struct.StaticFiles.html
|
|
|
|
[live template reloading]: https://rocket.rs/v0.4/guide/responses/#live-reloading
|
|
|
|
[`Handler`]: https://api.rocket.rs/v0.4/rocket/trait.Handler.html
|
|
|
|
[`mount()`]: https://api.rocket.rs/v0.4/rocket/struct.Rocket.html#method.mount
|
|
|
|
[`FromData::transform()`]: https://api.rocket.rs/v0.4/rocket/data/trait.FromData.html#tymethod.transform
|
|
|
|
[transforming]: https://api.rocket.rs/v0.4/rocket/data/trait.FromData.html#transforming
|
|
|
|
[query string handling]: https://rocket.rs/v0.4/guide/requests/#query-strings
|
|
|
|
[Default rankings]: https://rocket.rs/v0.4/guide/requests/#default-ranking
|
|
|
|
[`Request::get_query_value()`]: https://api.rocket.rs/v0.4/rocket/struct.Request.html#method.get_query_value
|
|
|
|
[`Responder` for `Status`]: https://rocket.rs/v0.4/guide/responses/#status
|
|
|
|
|
|
|
|
## Breaking Changes
|
|
|
|
|
|
|
|
This release includes many breaking changes. Please see the
|
|
|
|
[CHANGELOG](https://github.com/SergioBenitez/Rocket/blob/v0.3.0/CHANGELOG.md#breaking-changes)
|
|
|
|
for a complete list of breaking changes along with details on handling the
|
|
|
|
breaking change in existing applications.
|
|
|
|
|
|
|
|
Rocket 0.3 will continue as a security maintance release _only_. All users are
|
2018-12-08 18:19:00 +00:00
|
|
|
encouraged to migrate their applications to 0.4.
|
2018-12-08 16:45:06 +00:00
|
|
|
|
|
|
|
## General Improvements
|
|
|
|
|
|
|
|
In addition to new features, Rocket saw the following improvements:
|
|
|
|
|
|
|
|
* Log messages now refer to routes by name.
|
|
|
|
* Collision errors on launch name the colliding routes.
|
|
|
|
* Launch fairing failures refer to the failing fairing by name.
|
|
|
|
* The default `403` catcher now references authorization, not authentication.
|
|
|
|
* Private cookies are set to `HttpOnly` and are given an expiration date of 1
|
|
|
|
week by default.
|
|
|
|
* A [Tera templates example] was added.
|
|
|
|
* All macros, derives, and attributes are individually documented in
|
|
|
|
[`rocket_codegen`].
|
|
|
|
* Invalid client requests receive a response of `400` instead of `500`.
|
|
|
|
* Response bodies are reliably stripped on `HEAD` requests.
|
|
|
|
* Added a default catcher for `504: Gateway Timeout`.
|
|
|
|
* Configuration information is logged in all environments.
|
|
|
|
* Use of `unsafe` was reduced from 9 to 2 in core library.
|
|
|
|
* [`FormItems`] now parses empty keys and values as well as keys without
|
|
|
|
values.
|
|
|
|
* Added [`Config::active()`] as a shorthand for
|
|
|
|
`Config::new(Environment::active()?)`.
|
|
|
|
* Address/port binding errors at launch are detected and explicitly emitted.
|
|
|
|
* [`Flash`] cookies are cleared only after they are inspected.
|
|
|
|
* `Sync` bound on [`AdHoc::on_attach()`], [`AdHoc::on_launch()`] was removed.
|
|
|
|
* [`AdHoc::on_attach()`], [`AdHoc::on_launch()`] accept an `FnOnce`.
|
|
|
|
* Added [`Config::root_relative()`] for retrieving paths relative to the
|
|
|
|
configuration file.
|
|
|
|
* Added [`Config::tls_enabled()`] for determining whether TLS is actively
|
|
|
|
enabled.
|
|
|
|
* ASCII color codes are not emitted on versions of Windows that do not support
|
|
|
|
them.
|
|
|
|
* Added FLAC (`audio/flac`), Icon (`image/x-icon`), WEBA (`audio/webm`), TIFF
|
|
|
|
(`image/tiff`), AAC (`audio/aac`), Calendar (`text/calendar`), MPEG
|
|
|
|
(`video/mpeg`), TAR (`application/x-tar`), GZIP (`application/gzip`), MOV
|
|
|
|
(`video/quicktime`), MP4 (`video/mp4`), ZIP (`application/zip`) as known
|
|
|
|
media types.
|
|
|
|
* Added `.weba` (`WEBA`), `.ogv` (`OGG`), `.mp4` (`MP4`), `.mpeg4` (`MP4`),
|
|
|
|
`.aac` (`AAC`), `.ics` (`Calendar`), `.bin` (`Binary`), `.mpg` (`MPEG`),
|
|
|
|
`.mpeg` (`MPEG`), `.tar` (`TAR`), `.gz` (`GZIP`), `.tif` (`TIFF`), `.tiff`
|
|
|
|
(`TIFF`), `.mov` (`MOV`) as known extensions.
|
|
|
|
* Interaction between route attributes and declarative macros has been
|
|
|
|
improved.
|
|
|
|
* Generated code now logs through logging infrastructures as opposed to using
|
|
|
|
`println!`.
|
|
|
|
* Routing has been optimized by caching routing metadata.
|
|
|
|
* [`Form`] and [`LenientForm`] can be publicly constructed.
|
|
|
|
* Console coloring uses default terminal colors instead of white.
|
|
|
|
* Console coloring is consistent across all messages.
|
|
|
|
* `i128` and `u128` now implement [`FromParam`], [`FromFormValue`].
|
|
|
|
* The `base64` dependency was updated to `0.10`.
|
|
|
|
* The `log` dependency was updated to `0.4`.
|
|
|
|
* The `handlebars` dependency was updated to `1.0`.
|
|
|
|
* The `tera` dependency was updated to `0.11`.
|
|
|
|
* The `uuid` dependency was updated to `0.7`.
|
|
|
|
* The `rustls` dependency was updated to `0.14`.
|
|
|
|
* The `cookie` dependency was updated to `0.11`.
|
|
|
|
|
|
|
|
[Tera templates example]: @github/examples/tera_templates
|
|
|
|
[`FormItems`]: @api/rocket/request/enum.FormItems.html
|
|
|
|
[`Config::active()`]: @api/rocket/config/struct.Config.html#method.active
|
|
|
|
[`Flash`]: @api/rocket/response/struct.Flash.html
|
|
|
|
[`AdHoc::on_attach()`]: @api/rocket/fairing/struct.AdHoc.html#method.on_attach
|
|
|
|
[`AdHoc::on_launch()`]: @api/rocket/fairing/struct.AdHoc.html#method.on_launch
|
|
|
|
[`Config::root_relative()`]: @api/rocket/struct.Config.html#method.root_relative
|
|
|
|
[`Config::tls_enabled()`]: @api/rocket/struct.Config.html#method.tls_enabled
|
|
|
|
[`rocket_codegen`]: @api/rocket_codegen/index.html
|
|
|
|
[`FromParam`]: @api/rocket/request/trait.FromParam.html
|
|
|
|
[`FromFormValue`]: @api/rocket/request/trait.FromFormValue.html
|
|
|
|
[`Data`]: @api/rocket/struct.Data.html
|
|
|
|
[`Form`]: https://api.rocket.rs/v0.4/rocket/request/struct.Form.html
|
|
|
|
[`LenientForm`]: https://api.rocket.rs/v0.4/rocket/request/struct.LenientForm.html
|
|
|
|
|
|
|
|
## What's Next?
|
|
|
|
|
|
|
|
Rocket v0.5 is scheduled to be _at least_ as exciting as 0.4! As always, the
|
|
|
|
focus continues to be usability, stability, security, and performance. With this
|
|
|
|
in mind, the roadmap for 0.5 includes:
|
|
|
|
|
|
|
|
1. **Support for Rust Stable** ([#19])
|
|
|
|
|
|
|
|
Finally! Rocket 0.5 will compile and run on stable versions of the Rust
|
|
|
|
compiler.
|
|
|
|
|
2018-12-08 18:29:43 +00:00
|
|
|
2. **Asynchronous Request Handling** ([#17])
|
2018-12-08 16:45:06 +00:00
|
|
|
|
|
|
|
In 0.5, Rocket will migrate to the latest asynchronous version of `hyper` and
|
|
|
|
`futures` with compatibility for `async`/`await` syntax. Of utmost importance
|
|
|
|
is preserving Rocket's usability. As such, these changes will be largely
|
|
|
|
internal, with asynchronous I/O peeking over the covers _only_ when
|
|
|
|
explicitly desired or required. As a side effect, we expect a substantial
|
|
|
|
performance boost from the migration as well as resolution to long-standing
|
|
|
|
issues.
|
|
|
|
|
|
|
|
3. **Multipart Form Support** ([#106])
|
|
|
|
|
|
|
|
The lack of built-in multipart form support makes handling file uploads and
|
|
|
|
other submissions much more cumbersome than necessary. Rocket 0.5 will
|
|
|
|
generalize its existing forms infrastructure to handle multipart forms.
|
|
|
|
|
|
|
|
4. **Stronger CSRF and XSS Protection** ([#14])
|
|
|
|
|
|
|
|
Since 0.3, Rocket uses `SameSite: Strict` private cookies to prevent CSRF
|
|
|
|
attacks. This technique is only tenable in newer browsers. In 0.5, Rocket
|
|
|
|
will protect against CSRF using more robust techniques. Rocket will also add
|
|
|
|
support for automatic, browser-based XSS protection.
|
|
|
|
|
|
|
|
[#17]: https://github.com/SergioBenitez/Rocket/issues/17
|
|
|
|
[#19]: https://github.com/SergioBenitez/Rocket/issues/19
|
|
|
|
[#106]: https://github.com/SergioBenitez/Rocket/issues/106
|
|
|
|
[#14]: https://github.com/SergioBenitez/Rocket/issues/14
|
|
|
|
|
|
|
|
## Rocket v0.4 Contributors
|
|
|
|
|
|
|
|
The following wonderful people helped make Rocket 0.4 happen:
|
|
|
|
|
|
|
|
<ul class="columns">
|
|
|
|
<li>Alexander Mielczarek</li>
|
|
|
|
<li>Alex Bowers</li>
|
|
|
|
<li>Alfie John</li>
|
|
|
|
<li>Alva Snædís</li>
|
|
|
|
<li>Ashley Williams</li>
|
|
|
|
<li>Beatriz Rizental</li>
|
|
|
|
<li>bohov</li>
|
|
|
|
<li>Christophe Courtaut</li>
|
|
|
|
<li>David Darrell</li>
|
|
|
|
<li>Desmond</li>
|
|
|
|
<li>Divyahans Gupta</li>
|
|
|
|
<li>Donald Robertson</li>
|
|
|
|
<li>EloD10</li>
|
|
|
|
<li>Eric Dattore</li>
|
|
|
|
<li>Henning Kowalk</li>
|
|
|
|
<li>Imron Alston</li>
|
|
|
|
<li>Jeb Rosen</li>
|
|
|
|
<li>kryptan</li>
|
|
|
|
<li>Kyle Clemens</li>
|
|
|
|
<li>lerina</li>
|
|
|
|
<li>Linus Unnebäck</li>
|
|
|
|
<li>Lukas Abfalterer</li>
|
|
|
|
<li>Marc Mettke</li>
|
|
|
|
<li>Max Furman</li>
|
|
|
|
<li>messense</li>
|
|
|
|
<li>Ning Sun</li>
|
|
|
|
<li>Philip Jenvey</li>
|
|
|
|
<li>Pyry Kontio</li>
|
|
|
|
<li>Richo Healey</li>
|
|
|
|
<li>Riley Trautman</li>
|
|
|
|
<li>Rolf Schmidt</li>
|
|
|
|
<li>Rukai</li>
|
|
|
|
<li>Sean Stangl</li>
|
|
|
|
<li>Sébastien Santoro</li>
|
|
|
|
<li>Sergio Benitez</li>
|
|
|
|
<li>Stanislav Ivanov</li>
|
|
|
|
<li>Tal Garfinkel</li>
|
|
|
|
<li>Tobias Stolzmann</li>
|
|
|
|
<li>Ville Hakulinen</li>
|
|
|
|
<li>Vishal Sodani</li>
|
|
|
|
<li>Zack Chandler</li>
|
|
|
|
<li>Zac Pullar-Strecker</li>
|
|
|
|
</ul>
|
|
|
|
|
|
|
|
Thank you all! Your contributions are **greatly** appreciated!
|
|
|
|
|
|
|
|
Looking to help with Rocket's development? Head over to [Rocket's
|
|
|
|
GitHub](https://github.com/SergioBenitez/Rocket#contributing) and start
|
|
|
|
contributing!
|