Rocket v0.3: Fairings, TLS, Private Cookies
I'm excited to announce that the next major release of Rocket is available today! Rocket 0.3 is packed with new features and improvements that increase developer productivity, improve application security, and provide new opportunities for extensibility. Rocket 0.3 is the culmination of almost 6 months of work. During this time, more than 225 changes were committed, over 100 issues (primarily questions and feature requests) were closed, and over 40 pull requests were submitted. The Rocket community has proven steadfast in their support: a sincere thank you to everyone involved!
About Rocket
Rocket is a web framework for Rust with a focus on ease of use, expressiveness, and speed. Rocket makes it simple to write fast web applications without sacrificing flexibility or type safety. All with minimal code.
Not already using Rocket? Join the thousands of users and dozens of companies happily using Rocket today! Rocket's extensive documentation makes it easy. Get started now by reading through the guide or learning more from the overview.
What's New?
Rocket 0.3 is a big release, packed with over 100 changes. We highlight the biggest new features here. For a complete description of everything new and different in 0.3, please see the CHANGELOG.
Fairings
Fairings bring structured middleware to Rocket. With fairings, Rocket applications can hook into the application lifecycle to record or rewrite information about incoming requests, outgoing responses, and the Rocket application itself.
Rocket's fairings are a lot like middleware from other frameworks, but they bear a few key distinctions:
- Fairings cannot directly terminate or respond to an incoming request.
- Fairings cannot inject arbitrary, non-request data into a request.
- Fairings can prevent an application from launching.
- Fairings can inspect and modify the application's configuration.
Fairings are implemented through Rocket's Fairing trait. The trait consists of callback methods that Rocket invokes as needed. A fairing can subscribe to receive callbacks for the following four events:
- Attach: called when a fairing is first registered.
- Launch: called immediately before the Rocket application launches.
- Request: called just after a request is received.
- Response: called when a response is ready to be returned.
The new fairings guide describes fairings in detail, expands on their limitations and abilities, and includes implementation examples. I encourage you to experiment with fairings and report your experiences. As always, feedback is instrumental in solidifying a robust design.
Native TLS Support
Rocket 0.3 includes built-in, experimental support for TLS, powered by rustls. To enable TLS support, compile Rocket with the tls feature enabled. Then, configure file paths to an RSA certificate chain and corresponding private key in the Rocket.toml file or via environment variables:
1 2 3
[]
= "/path/to/certs.pem"
= "/path/to/key.pem"
TLS support in Rocket is experimental and not yet recommended for general use over the internet. Instead, prefer to place Rocket behind a mature reverse-proxy such as NGINX. That being said, use of Rocket's TLS support is encouraged for local networking (such as local-only IoT devices) or as required during development.
For more details on Rocket's TLS support, see the configuring TLS section of the guide.
Private Cookies
In Rocket 0.3, cookies can be private. Private cookies are encrypted using authenticated encryption, a form of encryption which simultaneously provides confidentiality, integrity, and authenticity. This means that private cookies cannot be inspected, tampered with, or manufactured by clients.
Retrieving, adding, and removing private cookies is done via the new get_private, add_private, and remove_private methods on the Cookies type. As an example, consider the code below which sets and retrieves a user_id private cookie in two routes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/// Retrieve the user's ID, if any.
/// Remove the `user_id` cookie.
To encrypt private cookies, Rocket uses the 256-bit key specified in the secret_key configuration parameter. If one is not specified, Rocket automatically generates a fresh key at launch.
For more details on private cookies, see the private cookies section of the guide.
Form Field Naming
In 0.2 and below, Rocket always matches form field names to structure field names exactly when deriving FromForm. This presented an issue when an invalid Rust identifier was used as a form field's name. For example, it was not possible to represent a form with a field name of "type" since type is a keyword and thus an illegal identifier. The following resulted in a compile-time error:
1 2 3 4
In Rocket 0.3, you can ask Rocket to match against a different form field for a given structure field by using the #[form(field = "name")] field annotation. As a result, the "type" form field can now be captured using something like the following:
1 2 3 4 5
Rocket will automatically match the form field named "type" to the structure field named api_type. For more details on form field naming, see the field renaming section of the guide.
And Plenty More!
In addition to the four highlighted above, Rocket 0.3 also ships with the following new features:
- A
MsgPacktype has been added for simple consumption and returning of MessagePack data. Rocket::launch()returns launch failures (LaunchError) for inspection without panicking.- Routes without query parameters now match requests with or without query parameters.
- Default rankings prefer static paths and routes with query string matches.
- A native
Acceptheader structure was added. - The
Acceptrequest header can be retrieved viaRequest::accept(). - All active routes can be retrieved via
Rocket::routes(). Response::body_string()was added to retrieve the response body as aString.Response::body_bytes()was added to retrieve the response body as aVec<u8>.Response::content_type()was added to retrieve the Content-Type header of a response.- Data limits on incoming data are now configurable.
Request::limits()was added to retrieve incoming data limits.- Responders may dynamically adjust their response based on the incoming request.
Request::guard()was added for simple retrieval of request guards.Request::route()was added to retrieve the active route, if any.&Routeis now a request guard.- The base mount path of a
Routecan be retrieved viaRoute::baseorRoute::base(). Config::{development, staging, production}constructors were added forConfig.Config::get_datetime()was added to retrieve an extra as aDatetime.- Forms can be now parsed leniently via the new
LenientFormdata guard. - The
?operator can now be used withOutcome. - Quoted string, array, and table configuration parameters can be set via environment variables.
- Log coloring is disabled when
stdoutis not a TTY. FromFormis implemented forOption<T: FromForm>,Result<T: FromForm, T::Error>.- The
NotFoundresponder was added for simple 404 response construction.
Breaking Changes
This release includes many breaking changes such as support for serde 1.0. To keep this release note short, please see the CHANGELOG for the full list of breaking changes along with a short note about how to handle the breaking change in existing applications.
General Improvements
In addition to new features, Rocket saw the following improvements:
- "Rocket" is now capitalized in the
ServerHTTP header. - The generic parameter of
rocket_contrib::Jsondefaults tojson::Value. - The trailing '...' in the launch message was removed.
- The launch message prints regardless of the config environment.
- For debugging,
FromDatais implemented forVec<u8>andString. - The port displayed on launch is the port resolved, not the one configured.
- The
uuiddependency was updated to0.5. - The
base64dependency was updated to0.6. - The
tomldependency was updated to0.4. - The
handlebarsdependency was updated to0.27. - The
teradependency was updated to0.10. yansiis now used for all terminal coloring.- The
devrustcrelease channel is supported during builds. Configis now exported from the root.RequestimplementsCloneandDebug.- The
workersconfig parameter now defaults tonum_cpus * 2. - Console logging for table-based config values is improved.
PartialOrd,Ord, andHashare now implemented forState.- The format of a request is always logged when available.
What's Next?
Rocket 0.4, of course! The focus of the next major release is two-fold: security and usability. The following major features are planned:
- Automatic CSRF protection across all payload-based requests (#14).
This is a carry-over from the 0.3 wishlist. Rocket will automatically check
the origin of requests made for HTTP `PUT`, `POST`, `DELETE`, and `PATCH`
requests, allowing only valid requests to be dispatched. This includes
checking form submissions and requests made via JavaScript.
- First-class database support (#167).
Connecting a database to Rocket is presently [much wordier than necessary].
The plan for 0.4 is to minimize the amount of effort. At most, a couple of
lines of configuration and a single line of initialization code should be
required.
- Typed URL generation from routes (#263).
Explicitly writing URLs is error-prone. Because routes are fully-typed in
Rocket, it's possible to check that a URL corresponding to a route
type-checks. In the next release, a `url!` macro will be available to
automatically generate URLs for routes in a type-safe manner.
Contributors to v0.3
The following wonderful people helped make Rocket v0.3 happen:
- Alan Stoate
- Alexey Zabelin
- Anton Pirker
- Fabrice Desré
- Ivar Abrahamsen
- Josh Holmer
- Joshua Rombauer
- Lance Carlson
- Lori Holden
- Roman Frołow
- Ryan Leckey
- Stephan Buys
- Tomek Wałkuski
- Vesa Kaihlavirta
- Yong Wen Chua
Thank you all! Your contributions are greatly appreciated!
Looking to help with Rocket's development? Head over to Rocket's GitHub and start contributing!