Reorganize and upgrade markup in site docs.

The guide is now in docs/guide. All other site assets are being migrated
to a separate repository.

The guide markup has been upgraded to take advantages of improvements in
the static site generator used to build the Rocket website.
This commit is contained in:
Sergio Benitez 2022-06-10 11:21:15 -07:00
parent a866134212
commit 8d3f1d65ac
42 changed files with 500 additions and 3718 deletions

6
.gitattributes vendored
View File

@ -1 +1,7 @@
* text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.gif binary
*.svg binary

View File

@ -10,5 +10,5 @@ members = [
"contrib/sync_db_pools/lib/",
"contrib/dyn_templates/",
"contrib/ws/",
"site/tests",
"docs/tests",
]

View File

@ -159,4 +159,4 @@ Rocket is licensed under either of the following, at your option:
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0)
* MIT License ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)
The Rocket website source is licensed under [separate terms](site#license).
The Rocket website docs are licensed under [separate terms](docs/LICENSE).

View File

@ -619,56 +619,3 @@ Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -1,3 +1,7 @@
+++
summary = "introduces Rocket and its philosophy"
+++
# Introduction
Rocket is a web framework for Rust. If you'd like, you can think of Rocket as

View File

@ -0,0 +1,16 @@
+++
summary = "a migration guide from Rocket v0.5 to v0.6"
+++
# Upgrading
This a placeholder for an eventual migration guide from v0.5 to v0.6.
## Getting Help
If you run into any issues upgrading, we encourage you to ask questions via
[GitHub discussions] or via chat at [`#rocket:mozilla.org`] on Matrix. The
[FAQ](../faq/) also provides answers to commonly asked questions.
[GitHub discussions]: @github/discussions
[`#rocket:mozilla.org`]: @chat

View File

@ -1,9 +1,13 @@
+++
summary = "the minimal steps to running your first Rocket application"
+++
# Quickstart
Before you can start writing a Rocket application, you'll need to install the
Rust toolchain. We recommend using [rustup](https://rustup.rs/). If you don't
have Rust installed and would like extra guidance doing so, see the [getting
started](../getting-started) section.
have Rust installed and would like extra guidance doing so, see [Getting
Started].
## Running Examples
@ -28,4 +32,4 @@ with `cargo run`.
libraries. When copying the examples for your own use, you should modify the
`Cargo.toml` files as explained in the [Getting Started] guide.
[Getting Started]: ../getting-started
[Getting Started]: ../getting-started/

View File

@ -1,3 +1,7 @@
+++
summary = "a gentle introduction to running your first Rocket application"
+++
# Getting Started
Let's create and run our first Rocket application. We'll ensure we have a
@ -19,7 +23,7 @@ the command:
rustup default stable
```
! note: You may prefer to develop using the _nightly_ channel.
! note: You may prefer to develop using the `nightly` channel.
The nightly Rust toolchain enables certain improved developer experiences,
such as better compile-time diagnostics, when developing with Rocket. You may
@ -52,12 +56,9 @@ rocket = "0.6.0-dev"
development version of Rocket, you'll need to point `Cargo.toml` to a Rocket
git repository. For example, with `######` replaced with a git commit hash:
`
[dependencies]
`
`
```toml
rocket = { git = "https://github.com/rwf2/Rocket", rev = "######" }
`
```
Modify `src/main.rs` so that it contains the code for the Rocket `Hello, world!`
program, reproduced below:

View File

@ -1,3 +1,7 @@
+++
summary = "an overview of Rocket's core concepts"
+++
# Overview
Rocket provides primitives to build web servers and applications with Rust:
@ -75,7 +79,7 @@ incoming `GET` requests. Instead of `#[get]`, we could have used `#[post]` or
`#[put]` for other HTTP methods, or `#[catch]` for serving [custom error
pages](../requests/#error-catchers). Additionally, other route parameters may be
necessary when building more interesting applications. The
[Requests](../requests) chapter, which follows this one, has further details on
[Requests](../requests/) chapter, which follows this one, has further details on
routing and error handling.
! note: We prefer `#[macro_use]`, but you may prefer explicit imports.
@ -192,9 +196,9 @@ as we expected.
! note: This and other examples are on GitHub.
An expanded version of this example's complete crate, ready to `cargo run`,
can be found on [GitHub](@example/hello). You can find dozens of other
can be found on [GitHub](@git/master/examples/hello). You can find dozens of other
complete examples, spanning all of Rocket's features, in the [GitHub examples
directory](@example/).
directory](@git/master/examples/).
The second approach uses the `#[rocket::main]` route attribute.
`#[rocket::main]` _also_ generates a `main` function that sets up an async
@ -223,8 +227,8 @@ async fn main() -> Result<(), rocket::Error> {
is desired, or when the return value of [`launch()`] is to be inspected. The
[error handling example] for instance, inspects the return value.
[`launch()`]: @api/rocket/struct.Rocket.html#method.launch
[error handling example]: @example/error-handling
[`launch()`]: @api/master/rocket/struct.Rocket.html#method.launch
[error handling example]: @git/master/examples/error-handling
## Futures and Async
@ -251,17 +255,17 @@ You can find async-ready libraries on [crates.io](https://crates.io) with the
`async` tag.
[`Future`]: @std/future/trait.Future.html
[`Data`]: @api/rocket/struct.Data.html
[`DataStream`]: @api/rocket/data/struct.DataStream.html
[Routes]: ../requests
[Error Catchers]: ../requests#error-catchers
[`FromData`]: ../requests#body-data
[`FromRequest`]: ../requests#request-guards
[`Data`]: @api/master/rocket/struct.Data.html
[`DataStream`]: @api/master/rocket/data/enum.DataStream.html
[Routes]: ../requests/
[Error Catchers]: ../requests/#error-catchers
[`FromData`]: ../requests/#body-data
[`FromRequest`]: ../requests/#request-guards
! note
Rocket uses the tokio runtime. The runtime is started for you if you use
`#[launch]` or `#[rocket::main]`, but you can still `launch()` a Rocket
Rocket uses the tokio runtime. The runtime is started for you if you
use `#[launch]` or `#[rocket::main]`, but you can still `launch()` a Rocket
instance on a custom-built runtime by not using _either_ attribute.
### Async Routes

View File

@ -1,3 +1,7 @@
+++
summary = "handling request and body data: control-flow, parsing, validation"
+++
# Requests
Together, a [`route`] attribute and function signature specify what must be true
@ -29,7 +33,7 @@ validations. Rocket's code generation takes care of actually validating the
properties. This section describes how to ask Rocket to validate against all of
these properties and more.
[`route`]: @api/rocket/attr.route.html
[`route`]: @api/master/rocket/attr.route.html
## Methods
@ -64,7 +68,7 @@ request contains a body of `Content-Type: application/x-www-form-urlencoded` and
the form's **first** field has the name `_method` and a valid HTTP method name
as its value (such as `"PUT"`), that field's value is used as the method for the
incoming request. This allows Rocket applications to submit non-`POST` forms.
The [todo example](@example/todo/static/index.html.tera#L47) makes use of this
The [todo example](@git/master/examples/todo/static/index.html.tera#L47) makes use of this
feature to submit `PUT` and `DELETE` requests from a web form.
## Dynamic Paths
@ -109,8 +113,8 @@ fn hello(name: &str, age: u8, cool: bool) -> String {
}
```
[`FromParam`]: @api/rocket/request/trait.FromParam.html
[`FromParam` API docs]: @api/rocket/request/trait.FromParam.html
[`FromParam`]: @api/master/rocket/request/trait.FromParam.html
[`FromParam` API docs]: @api/master/rocket/request/trait.FromParam.html
### Multiple Segments
@ -156,10 +160,21 @@ async fn files(file: PathBuf) -> Option<NamedFile> {
If you need to serve static files from your Rocket application, consider using
[`FileServer`], which makes it as simple as:
`rocket.mount("/public", FileServer::from("static/"))`
```rust
# #[macro_use] extern crate rocket;
[`FileServer`]: @api/rocket/fs/struct.FileServer.html
[`FromSegments`]: @api/rocket/request/trait.FromSegments.html
use rocket::fs::FileServer;
#[launch]
fn rocket() -> _ {
rocket::build()
// serve files from `/www/static` at path `/public`
.mount("/public", FileServer::from("/www/static"))
}
```
[`FileServer`]: @api/master/rocket/fs/struct.FileServer.html
[`FromSegments`]: @api/master/rocket/request/trait.FromSegments.html
### Ignored Segments
@ -188,7 +203,7 @@ fn everything() -> &'static str {
}
# // Ensure there are no collisions.
# rocket_guide_tests::client(routes![foo_bar, everything]);
# rocket_docs_tests::client(routes![foo_bar, everything]);
```
## Forwarding
@ -317,9 +332,9 @@ fn foo_bar() { }
#[get("/<_..>")]
fn everything() { }
#
# // Ensure there are no collisions.
# rocket_guide_tests::client(routes![foo_bar, everything]);
# rocket_docs_tests::client(routes![foo_bar, everything]);
```
Default ranking ensures that `foo_bar`, with a "partial" path color, has higher
@ -363,8 +378,8 @@ short-circuiting; if one guard fails, the remaining are not attempted. To learn
more about request guards and implementing them, see the [`FromRequest`]
documentation.
[`FromRequest`]: @api/rocket/request/trait.FromRequest.html
[`CookieJar`]: @api/rocket/http/struct.CookieJar.html
[`FromRequest`]: @api/master/rocket/request/trait.FromRequest.html
[`CookieJar`]: @api/master/rocket/http/struct.CookieJar.html
### Custom Guards
@ -567,8 +582,8 @@ fn login(cert: Option<Result<mtls::Certificate, mtls::Error>>) {
}
```
[`mtls::Certificate`]: @api/rocket/mtls/struct.Certificate.html
[`mtls::Error`]: @api/rocket/mtls/enum.Error.html
[`mtls::Certificate`]: @api/master/rocket/mtls/struct.Certificate.html
[`mtls::Error`]: @api/master/rocket/mtls/enum.Error.html
## Cookies
@ -593,7 +608,7 @@ be set and removed using the `CookieJar` guard. The [cookies example] on GitHub
illustrates further use of the `CookieJar` type to get and set cookies, while
the [`CookieJar`] documentation contains complete usage information.
[cookies example]: @example/cookies
[cookies example]: @git/master/examples/cookies
### Private Cookies
@ -641,7 +656,7 @@ fn logout(cookies: &CookieJar<'_>) -> Flash<Redirect> {
}
```
[`CookieJar::add()`]: @api/rocket/http/struct.CookieJar.html#method.add
[`CookieJar::add()`]: @api/master/rocket/http/struct.CookieJar.html#method.add
### Secret Key
@ -656,12 +671,13 @@ Generating a string suitable for use as a `secret_key` configuration value is
usually done through tools like `openssl`. Using `openssl`, a 256-bit base64 key
can be generated with the command `openssl rand -base64 32`.
For more information on configuration, see the [Configuration](../configuration)
section of the guide.
For more information on configuration, see the [Configuration] section of the
guide.
[`get_private`]: @api/rocket/http/struct.CookieJar.html#method.get_private
[`add_private`]: @api/rocket/http/struct.CookieJar.html#method.add_private
[`remove_private`]: @api/rocket/http/struct.CookieJar.html#method.remove_private
[`get_private`]: @api/master/rocket/http/struct.CookieJar.html#method.get_private
[`add_private`]: @api/master/rocket/http/struct.CookieJar.html#method.add_private
[`remove_private`]: @api/master/rocket/http/struct.CookieJar.html#method.remove_private
[Configuration]: ../configuration/
## Format
@ -718,7 +734,7 @@ header will match `user`. If instead the route had been declared as `post`,
Rocket would match the `format` against the `Content-Type` header of the
incoming response.
[`ContentType::parse_flexible()`]: @api/rocket/http/struct.ContentType.html#method.parse_flexible
[`ContentType::parse_flexible()`]: @api/master/rocket/http/struct.ContentType.html#method.parse_flexible
## Body Data
@ -738,11 +754,11 @@ fn new(input: T) { /* .. */ }
Any type that implements [`FromData`] is also known as _a data guard_.
[`FromData`]: @api/rocket/data/trait.FromData.html
[`FromData`]: @api/master/rocket/data/trait.FromData.html
### JSON
The [`Json<T>`](@api/rocket/serde/json/struct.Json.html) guard deserializes body
The [`Json<T>`](@api/master/rocket/serde/json/struct.Json.html) guard deserializes body
data as JSON. The only condition is that the generic type `T` implements the
`Deserialize` trait from [`serde`](https://serde.rs).
@ -771,26 +787,26 @@ fn new(task: Json<Task<'_>>) { /* .. */ }
you'd like to avoid this extra annotation, you must depend on `serde` directly
via your crate's `Cargo.toml`:
`
```toml
serde = { version = "1.0", features = ["derive"] }
`
```
We always use the extra annotation in the guide, but you may prefer the
alternative.
See the [JSON example](@example/serialization/src/json.rs) on GitHub for a
See the [JSON example](@git/master/examples/serialization/src/json.rs) on GitHub for a
complete example.
! note: JSON support requires enabling Rocket's `json` feature flag.
Rocket intentionally places JSON support, as well support for other data
formats and features, behind feature flags. See [the api
docs](@api/rocket/#features) for a list of available features. The `json`
docs](@api/master/rocket/#features) for a list of available features. The `json`
feature can be enabled in the `Cargo.toml`:
`
```toml
rocket = { version = "0.6.0-dev", features = ["json"] }
`
```
### Temporary Files
@ -809,13 +825,13 @@ async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
}
```
[`TempFile`]: @api/rocket/fs/enum.TempFile.html
[`TempFile`]: @api/master/rocket/fs/enum.TempFile.html
### Streaming
Sometimes you just want to handle incoming data directly. For example, you might
want to stream the incoming data to some sink. Rocket makes this as simple as
possible via the [`Data`](@api/rocket/data/struct.Data.html) type:
possible via the [`Data`](@api/master/rocket/data/struct.Data.html) type:
```rust
# #[macro_use] extern crate rocket;
@ -842,9 +858,9 @@ response is returned. The handler above is complete. It really is that simple!
! note: Rocket requires setting limits when reading incoming data.
To aid in preventing DoS attacks, Rocket requires you to specify, as a
[`ByteUnit`](@api/rocket/data/struct.ByteUnit.html), the amount of data you're
[`ByteUnit`](@api/master/rocket/data/struct.ByteUnit.html), the amount of data you're
willing to accept from the client when `open`ing a data stream. The
[`ToByteUnit`](@api/rocket/data/trait.ToByteUnit.html) trait makes specifying
[`ToByteUnit`](@api/master/rocket/data/trait.ToByteUnit.html) trait makes specifying
such a value as idiomatic as `128.kibibytes()`.
## Forms
@ -915,9 +931,9 @@ struct Upload<'r> {
fn upload_form(upload: Form<Upload<'_>>) { /* .. */ }
```
[`Form`]: @api/rocket/form/struct.Form.html
[`FromForm`]: @api/rocket/form/trait.FromForm.html
[`FromFormField`]: @api/rocket/form/trait.FromFormField.html
[`Form`]: @api/master/rocket/form/struct.Form.html
[`FromForm`]: @api/master/rocket/form/trait.FromForm.html
[`FromFormField`]: @api/master/rocket/form/trait.FromFormField.html
### Parsing Strategy
@ -966,8 +982,8 @@ lenient. `Form` is lenient by default, so a `Form<Lenient<T>>` is redundant, but
`Lenient` can be used to overwrite a strict parse as lenient:
`Option<Lenient<T>>`.
[`Form<Strict<T>>`]: @api/rocket/form/struct.Strict.html
[`Lenient`]: @api/rocket/form/struct.Lenient.html
[`Form<Strict<T>>`]: @api/master/rocket/form/struct.Strict.html
[`Lenient`]: @api/master/rocket/form/struct.Lenient.html
### Defaults
@ -990,8 +1006,7 @@ struct MyForm<'v> {
ok_or_error: form::Result<'v, Vec<&'v str>>,
here_or_false: bool,
}
# rocket_guide_tests::assert_form_parses_ok!(MyForm, "");
# rocket_docs_tests::assert_form_parses_ok!(MyForm, "");
```
The default can be overridden or unset using the `#[field(default = expr)]`
@ -1020,9 +1035,9 @@ See the [`FromForm` derive] documentation for full details on the `default`
attribute parameter as well documentation on the more expressive `default_with`
parameter option.
[`Errors<'_>`]: @api/rocket/form/struct.Errors.html
[`form::Result`]: @api/rocket/form/type.Result.html
[`FromForm` derive]: @api/rocket/derive.FromForm.html
[`Errors<'_>`]: @api/master/rocket/form/struct.Errors.html
[`form::Result`]: @api/master/rocket/form/type.Result.html
[`FromForm` derive]: @api/master/rocket/derive.FromForm.html
### Field Renaming
@ -1126,10 +1141,10 @@ struct Password<'r> {
}
```
[`form::validate`]: @api/rocket/form/validate/index.html
[`form::validate::range`]: @api/rocket/form/validate/fn.range.html
[`form::Result`]: @api/rocket/form/type.Result.html
[`Errors<'_>`]: @api/rocket/form/error/struct.Errors.html
[`form::validate`]: @api/master/rocket/form/validate/index.html
[`form::validate::range`]: @api/master/rocket/form/validate/fn.range.html
[`form::Result`]: @api/master/rocket/form/type.Result.html
[`Errors<'_>`]: @api/master/rocket/form/error/struct.Errors.html
In reality, the expression after `validate =` can be _any_ expression as long as
it evaluates to a value of type `Result<(), Errors<'_>>` (aliased by
@ -1201,7 +1216,7 @@ use std::str::FromStr;
struct Token<'r>(&'r str);
```
[`try_with`]: @api/rocket/form/validate/fn.try_with.html
[`try_with`]: @api/master/rocket/form/validate/fn.try_with.html
### Collections
@ -1267,7 +1282,7 @@ Such a form, URL-encoded, may look like:
```rust
# use rocket::form::FromForm;
# use rocket_guide_tests::{assert_form_parses, assert_not_form_parses};
# use rocket_docs_tests::{assert_form_parses, assert_not_form_parses};
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { owner: Person, pet: Pet, }
# #[derive(FromForm, Debug, PartialEq)] struct Person { name: String }
# #[derive(FromForm, Debug, PartialEq)] struct Pet { name: String, good_pet: bool, }
@ -1298,7 +1313,7 @@ place of or in addition to `.`:
```rust
# use rocket::form::FromForm;
# use rocket_guide_tests::{assert_form_parses, assert_not_form_parses};
# use rocket_docs_tests::{assert_form_parses, assert_not_form_parses};
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { owner: Person, pet: Pet, }
# #[derive(FromForm, Debug, PartialEq)] struct Person { name: String }
# #[derive(FromForm, Debug, PartialEq)] struct Pet { name: String, good_pet: bool, }
@ -1354,7 +1369,7 @@ Consider the following examples.
```rust
# use rocket::form::FromForm;
# use rocket_guide_tests::{assert_form_parses, assert_not_form_parses};
# use rocket_docs_tests::{assert_form_parses, assert_not_form_parses};
# #[derive(FromForm, PartialEq, Debug)] struct MyForm { numbers: Vec<usize>, }
// These form strings...
# assert_form_parses! { MyForm,
@ -1423,7 +1438,7 @@ Examples include:
```rust
# use rocket::form::FromForm;
# use rocket_guide_tests::{assert_form_parses, assert_not_form_parses};
# use rocket_docs_tests::{assert_form_parses, assert_not_form_parses};
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { name: String, pets: Vec<Pet>, }
# #[derive(FromForm, Debug, PartialEq)] struct Pet { name: String, good_pet: bool, }
// These form strings...
@ -1463,7 +1478,7 @@ The rules are exactly the same.
```rust
# use rocket::form::FromForm;
# use rocket_guide_tests::assert_form_parses;
# use rocket_docs_tests::assert_form_parses;
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { v: Vec<Vec<usize>>, }
# assert_form_parses! { MyForm,
"v=1&v=2&v=3" => MyForm { v: vec![vec![1], vec![2], vec![3]] },
@ -1506,7 +1521,7 @@ As an example, the following are equivalent and all parse to `{ "a" => 1, "b" =>
# use std::collections::HashMap;
#
# use rocket::form::FromForm;
# use rocket_guide_tests::{map, assert_form_parses};
# use rocket_docs_tests::{map, assert_form_parses};
#
# #[derive(Debug, PartialEq, FromForm)]
# struct MyForm {
@ -1561,7 +1576,7 @@ Examples include:
# use std::collections::HashMap;
#
# use rocket::form::FromForm;
# use rocket_guide_tests::{map, assert_form_parses};
# use rocket_docs_tests::{map, assert_form_parses};
#
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { ids: HashMap<usize, Person>, }
@ -1636,7 +1651,7 @@ Examples include:
# use std::collections::HashMap;
#
# use rocket::form::FromForm;
# use rocket_guide_tests::{map, assert_form_parses};
# use rocket_docs_tests::{map, assert_form_parses};
#
# #[derive(FromForm, Debug, PartialEq)] struct MyForm { m: HashMap<Person, Pet>, }
@ -1728,7 +1743,7 @@ Where we have the following symbolic keys:
# use std::collections::HashMap;
#
# use rocket::form::FromForm;
# use rocket_guide_tests::{map, bmap, assert_form_parses};
# use rocket_docs_tests::{map, bmap, assert_form_parses};
# #[derive(FromForm, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
# struct Person { name: String, age: usize }
@ -1806,9 +1821,9 @@ will be returned.
The [forms example], too, makes use of form contexts, as well as every other
forms feature.
[`Contextual`]: @api/rocket/form/struct.Contextual.html
[`Context`]: @api/rocket/form/struct.Context.html
[forms example]: @example/forms
[`Contextual`]: @api/master/rocket/form/struct.Contextual.html
[`Context`]: @api/master/rocket/form/struct.Context.html
[forms example]: @git/master/examples/forms
## Query Strings
@ -1851,15 +1866,15 @@ fn cats() -> &'static str {
}
// The following GET requests match `cats`. `%E2%99%A5` is encoded `♥`.
# let status = rocket_guide_tests::client(routes![cats]).get(
# let status = rocket_docs_tests::client(routes![cats]).get(
"/?cat=%E2%99%A5&hello"
# ).dispatch().status();
# assert_eq!(status, rocket::http::Status::Ok);
# let status = rocket_guide_tests::client(routes![cats]).get(
# let status = rocket_docs_tests::client(routes![cats]).get(
"/?hello&cat=%E2%99%A5"
# ).dispatch().status();
# assert_eq!(status, rocket::http::Status::Ok);
# let status = rocket_guide_tests::client(routes![cats]).get(
# let status = rocket_docs_tests::client(routes![cats]).get(
"/?dogs=amazing&hello&there&cat=%E2%99%A5"
# ).dispatch().status();
# assert_eq!(status, rocket::http::Status::Ok);
@ -1906,7 +1921,7 @@ fn hello(name: &str, color: Vec<Color>, person: Person<'_>, other: Option<usize>
}
// A request with these query segments matches as above.
# let status = rocket_guide_tests::client(routes![hello]).get("/?\
# let status = rocket_docs_tests::client(routes![hello]).get("/?\
name=George&\
color=red&\
color=green&\
@ -1948,7 +1963,7 @@ fn user(id: usize, user: User<'_>) {
}
// A request with these query segments matches as above.
# let status = rocket_guide_tests::client(routes![user]).get("/?\
# let status = rocket_docs_tests::client(routes![user]).get("/?\
hello&\
name=Bob+Smith&\
id=1337&\
@ -2110,13 +2125,13 @@ Rocket provides a built-in default catcher. It produces HTML or JSON, depending
on the value of the `Accept` header. As such, custom catchers only need to be
registered for custom error handling.
The [error handling example](@example/error-handling) illustrates catcher use in
The [error handling example](@git/master/examples/error-handling) illustrates catcher use in
full, while the [`Catcher`] API documentation provides further details.
[`catch`]: @api/rocket/attr.catch.html
[`register()`]: @api/rocket/struct.Rocket.html#method.register
[`mount()`]: @api/rocket/struct.Rocket.html#method.mount
[`catchers!`]: @api/rocket/macro.catchers.html
[`&Request`]: @api/rocket/struct.Request.html
[`Status`]: @api/rocket/http/struct.Status.html
[`Catcher`]: @api/rocket/catcher/struct.Catcher.html
[`catch`]: @api/master/rocket/attr.catch.html
[`register()`]: @api/master/rocket/struct.Rocket.html#method.register
[`mount()`]: @api/master/rocket/struct.Rocket.html#method.mount
[`catchers!`]: @api/master/rocket/macro.catchers.html
[`&Request`]: @api/master/rocket/struct.Request.html
[`Status`]: @api/master/rocket/http/struct.Status.html
[`Catcher`]: @api/master/rocket/catcher/struct.Catcher.html

View File

@ -1,3 +1,7 @@
+++
summary = "generating responses and using typed URIs"
+++
# Responses
You may have noticed that the return type of a handler appears to be arbitrary,
@ -6,7 +10,7 @@ trait can be returned, including your own. In this section, we describe the
`Responder` trait as well as several useful `Responder`s provided by Rocket.
We'll also briefly discuss how to implement your own `Responder`.
[`Responder`]: @api/rocket/response/trait.Responder.html
[`Responder`]: @api/master/rocket/response/trait.Responder.html
## Responder
@ -17,7 +21,7 @@ decides which to use. For instance, `String` uses a fixed-sized body, while
`File` uses a streamed response. Responders may dynamically adjust their
responses according to the incoming `Request` they are responding to.
[`Response`]: @api/rocket/response/struct.Response.html
[`Response`]: @api/master/rocket/response/struct.Response.html
### Wrapping
@ -31,7 +35,7 @@ struct WrappingResponder<R>(R);
A wrapping responder modifies the response returned by `R` before responding
with that same response. For instance, Rocket provides `Responder`s in the
[`status` module](@api/rocket/response/status/) that override the status code of
[`status` module](@api/master/rocket/response/status/) that override the status code of
the wrapped `Responder`. As an example, the [`Accepted`] type sets the status to
`202 - Accepted`. It can be used as follows:
@ -47,7 +51,7 @@ fn new(id: usize) -> status::Accepted<String> {
}
```
Similarly, the types in the [`content` module](@api/rocket/response/content/)
Similarly, the types in the [`content` module](@api/master/rocket/response/content/)
can be used to override the Content-Type of a response. For instance, to set the
Content-Type of `&'static str` to JSON, as well as setting the status code to an
arbitrary one like `418 I'm a teapot`, combine [`content::RawJson`] with
@ -95,10 +99,10 @@ fn json() -> RawTeapotJson {
}
```
[`Accepted`]: @api/rocket/response/status/struct.Accepted.html
[`content::Json`]: @api/rocket/response/content/struct.Json.html
[`status::Custom`]: @api/rocket/response/status/struct.Custom.html
[`serde::json::Json`]: @api/rocket/serde/json/struct.Json.html
[`Accepted`]: @api/master/rocket/response/status/struct.Accepted.html
[`content::Json`]: @api/master/rocket/response/content/struct.Json.html
[`status::Custom`]: @api/master/rocket/response/status/struct.Custom.html
[`serde::json::Json`]: @api/master/rocket/serde/json/struct.Json.html
[custom responder]: #custom-responders
### Errors
@ -144,7 +148,7 @@ generated by `Status` for these and other codes:
| 100, [200, 205] | Empty with given status. |
| All others. | Invalid. Errors to `500` catcher. |
[`Status`]: @api/rocket/http/struct.Status.html
[`Status`]: @api/master/rocket/http/struct.Status.html
## Custom Responders
@ -232,8 +236,8 @@ enum Error {
For more on using the `Responder` derive, including details on how to use the
derive to define generic responders, see the [`Responder` derive] documentation.
[`Responder` derive]: @api/rocket/derive.Responder.html
[`ContentType`]: @api/rocket/http/struct.ContentType.html
[`Responder` derive]: @api/master/rocket/derive.Responder.html
[`ContentType`]: @api/master/rocket/http/struct.ContentType.html
## Implementations
@ -352,14 +356,14 @@ are:
* [`MsgPack`] - Automatically serializes values into MessagePack.
* [`Template`] - Renders a dynamic template using handlebars or Tera.
[`status`]: @api/rocket/response/status/
[`content`]: @api/rocket/response/content/
[`response`]: @api/rocket/response/
[`NamedFile`]: @api/rocket/fs/struct.NamedFile.html
[`Redirect`]: @api/rocket/response/struct.Redirect.html
[`Flash`]: @api/rocket/response/struct.Flash.html
[`MsgPack`]: @api/rocket/serde/msgpack/struct.MsgPack.html
[`Template`]: @api/rocket_dyn_templates/struct.Template.html
[`status`]: @api/master/rocket/response/status/
[`content`]: @api/master/rocket/response/content/
[`response`]: @api/master/rocket/response/
[`NamedFile`]: @api/master/rocket/fs/struct.NamedFile.html
[`Redirect`]: @api/master/rocket/response/struct.Redirect.html
[`Flash`]: @api/master/rocket/response/struct.Flash.html
[`MsgPack`]: @api/master/rocket/serde/msgpack/struct.MsgPack.html
[`Template`]: @api/master/rocket_dyn_templates/struct.Template.html
### Async Streams
@ -413,13 +417,13 @@ fn hello() -> TextStream![&'static str] {
See the [`stream`] docs for full details on creating streams including notes on
how to detect and handle graceful shutdown requests.
[`stream`]: @api/rocket/response/stream/index.html
[`stream!`]: @api/rocket/response/stream/macro.stream.html
[`stream`]: @api/master/rocket/response/stream/index.html
[`stream!`]: @api/master/rocket/response/stream/macro.stream.html
[async `Stream`]: https://docs.rs/futures/0.3/futures/stream/trait.Stream.html
[`ReaderStream`]: @api/rocket/response/stream/struct.ReaderStream.html
[`TextStream`]: @api/rocket/response/stream/struct.TextStream.html
[`EventStream`]: @api/rocket/response/stream/struct.EventStream.html
[`chat` example]: @example/chat
[`ReaderStream`]: @api/master/rocket/response/stream/struct.ReaderStream.html
[`TextStream`]: @api/master/rocket/response/stream/struct.TextStream.html
[`EventStream`]: @api/master/rocket/response/stream/struct.EventStream.html
[`chat` example]: @git/master/examples/chat
### WebSockets
@ -456,8 +460,8 @@ fn echo_stream(ws: WebSocket) -> Stream!['static] {
For complete usage details, see the [`rocket_ws`] documentation.
[HTTP connection upgrades]: @api-v0.5/rocket/response/struct.Response.html#upgrading
[`rocket_ws`]: @api-v0.5/rocket_ws
[HTTP connection upgrades]: @api/master/rocket/response/struct.Response.html#upgrading
[`rocket_ws`]: @api/master/rocket_ws/
### JSON
@ -492,10 +496,10 @@ fails, a **500 - Internal Server Error** is returned.
The [serialization example] provides further illustration.
[`Json`]: @api/rocket/serde/json/struct.Json.html
[`Json`]: @api/master/rocket/serde/json/struct.Json.html
[`Serialize`]: https://docs.serde.rs/serde/trait.Serialize.html
[`serde`]: https://serde.rs
[serialization example]: @example/serialization
[serialization example]: @git/master/examples/serialization
## Templates
@ -544,7 +548,7 @@ fn index() -> Template {
To render a template, it must first be registered. The `Template` fairing
automatically registers all discoverable templates when attached. The
[Fairings](../fairings) sections of the guide provides more information on
[Fairings](../fairings/) sections of the guide provides more information on
fairings. To attach the template fairing, simply call
`.attach(Template::fairing())` on an instance of `Rocket` as follows:
@ -570,10 +574,10 @@ used.
! note: The name of the template _does not_ include its extension.
For a template file named `index.html.tera`, call `render("index")` and use
the name `"index"` in templates, i.e, `{% extends "index" %}` or `{% extends
"base" %}` for `base.html.tera`.
the name `"index"` in templates, i.e, `extends "index"` or `extends "base"`
for `base.html.tera`.
[`context!`]: @api/rocket_dyn_templates/macro.context.html
[`context!`]: @api/master/rocket_dyn_templates/macro.context.html
### Live Reloading
@ -585,10 +589,10 @@ reloading is disabled.
The [`Template`] API documentation contains more information about templates,
including how to customize a template engine to add custom helpers and filters.
The [templating example](@example/templating) uses both Tera and Handlebars
The [templating example](@git/master/examples/templating) uses both Tera and Handlebars
templating to implement the same application.
[configurable]: ../configuration
[configurable]: ../configuration/
## Typed URIs
@ -818,15 +822,15 @@ uri!(person(id = 100, details = "a/b/c"));
See the [`FromUriParam`] documentation for further details.
[`Origin`]: @api/rocket/http/uri/struct.Origin.html
[`Part`]: @api/rocket/http/uri/fmt/trait.Part.html
[`Uri`]: @api/rocket/http/uri/enum.Uri.html
[`Redirect::to()`]: @api/rocket/response/struct.Redirect.html#method.to
[`uri!`]: @api/rocket/macro.uri.html
[`UriDisplay`]: @api/rocket/http/uri/fmt/trait.UriDisplay.html
[`FromUriParam`]: @api/rocket/http/uri/fmt/trait.FromUriParam.html
[`Path`]: @api/rocket/http/uri/fmt/enum.Path.html
[`Query`]: @api/rocket/http/uri/fmt/enum.Query.html
[`Ignorable`]: @api/rocket/http/uri/fmt/trait.Ignorable.html
[`UriDisplayPath`]: @api/rocket/derive.UriDisplayPath.html
[`UriDisplayQuery`]: @api/rocket/derive.UriDisplayQuery.html
[`Origin`]: @api/master/rocket/http/uri/struct.Origin.html
[`Part`]: @api/master/rocket/http/uri/fmt/trait.Part.html
[`Uri`]: @api/master/rocket/http/uri/enum.Uri.html
[`Redirect::to()`]: @api/master/rocket/response/struct.Redirect.html#method.to
[`uri!`]: @api/master/rocket/macro.uri.html
[`UriDisplay`]: @api/master/rocket/http/uri/fmt/trait.UriDisplay.html
[`FromUriParam`]: @api/master/rocket/http/uri/fmt/trait.FromUriParam.html
[`Path`]: @api/master/rocket/http/uri/fmt/enum.Path.html
[`Query`]: @api/master/rocket/http/uri/fmt/enum.Query.html
[`Ignorable`]: @api/master/rocket/http/uri/fmt/trait.Ignorable.html
[`UriDisplayPath`]: @api/master/rocket/derive.UriDisplayPath.html
[`UriDisplayQuery`]: @api/master/rocket/derive.UriDisplayQuery.html

View File

@ -1,3 +1,7 @@
+++
summary = "managing application state and connecting to databases"
+++
# State
Many web applications have a need to maintain state. This can be as simple as
@ -27,10 +31,11 @@ The process for using managed state is simple:
ensuring that the type of values you store in managed state implement `Send` +
`Sync`.
### Adding State
To instruct Rocket to manage state for your application, call the
[`manage`](@api/rocket/struct.Rocket.html#method.manage) method
[`manage`](@api/master/rocket/struct.Rocket.html#method.manage) method
on an instance of `Rocket`. For example, to ask Rocket to manage a `HitCount`
structure with an internal `AtomicUsize` with an initial value of `0`, we can
write the following:
@ -63,7 +68,7 @@ rocket::build()
### Retrieving State
State that is being managed by Rocket can be retrieved via the
[`&State`](@api/rocket/struct.State.html) type: a [request
[`&State`](@api/master/rocket/struct.State.html) type: a [request
guard](../requests/#request-guards) for managed state. To use the request guard,
add a `&State<T>` type to any request handler, where `T` is the type of the
managed state. For example, we can retrieve and respond with the current
@ -104,14 +109,14 @@ fn state(hit_count: &State<HitCount>, config: &State<Config>) { /* .. */ }
If you request a `&State<T>` for a `T` that is not `managed`, Rocket will
refuse to start your application. This prevents what would have been an
unmanaged state runtime error. Unmanaged state is detected at runtime through
[_sentinels_](@api/rocket/trait.Sentinel.html), so there are limitations. If a
[_sentinels_](@api/master/rocket/trait.Sentinel.html), so there are limitations. If a
limitation is hit, Rocket still won't call the offending route. Instead,
Rocket will log an error message and return a **500** error to the client.
You can find a complete example using the `HitCount` structure in the [state
example on GitHub](@example/state) and learn more about the [`manage`
method](@api/rocket/struct.Rocket.html#method.manage) and [`State`
type](@api/rocket/struct.State.html) in the API docs.
example on GitHub](@git/master/examples/state) and learn more about the [`manage`
method](@api/master/rocket/struct.Rocket.html#method.manage) and [`State`
type](@api/master/rocket/struct.State.html) in the API docs.
### Within Guards
@ -148,8 +153,8 @@ impl<'r> FromRequest<'r> for Item<'r> {
}
```
[`Request::guard()`]: @api/rocket/struct.Request.html#method.guard
[`Rocket::state()`]: @api/rocket/struct.Rocket.html#method.state
[`Request::guard()`]: @api/master/rocket/struct.Request.html#method.guard
[`Rocket::state()`]: @api/master/rocket/struct.Rocket.html#method.state
## Request-Local State
@ -211,8 +216,8 @@ which uses request-local state to cache expensive authentication and
authorization computations, and the [`Fairing`] documentation, which uses
request-local state to implement request timing.
[`FromRequest` request-local state]: @api/rocket/request/trait.FromRequest.html#request-local-state
[`Fairing`]: @api/rocket/fairing/trait.Fairing.html#request-local-state
[`FromRequest` request-local state]: @api/master/rocket/request/trait.FromRequest.html#request-local-state
[`Fairing`]: @api/master/rocket/fairing/trait.Fairing.html#request-local-state
## Databases
@ -220,7 +225,7 @@ Rocket includes built-in, ORM-agnostic support for databases via
[`rocket_db_pools`]. The library simplifies accessing one or more databases via
connection pools: data structures that maintain active database connections for
use in the application. Database configuration occurs via Rocket's regular
[configuration](../configuration) mechanisms.
[configuration](../configuration/) mechanisms.
Connecting your Rocket application to a database using `rocket_db_pools` happens
in three simple steps:
@ -277,13 +282,13 @@ in three simple steps:
For complete usage details, see [`rocket_db_pools`].
[`rocket_db_pools`]: @api/rocket_db_pools/index.html
[supported database driver list]: @api/rocket_db_pools/index.html#supported-drivers
[database driver features]: @api/rocket_db_pools/index.html#supported-drivers
[`Pool`]: @api/rocket_db_pools/index.html#supported-drivers
[Configure]: @api/rocket_db_pools/index.html#configuration
[Derive `Database`]: @api/rocket_db_pools/derive.Database.html
[`Connection<$Type>`]: @api/rocket_db_pools/struct.Connection.html
[`rocket_db_pools`]: @api/master/rocket_db_pools/index.html
[supported database driver list]: @api/master/rocket_db_pools/index.html#supported-drivers
[database driver features]: @api/master/rocket_db_pools/index.html#supported-drivers
[`Pool`]: @api/master/rocket_db_pools/index.html#supported-drivers
[Configure]: @api/master/rocket_db_pools/index.html#configuration
[Derive `Database`]: @api/master/rocket_db_pools/derive.Database.html
[`Connection<$Type>`]: @api/master/rocket_db_pools/struct.Connection.html
### Driver Features
@ -311,13 +316,13 @@ ORMs like [Diesel] via the [`rocket_sync_db_pools`] library, which you may wish
to explore. Usage is similar, but not identical, to `rocket_db_pools`. See the
crate docs for complete usage details.
[`rocket_sync_db_pools`]: @api/rocket_sync_db_pools/index.html
[`rocket_sync_db_pools`]: @api/master/rocket_sync_db_pools/index.html
[diesel]: https://diesel.rs/
### Examples
For examples of CRUD-like "blog" JSON APIs backed by a SQLite database driven by
each of `sqlx`, `diesel`, and `rusqlite`, with migrations run automatically for
the former two drivers, see the [databases example](@example/databases). The
the former two drivers, see the [databases example](@git/master/examples/databases). The
`sqlx` example uses `rocket_db_pools` while the `diesel` and `rusqlite` examples
use `rocket_sync_db_pools`.

View File

@ -1,3 +1,7 @@
+++
summary = "Rocket's structured middleware"
+++
# Fairings
Fairings are Rocket's approach to structured middleware. With fairings, your
@ -36,7 +40,7 @@ that can be used to solve problems in a clean, composable, and robust manner.
fairing to record timing and usage statistics or to enforce global security
policies.
[`Fairing`]: @api/rocket/fairing/trait.Fairing.html
[`Fairing`]: @api/master/rocket/fairing/trait.Fairing.html
[request guard]: ../requests/#request-guards
[request guards]: ../requests/#request-guards
[data guards]: ../requests/#body-data
@ -66,9 +70,9 @@ attached any number of times. Except for [singleton fairings], all attached
instances are polled at runtime. Fairing callbacks may not be commutative; the
order in which fairings are attached may be significant.
[singleton fairings]: @api/rocket/fairing/trait.Fairing.html#singletons
[`attach`]: @api/rocket/struct.Rocket.html#method.attach
[`Rocket`]: @api/rocket/struct.Rocket.html
[singleton fairings]: @api/master/rocket/fairing/trait.Fairing.html#singletons
[`attach`]: @api/master/rocket/struct.Rocket.html#method.attach
[`Rocket`]: @api/master/rocket/struct.Rocket.html
### Callbacks
@ -114,8 +118,8 @@ events is briefly described below and in details in the [`Fairing`] trait docs:
requests. All registered shutdown fairings are run concurrently; resolution
of all fairings is awaited before resuming shutdown.
[ignition]: @api/rocket/struct.Rocket.html#method.ignite
[shutdown is triggered]: @api/rocket/config/struct.Shutdown.html#triggers
[ignition]: @api/master/rocket/struct.Rocket.html#method.ignite
[shutdown is triggered]: @api/master/rocket/config/struct.Shutdown.html#triggers
## Implementing
@ -127,13 +131,13 @@ fairing and determine the set of callbacks the fairing is registering for. A
[`on_liftoff`], [`on_request`], [`on_response`], and [`on_shutdown`]. Each
callback has a default implementation that does absolutely nothing.
[`Info`]: @api/rocket/fairing/struct.Info.html
[`info`]: @api/rocket/fairing/trait.Fairing.html#tymethod.info
[`on_ignite`]: @api/rocket/fairing/trait.Fairing.html#method.on_ignite
[`on_liftoff`]: @api/rocket/fairing/trait.Fairing.html#method.on_liftoff
[`on_request`]: @api/rocket/fairing/trait.Fairing.html#method.on_request
[`on_response`]: @api/rocket/fairing/trait.Fairing.html#method.on_response
[`on_shutdown`]: @api/rocket/fairing/trait.Fairing.html#method.on_shutdown
[`Info`]: @api/master/rocket/fairing/struct.Info.html
[`info`]: @api/master/rocket/fairing/trait.Fairing.html#tymethod.info
[`on_ignite`]: @api/master/rocket/fairing/trait.Fairing.html#method.on_ignite
[`on_liftoff`]: @api/master/rocket/fairing/trait.Fairing.html#method.on_liftoff
[`on_request`]: @api/master/rocket/fairing/trait.Fairing.html#method.on_request
[`on_response`]: @api/master/rocket/fairing/trait.Fairing.html#method.on_response
[`on_shutdown`]: @api/master/rocket/fairing/trait.Fairing.html#method.on_shutdown
### Requirements
@ -210,7 +214,7 @@ impl Fairing for Counter {
```
The complete example can be found in the [`Fairing`
documentation](@api/rocket/fairing/trait.Fairing.html#example).
documentation](@api/master/rocket/fairing/trait.Fairing.html#example).
## Ad-Hoc Fairings
@ -241,4 +245,4 @@ rocket::build()
})));
```
[`AdHoc`]: @api/rocket/fairing/struct.AdHoc.html
[`AdHoc`]: @api/master/rocket/fairing/struct.AdHoc.html

View File

@ -1,3 +1,7 @@
+++
summary = "unit and integration testing with the built-in testing library"
+++
# Testing
Every application should be well tested and understandable. Rocket provides the
@ -49,10 +53,10 @@ instance. Usage is straightforward:
# let _ = response;
```
[`local`]: @api/rocket/local/
[`Client`]: @api/rocket/local/#client
[`LocalRequest`]: @api/rocket/local/#localrequest
[`Rocket`]: @api/rocket/struct.Rocket.html
[`local`]: @api/master/rocket/local/
[`Client`]: @api/master/rocket/local/#client
[`LocalRequest`]: @api/master/rocket/local/#localrequest
[`Rocket`]: @api/master/rocket/struct.Rocket.html
## Validating Responses
@ -72,14 +76,14 @@ a few below:
* [`into_json`]: deserializes the body data on-the-fly as JSON.
* [`into_msgpack`]: deserializes the body data on-the-fly as MessagePack.
[`LocalResponse`]: @api/rocket/local/blocking/struct.LocalResponse.html
[`status`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.status
[`content_type`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.content_type
[`headers`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.headers
[`into_string`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.into_string
[`into_bytes`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.into_bytes
[`into_json`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.into_json
[`into_msgpack`]: @api/rocket/local/blocking/struct.LocalResponse.html#method.into_msgpack
[`LocalResponse`]: @api/master/rocket/local/blocking/struct.LocalResponse.html
[`status`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.status
[`content_type`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.content_type
[`headers`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.headers
[`into_string`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.into_string
[`into_bytes`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.into_bytes
[`into_json`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.into_json
[`into_msgpack`]: @api/master/rocket/local/blocking/struct.LocalResponse.html#method.into_msgpack
These methods are typically used in combination with the `assert_eq!` or
`assert!` macros as follows:
@ -271,7 +275,7 @@ mod test {
```
The tests can be run with `cargo test`. You can find the full source code to
[this example on GitHub](@example/testing).
[this example on GitHub](@git/master/examples/testing).
## Asynchronous Testing
@ -285,9 +289,9 @@ capable of dispatching multiple requests simultaneously. While synthetic, the
a case. For more information, see the [`rocket::local`] and
[`rocket::local::asynchronous`] documentation.
[`rocket::local`]: @api/rocket/local/index.html
[`rocket::local::asynchronous`]: @api/rocket/local/asynchronous/index.html
[`async_required` `testing` example]: @example/testing/src/async_required.rs
[`rocket::local`]: @api/master/rocket/local/index.html
[`rocket::local::asynchronous`]: @api/master/rocket/local/asynchronous/index.html
[`async_required` `testing` example]: @git/master/examples/testing/src/async_required.rs
## Codegen Debug

View File

@ -1,3 +1,7 @@
+++
summary = "overview and customization of Rocket application configuration"
+++
# Configuration
Rocket's configuration system is flexible. Based on [Figment](@figment), it
@ -40,8 +44,8 @@ values:
<small>* Note: the `workers`, `max_blocking`, and `shutdown.force` configuration
parameters are only read from the [default provider](#default-provider).</small>
[client's real IP]: @api/rocket/request/struct.Request.html#method.real_ip
[client to proxy protocol]: @api/rocket/request/struct.Request.html#method.proxy_proto
[client's real IP]: @api/master/rocket/request/struct.Request.html#method.real_ip
[client to proxy protocol]: @api/master/rocket/request/struct.Request.html#method.proxy_proto
### Profiles
@ -61,20 +65,20 @@ profile supplant any values with the same name in any profile.
[`Provider`]: @figment/trait.Provider.html
[`Profile`]: @figment/struct.Profile.html
[`Config`]: @api/rocket/struct.Config.html
[`Config::figment()`]: @api/rocket/struct.Config.html#method.figment
[`Config`]: @api/master/rocket/struct.Config.html
[`Config::figment()`]: @api/master/rocket/struct.Config.html#method.figment
[`Toml`]: @figment/providers/struct.Toml.html
[`Json`]: @figment/providers/struct.Json.html
[`Figment`]: @figment/struct.Figment.html
[`Deserialize`]: @api/rocket/serde/trait.Deserialize.html
[`LogLevel`]: @api/rocket/config/enum.LogLevel.html
[`Limits`]: @api/rocket/data/struct.Limits.html
[`Limits::default()`]: @api/rocket/data/struct.Limits.html#impl-Default
[`SecretKey`]: @api/rocket/config/struct.SecretKey.html
[`CliColors`]: @api/rocket/config/enum.CliColors.html
[`TlsConfig`]: @api/rocket/config/struct.TlsConfig.html
[`Shutdown`]: @api/rocket/config/struct.Shutdown.html
[`Shutdown::default()`]: @api/rocket/config/struct.Shutdown.html#fields
[`Deserialize`]: @api/master/rocket/serde/trait.Deserialize.html
[`LogLevel`]: @api/master/rocket/config/enum.LogLevel.html
[`Limits`]: @api/master/rocket/data/struct.Limits.html
[`Limits::default()`]: @api/master/rocket/data/struct.Limits.html#impl-Default-for-Limits
[`SecretKey`]: @api/master/rocket/config/struct.SecretKey.html
[`CliColors`]: @api/master/rocket/config/enum.CliColors.html
[`TlsConfig`]: @api/master/rocket/tls/struct.TlsConfig.html
[`Shutdown`]: @api/master/rocket/config/struct.Shutdown.html
[`Shutdown::default()`]: @api/master/rocket/config/struct.Shutdown.html#fields
## Default Provider
@ -99,7 +103,7 @@ As a result of `Config::figment()`, without any effort, Rocket can be configured
via a `Rocket.toml` file and/or via environment variables, the latter of which
take precedence over the former.
[`Config::default()`]: @api/rocket/struct.Config.html#method.default
[`Config::default()`]: @api/master/rocket/struct.Config.html#method.default
### Rocket.toml
@ -231,7 +235,7 @@ bytes Rocket should accept for that type. Rocket can parse both integers
By default, Rocket specifies a `32 KiB` limit for incoming forms. Since Rocket
requires specifying a read limit whenever data is read, external data guards may
also choose to have a configure limit via the `limits` parameter. The
[`Json`](@api/rocket/serde/json/struct.Json.html) type, for instance, uses the
[`Json`](@api/master/rocket/serde/json/struct.Json.html) type, for instance, uses the
`limits.json` parameter.
### TLS
@ -267,8 +271,8 @@ The `tls` parameter is expected to be a dictionary that deserializes into a
| `prefer_server_cipher_order` | no | Boolean for whether to [prefer server cipher suites]. |
| `mutual` | no | A map with [mutual TLS] configuration. |
[`CipherSuite`]: @api/rocket/config/enum.CipherSuite.html
[prefer server cipher suites]: @api/rocket/config/struct.TlsConfig.html#method.with_preferred_server_cipher_order
[`CipherSuite`]: @api/master/rocket/tls/enum.CipherSuite.html
[prefer server cipher suites]: @api/master/rocket/tls/struct.TlsConfig.html#method.with_preferred_server_cipher_order
[mutual TLS]: #mutual-tls
When specified via TOML or other serialized formats, each [`CipherSuite`] is
@ -331,8 +335,8 @@ The `tls.mutual` parameter is expected to be a dictionary that deserializes into
| `ca_certs` | **_yes_** | Path or bytes to DER-encoded X.509 TLS cert chain. |
| `mandatory` | no | Boolean controlling whether the client _must_ authenticate. |
[`MutualTls`]: @api/rocket/config/struct.MutualTls.html
[`mtls`]: @api/rocket/mtls/index.html
[`MtlsConfig`]: @api/master/rocket/mtls/struct.MtlsConfig.html
[`mtls`]: @api/master/rocket/mtls/index.html
Rocket reports if TLS and/or mTLS are enabled at launch time:
@ -355,13 +359,14 @@ fn auth(cert: Certificate<'_>) {
}
```
The [TLS example](@example/tls) illustrates a fully configured TLS server with
The [TLS example](@git/master/examples/tls) illustrates a fully configured TLS server with
mutual TLS.
! warning: Rocket's built-in TLS supports only TLS 1.2 and 1.3. This may not be
suitable for production use.
! warning: Rocket's built-in TLS supports only TLS 1.2 and 1.3.
[`mtls::Certificate`]: @api/rocket/mtls/struct.Certificate.html
This may not be suitable for production use requiring legacy support.
[`mtls::Certificate`]: @api/master/rocket/mtls/struct.Certificate.html
### Proxied TLS
@ -385,10 +390,10 @@ via a TOML file:
proxy_proto_header = "X-Forwarded-Proto"
```
[`Request::proxy_proto()`]: @api/rocket/request/struct.Request.html#method.proxy_proto
[`ProxyProto`]: @api/rocket/http/enum.ProxyProto.html
[`CookieJar`]: @api/rocket/http/struct.CookieJar.html
[`Request::context_is_likely_secure()`]: @api/rocket/request/struct.Request.html#method.context_is_likely_secure
[`Request::proxy_proto()`]: @api/master/rocket/request/struct.Request.html#method.proxy_proto
[`ProxyProto`]: @api/master/rocket/http/enum.ProxyProto.html
[`CookieJar`]: @api/master/rocket/http/struct.CookieJar.html
[`Request::context_is_likely_secure()`]: @api/master/rocket/request/struct.Request.html#method.context_is_likely_secure
### Workers
@ -412,8 +417,8 @@ required such as when performing file system I/O via [`TempFile`] or wrapping
synchronous work via [`rocket_sync_db_pools`].
[`spawn_blocking`]: @tokio/task/fn.spawn_blocking.html
[`TempFile`]: @api/rocket/fs/enum.TempFile.html
[`rocket_sync_db_pools`]: @api/rocket_sync_db_pools/index.html
[`TempFile`]: @api/master/rocket/fs/enum.TempFile.html
[`rocket_sync_db_pools`]: @api/master/rocket_sync_db_pools/index.html
## Extracting Values
@ -481,7 +486,7 @@ fn rocket() -> _ {
}
```
[`Rocket::figment()`]: @api/rocket/struct.Rocket.html#method.figment
[`Rocket::figment()`]: @api/master/rocket/struct.Rocket.html#method.figment
## Custom Providers
@ -567,5 +572,5 @@ that if values like `port` and `address` are configured in `Config`, `App.toml`
or `APP_` environment variables, Rocket will make use of them. The application
can also extract its configuration, done here via the `Adhoc::config()` fairing.
[`rocket::custom()`]: @api/rocket/fn.custom.html
[`rocket::build()`]: @api/rocket/fn.custom.html
[`rocket::custom()`]: @api/master/rocket/fn.custom.html
[`rocket::build()`]: @api/master/rocket/fn.custom.html

View File

@ -1,3 +1,7 @@
+++
summary = "step-by-step guide to creating a pastebin with Rocket"
+++
# Pastebin Tutorial
This section of the guide is a tutorial intended to demonstrate how real-world
@ -109,9 +113,9 @@ string with the specified contents. Rocket will take the string and return it as
the body of a fully formed HTTP response with `Content-Type: text/plain`. You
can read more about how Rocket formulates responses in the [responses section]
of the guide or at the [API documentation for the Responder
trait](@api/rocket/response/trait.Responder.html).
trait](@api/master/rocket/response/trait.Responder.html).
[responses section]: ../responses
[responses section]: ../responses/
Remember that routes first need to be mounted before Rocket dispatches requests
to them. To mount the `index` route, modify the main function so that it reads:
@ -249,7 +253,7 @@ Here's a first take at implementing the `retrieve` route. The route below takes
in an `<id>` as a dynamic path element. The handler uses the `id` to construct a
path to the paste inside `upload/`, and then attempts to open the file at that
path, optionally returning the `File` if it exists. Rocket treats a `None`
[Responder](@api/rocket/response/trait.Responder.html#provided-implementations)
[Responder](@api/master/rocket/response/trait.Responder.html#provided-implementations)
as a **404** error, which is exactly what we want to return when the requested
paste doesn't exist.
@ -297,8 +301,9 @@ opened. For instance, imagine that you later decide that a special file
user issues a `GET` request to `/_credentials.txt`, the server will read and
return the `upload/_credentials.txt` file, leaking the sensitive information.
This is a big problem; it's known as the [full path disclosure
attack](https://www.owasp.org/index.php/Full_Path_Disclosure), and Rocket
provides the tools to prevent this and other kinds of attacks from happening.
attack](https://owasp.org/www-community/attacks/Full_Path_Disclosure), and
Rocket provides the tools to prevent this and other kinds of attacks from
happening.
### The Solution
@ -315,7 +320,7 @@ paste IDs, `PasteId`, so we'll simply need to implement `FromParam` for
Here's the `FromParam` implementation for `PasteId` in `src/paste_id.rs`:
[`FromParam`]: @api/rocket/request/trait.FromParam.html
[`FromParam`]: @api/master/rocket/request/trait.FromParam.html
```rust
use rocket::request::FromParam;
@ -404,7 +409,7 @@ async fn upload(paste: Data<'_>) -> std::io::Result<String> {
}
```
[`Data`]: @api/rocket/data/struct.Data.html
[`Data`]: @api/master/rocket/data/struct.Data.html
[data guard]: ../requests/#body-data
Your code should:
@ -467,14 +472,14 @@ We note the following Rocket APIs being used in our implementation:
* The [`UriDisplayPath`] derive, allowing `PasteId` to be used in [`uri!`].
* The [`uri!`] macro to crate type-safe, URL-safe URIs.
[`Data::open()`]: @api/rocket/data/struct.Data.html#method.open
[`Data`]: @api/rocket/data/struct.Data.html
[`DataStream`]: @api/rocket/data/struct.DataStream.html
[`DataStream::into_file()`]: @api/rocket/data/struct.DataStream.html#method.into_file
[`uri!`]: @api/rocket/macro.uri.html
[`kibibytes()`]: @api/rocket/data/trait.ToByteUnit.html#tymethod.kibibytes
[`ToByteUnit`]: @api/rocket/data/trait.ToByteUnit.html
[`UriDisplayPath`]: @api/rocket/derive.UriDisplayPath.html
[`Data::open()`]: @api/master/rocket/data/struct.Data.html#method.open
[`Data`]: @api/master/rocket/data/struct.Data.html
[`DataStream`]: @api/master/rocket/data/enum.DataStream.html
[`DataStream::into_file()`]: @api/master/rocket/data/enum.DataStream.html#method.into_file
[`uri!`]: @api/master/rocket/macro.uri.html
[`kibibytes()`]: @api/master/rocket/data/trait.ToByteUnit.html#method.kibibytes
[`ToByteUnit`]: @api/master/rocket/data/trait.ToByteUnit.html
[`UriDisplayPath`]: @api/master/rocket/derive.UriDisplayPath.html
Ensure that the route is mounted at the root path:
@ -536,10 +541,10 @@ through some of them to get a better feel for Rocket. Here are some ideas:
* Add a new route, `GET /<id>/<lang>` that syntax highlights the paste with ID
`<id>` for language `<lang>`. If `<lang>` is not a known language, do no
highlighting. Possibly validate `<lang>` with `FromParam`.
* Use the [`local` module](@api/rocket/local/) to write unit tests for your
* Use the [`local` module](@api/master/rocket/local/) to write unit tests for your
pastebin.
* Dispatch a thread before `launch`ing Rocket in `main` that periodically
cleans up idling old pastes in `upload/`.
You can find the full source code for the [completed pastebin tutorial on
GitHub](@example/pastebin).
GitHub](@git/master/examples/pastebin).

View File

@ -0,0 +1,25 @@
+++
summary = "next steps, and learning more about Rocket"
+++
# Conclusion
We hope you agree that Rocket is a refreshing take on web frameworks. As with
any software project, Rocket is _alive_. There are always things to improve, and
we're happy to take the best ideas. If you have something in mind, please
[submit an issue](https://github.com/rwf2/Rocket/issues).
## Getting Help
If you find yourself having trouble developing Rocket applications, you can get
help via chat at [`#rocket:mozilla.org`] on Matrix. The [FAQ](../faq/) also
provides answers to commonly asked questions.
[`#rocket:mozilla.org`]: @chat
## What's next?
The best way to learn Rocket is to _build something_. It should be fun and easy,
and there's always someone to help. Alternatively, you can read through the
[Rocket examples](@git/master/examples) or the [Rocket source code](@git/master/core/lib/src).
Whatever you decide to do next, we hope you have a blast!

View File

@ -1,3 +1,23 @@
+++
summary = "answers to frequently asked questions about Rocket and its usage"
+++
{% macro faq(id) %}
<details id="{{ id }}">
<summary>
<a class="anchor" href="#{{ id }}" title="anchor">#</a>
{% endmacro %}
{% macro answer() %}
</summary>
<div class="content">
{% endmacro %}
{% macro endfaq() %}
</div>
</details>
{% endmacro %}
# FAQ
Below you'll find a collection of commonly asked questions and answers. If you
@ -8,12 +28,9 @@ discussion thread].
## About Rocket
<details id="monolithic">
<summary>
{{ faq("monolithic") }}
Is Rocket a monolithic framework like Rails? Or is it more like Flask?
<a class="headerlink" href="#monolithic" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Neither!
@ -38,13 +55,13 @@ Unlike other frameworks, Rocket makes it its mission to help you avoid security
and correctness blunders. It does this by including, out-of-the-box:
* A flexible, type-based [configuration](../configuration/) system.
* [Security and privacy headers](@api/rocket/shield/) by default.
* Zero-Copy RFC compliant [URI parsers](@api/rocket/http/uri).
* Safe, [typed URIs](@api/rocket/macro.uri.html) with compile-time checking.
* [Compile-time and launch-time route checking](@api/rocket/attr.route.html).
* A [testing framework](@api/rocket/local) with sync and `async` variants.
* [Security and privacy headers](@api/master/rocket/shield/) by default.
* Zero-Copy RFC compliant [URI parsers](@api/master/rocket/http/uri).
* Safe, [typed URIs](@api/master/rocket/macro.uri.html) with compile-time checking.
* [Compile-time and launch-time route checking](@api/master/rocket/attr.route.html).
* A [testing framework](@api/master/rocket/local) with sync and `async` variants.
* Safe, exclusive access to fully decoded HTTP values.
* Mandatory [data limits](@api/rocket/data/struct.Limits.html) to prevent
* Mandatory [data limits](@api/master/rocket/data/struct.Limits.html) to prevent
trivial DoS attacks.
Of course, this functionality comes at a compile-time cost (but notably, _not_
@ -66,40 +83,26 @@ time can be further reduced by using faster linkers like `lld`. We think the
trade-off is worth it. Rocket will never compromise security, correctness, or
usability to "win" at benchmarks of any sort.
</div>
</details>
[`rocket_dyn_templates`]: @api/master/rocket_dyn_templates/
[`rocket_db_pools`]: @api/master/rocket_db_pools/
{{ endfaq() }}
[`rocket_dyn_templates`]: @api/rocket_dyn_templates
[`rocket_db_pools`]: @api/rocket_db_pools
<details id="compact">
<summary>
{{ faq("compact") }}
I want a small and compact web framework. Is Rocket it?
<a class="headerlink" href="#compact" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
We think so! See ["Is Rocket a monolithic framework like Rails?"](#monolithic)
</div>
</details>
{{ endfaq() }}
<details id="complete">
<summary>
{{ faq("complete") }}
I want a web framework with all the bells and whistles. Is Rocket it?
<a class="headerlink" href="#complete" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
We think so! See ["Is Rocket a monolithic framework like Rails?"](#monolithic)
</div>
</details>
{{ endfaq() }}
<details id="in-prod">
<summary>
{{ faq("in-prod") }}
Can I use Rocket in production? Should I? It's only v0.x!
<a class="headerlink" href="#in-prod" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
We **enthusiastically** recommend using Rocket in production, with the following
non-exhaustive list of caveats:
@ -137,15 +140,11 @@ Furthermore, we backport _all_ security and correctness patches to the previous
major release (`0.{x-1}.y`), so your application remains secure if you need time
to upgrade.
</div>
</details>
{{ endfaq() }}
<details id="performance">
<summary>
{{ faq("performance") }}
Is Rocket slow? Is Rocket fast?
<a class="headerlink" href="#performance" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Rocket is pretty fast.
@ -184,18 +183,13 @@ zero-copy parsing and deserialization.
<small>* A common mistake is to pit against Rocket's "Hello, world!" without
normalizing for response size, especially security headers.</small>
</div>
</details>
[managed state]: ../state/#managed-state
[request-local state]: ../state/#request-local-state
{{ endfaq() }}
<details id="showcase">
<summary>
{{ faq("showcase") }}
What are some examples of "big" apps written in Rocket?
<a class="headerlink" href="#showcase" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Here are some notable projects and websites in Rocket we're aware of:
@ -213,20 +207,16 @@ you'd like to see here!
[Conduit]: https://conduit.rs/
[Rust-Lang.org]: https://www.rust-lang.org/
[Plume]: https://github.com/Plume-org/Plume
[Hagrid]: https://gitlab.com/hagrid-keyserver/hagrid/
[Hagrid]: https://gitlab.com/keys.openpgp.org/hagrid
[SourceGraph Syntax Highlighter]: https://github.com/sourcegraph/sourcegraph/tree/main/docker-images/syntax-highlighter
[Let us know]: https://github.com/rwf2/Rocket/discussions/categories/show-and-tell
[Revolt]: https://github.com/revoltchat/backend
{{ endfaq() }}
</div>
</details>
<details id="releases">
<summary>
{{ faq("releases") }}
When will version `$y` be released? Why does it take so long?
<a class="headerlink" href="#releases" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Rocket represents an ecosystem-wide effort to create a web framework that
enables writing web applications with unparalleled security, performance, and
@ -242,14 +232,14 @@ For example, work for Rocket v0.5 included:
* [Reporting multiple](https://github.com/bikeshedder/deadpool/issues/114)
[correctness issues](https://github.com/bikeshedder/deadpool/issues/113) in `deadpool`.
* [Fixing a major usability issue in `async-stream`.](https://github.com/tokio-rs/async-stream/pull/57)
* [Creating a brand new configuration library.](https://github.com/rwf2/Figment)
* [Creating a brand new configuration library.](https://github.com/SergioBenitez/Figment)
* [Updating](https://github.com/rousan/multer-rs/pull/21),
[fixing](https://github.com/rousan/multer-rs/pull/29), and
[maintaining](https://github.com/rousan/multer-rs/commit/2758e778e6aa2785b737c82fe45e58026bea2f01) `multer`.
* [Significantly improving `async_trait` correctness and usability.](https://github.com/dtolnay/async-trait/pull/143)
* [Porting `Pattern` APIs to stable.](https://github.com/rwf2/stable-pattern)
* [Porting macro diagnostics to stable.](https://github.com/rwf2/proc-macro2-diagnostics)
* [Creating a brand new byte unit library.](https://github.com/rwf2/ubyte)
* [Porting `Pattern` APIs to stable.](https://github.com/SergioBenitez/stable-pattern)
* [Porting macro diagnostics to stable.](https://github.com/SergioBenitez/proc-macro2-diagnostics)
* [Creating a brand new byte unit library.](https://github.com/SergioBenitez/ubyte)
* [Fixing a bug in `rustc`'s `libtest`.](https://github.com/rust-lang/rust/pull/78227)
A version of Rocket is released whenever it is feature-complete and exceeds
@ -259,21 +249,17 @@ a release if these properties are not readily evident.
We know it can be frustrating, but we hope you'll agree that Rocket is worth the
wait.
</div>
</details>
{{ endfaq() }}
## How To
<details id="web-sockets">
<summary>
{{ faq("web-sockets") }}
Can I, and if so how, do I use WebSockets?
<a class="headerlink" href="#web-sockets" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
You can! WebSocket support is provided by the officially maintained
[`rocket_ws`](@api/rocket_ws) crate. You'll find all the docs you need there.
[`rocket_ws`](@api/master/rocket_ws/) crate. You'll find all the docs you need
there.
Rocket _also_ supports [Server-Sent Events], which allows for real-time
_unidirectional_ communication from the server to the client. The protocol is a
@ -281,19 +267,20 @@ bit simpler, and you may find SSE sufficient for your use-case. For instance,
the [chat example] uses SSE to implement a real-time, multiroom chat
application.
</div>
</details>
That being said, Rocket _does_ suport [Server-Sent Events], which allows for
real-time _unidirectional_ communication from the server to the client. This is
often sufficient for many of the applications that WebSockets are typically used
for. For instance, the [chat example] uses SSE to implement a real-time,
multiroom chat application.
[working on it]: https://github.com/rwf2/Rocket/issues/90
[Server-Sent Events]: @api/rocket/response/stream/struct.EventStream.html
[chat example]: @example/chat
[Server-Sent Events]: @api/master/rocket/response/stream/struct.EventStream.html
[chat example]: @git/master/examples/chat
{{ endfaq() }}
<details id="global-state">
<summary>
{{ faq("global-state") }}
Should I use global state via something like `lazy_static!`?
<a class="headerlink" href="#global-state" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
No. Rocket's [managed state] provides a better alternative.
@ -305,17 +292,13 @@ numerous. They include:
state.
* The inability to know the state a route accesses by looking at its
signature.
</div>
</details>
[managed state]: ../state/#managed-state
{{ endfaq() }}
<details id="file-uploads">
<summary>
{{ faq("file-uploads") }}
How do I handle file uploads? What is this "multipart" in my stream?
<a class="headerlink" href="#file-uploads" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
For a quick example on how to handle file uploads, see [multipart forms]. The
gist is: use `Form<TempFile>` as a data guard.
@ -325,24 +308,20 @@ The raw stream, as seen by [`Data`] for example, thus contains the necessary
metadata to encode the form. Rocket's [`Form`] data guard can parse these form
submissions into any type that implements [`FromForm`]. This includes types like
[`TempFile`] which streams the decoded data to disk for persistence.
</div>
</details>
[multipart]: https://datatracker.ietf.org/doc/html/rfc7578
[multipart forms]: ../requests/#multipart
[`DataField`]: @api/rocket/form/struct.DataField.html
[`TempFile`]: @api/rocket/fs/enum.TempFile.html
[`DataField`]: @api/rocket/data/struct.Data.html
[`Form`]: @api/rocket/form/struct.Form.html
[`FromForm`]: @api/rocket/form/trait.FromForm.html
[`Data`]: @api/rocket/struct.Data.html
[`DataField`]: @api/master/rocket/form/struct.DataField.html
[`TempFile`]: @api/master/rocket/fs/enum.TempFile.html
[`DataField`]: @api/master/rocket/data/struct.Data.html
[`Form`]: @api/master/rocket/form/struct.Form.html
[`FromForm`]: @api/master/rocket/form/trait.FromForm.html
[`Data`]: @api/master/rocket/struct.Data.html
{{ endfaq() }}
<details id="raw-request">
<summary>
{{ faq("raw-request") }}
How do I get an `&Request` in a handler?
<a class="headerlink" href="#raw-request" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
You don't!
@ -364,22 +343,18 @@ out-of-the-box, and you can implement your own, too. See the following:
* Data Guards: [`FromData`]
* Form Guards: [`FromForm`]
* Request Guards: [`FromRequest`]
</div>
</details>
[philosophy]: ../introduction/#foreword
[`FromParam`]: @api/rocket/request/trait.FromParam.html
[`FromSegments`]: @api/rocket/request/trait.FromSegments.html
[`FromData`]: @api/rocket/data/trait.FromData.html
[`FromForm`]: @api/rocket/form/trait.FromForm.html
[`FromRequest`]: @api/rocket/request/trait.FromRequest.html
[`FromParam`]: @api/master/rocket/request/trait.FromParam.html
[`FromSegments`]: @api/master/rocket/request/trait.FromSegments.html
[`FromData`]: @api/master/rocket/data/trait.FromData.html
[`FromForm`]: @api/master/rocket/form/trait.FromForm.html
[`FromRequest`]: @api/master/rocket/request/trait.FromRequest.html
{{ endfaq() }}
<details id="response-headers">
<summary>
{{ faq("response-headers") }}
How do I add a header to a response?
<a class="headerlink" href="#response-headers" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
That depends on the header!
@ -404,7 +379,7 @@ details setting a custom `Content-Type` or overriding an existing one.
**Everything Else**
To add a custom header, you'll need a custom [`Responder`]. Not to worry!
[`Responder` can be derived](@api/rocket/derive.Responder.html) in almost all
[`Responder` can be derived](@api/master/rocket/derive.Responder.html) in almost all
cases. If a type for the header you want to add already exists, you can directly
derive `Responder` for a struct that contains the header value, which adds the
header to the response:
@ -461,21 +436,16 @@ impl<'r> Responder<'r, 'static> for Person {
}
```
</div>
</details>
[`Responder`]: @api/master/rocket/response/trait.Responder.html
[`content`]: @api/master/rocket/response/content/index.html
[`status`]: @api/master/rocket/response/status/index.html
[`Header`]: @api/master/rocket/http/struct.Header.html
[`Json`]: @api/master/rocket/serde/json/struct.Json.html
{{ endfaq() }}
[`Responder`]: @api/rocket/response/trait.Responder.html
[`content`]: @api/rocket/response/content/index.html
[`status`]: @api/rocket/response/status/index.html
[`Header`]: @api/rocket/http/struct.Header.html
[`Json`]: @api/rocket/serde/json/struct.Json.html
<details id="multiple-responses">
<summary>
{{ faq("multiple-responses") }}
How do I make one handler return different responses or status codes?
<a class="headerlink" href="#multiple-responses" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
If you're returning _two_ different responses, use a `Result<T, E>` or an
[`Either<A, B>`].
@ -498,18 +468,13 @@ enum Error<'r, T> {
}
```
</div>
</details>
[`Either<A, B>`]: https://docs.rs/either/1/either/enum.Either.html
[derive a custom `Responder`]: @api/rocket/derive.Responder.html
[derive a custom `Responder`]: @api/master/rocket/derive.Responder.html
{{ endfaq() }}
<details id="automatic-reload">
<summary>
{{ faq("automatic-reload") }}
How do I make Rocket reload automatically when I change source code?
<a class="headerlink" href="#automatic-reload" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
In debug mode, Rocket automatically reloads templates for you. So if all you
need is live template reloading, Rocket's got you covered.
@ -523,20 +488,16 @@ cargo watch -x run
```
To only restart on successful compilations, see [this note].
</div>
</details>
[`cargo-watch`]: https://github.com/watchexec/cargo-watch
[`watchexec`]: https://github.com/watchexec/watchexec
[`entr`]: http://eradman.com/entrproject/
[this note]: https://github.com/watchexec/cargo-watch/tree/b75ce2c260874dea480f4accfd46ab28709ec56a#restarting-an-application-only-if-the-buildcheck-succeeds
{{ endfaq() }}
<details id="external-managed-state">
<summary>
{{ faq("external-managed-state") }}
How do I access managed state outside of a Rocket-related context?
<a class="headerlink" href="#external-managed-state" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Use an `Arc`, like this:
@ -558,15 +519,11 @@ fn rocket() -> _ {
}
```
</div>
</details>
{{ endfaq() }}
<details id="internal-server">
<summary>
{{ faq("internal-server") }}
How do I make Rocket a _part_ of my application as opposed to the whole thing?
<a class="headerlink" href="#internal-server" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Use the `#[main]` attribute and manually call [`launch()`]:
@ -585,19 +542,14 @@ async fn main() {
The cost to using the attribute is imperceptible and guarantees compatibility
with Rocket's async I/O.
</div>
</details>
[`launch()`]: @api/rocket/struct.Rocket.html#method.launch
[`launch()`]: @api/master/rocket/struct.Rocket.html#method.launch
{{ endfaq() }}
## Debugging
<details id="broken-example">
<summary>
{{ faq("broken-example") }}
Is example `foo` broken? It doesn't work for me.
<a class="headerlink" href="#broken-example" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
Almost certainly not.
@ -612,27 +564,23 @@ Common mistakes when running examples include:
* Looking at outdated examples on StackOverflow or Google. Check the
date/version!
* Not configuring the correct dependencies. See the example's `Cargo.toml`!
</div>
</details>
{{ endfaq() }}
<details id="unsat-bound">
<summary>
{{ faq("unsat-bound") }}
The trait bound `rocket::Responder` (`FromRequest`, etc.) is not satisfied.
<a class="headerlink" href="#unsat-bound" title="permalink">#</a>
</summary>
<div class="content">
{{ answer() }}
If you're fairly certain a type implements a given Rocket trait but still get an
error like:
```rust,ignore
error[E0277]: the trait bound `Foo: Responder<'_, '_>` is not satisfied
--> src\main.rs:4:20
|
--> src\main.rs:4:20
|
4 | fn foo() -> Foo
| ^^^ the trait `Responder<'_, '_>` is not implemented for `Foo`
|
= note: required by `respond_to`
| ^^^ the trait `Responder<'_, '_>` is not implemented for `Foo`
|
= note: required by `respond_to`
```
...then you're almost certainly depending, perhaps transitively, on _two
@ -658,6 +606,4 @@ implement the trait from the other library (since it is considered to be a
_different_, _distinct_ library). In other words, you can _never_ mix two
different published versions of Rocket, a published version and a `git` version,
or two instances from different `git` revisions.
</div>
</details>
{{ endfaq() }}

25
docs/guide/index.md Normal file
View File

@ -0,0 +1,25 @@
# The Rocket Programming Guide
Welcome to Rocket!
This is the official guide for Rocket v0.6. It is designed to serve as a
starting point to writing web applications with Rocket and Rust. The guide is
also designed to be a reference for experienced Rocket developers. This guide is
conversational in tone. For purely technical documentation with examples, see
the [API documentation](@api/master/rocket).
The guide is split into several sections, each with a focus on a different
aspect of Rocket. The sections are:
================================================================================
## Getting Help
The official community support channels are via Matrix chat on
[`#rocket:mozilla.org`] and via [GitHub Discussions]. To join us on Matrix, we
recommend the browser-based [Element] client. The [FAQ](faq/) also provides
answers to commonly asked questions.
[`#rocket:mozilla.org`]: @chat
[GitHub Discussions]: https://github.com/rwf2/Rocket/discussions
[Element]: https://chat.mozilla.org/#/room/#rocket:mozilla.org

View File

@ -1,5 +1,5 @@
[package]
name = "rocket_guide_tests"
name = "rocket_docs_tests"
version = "0.6.0-dev"
workspace = "../../"
edition = "2021"
@ -10,8 +10,9 @@ rocket = { path = "../../core/lib", features = ["secrets"] }
[dev-dependencies]
rocket = { path = "../../core/lib", features = ["secrets", "json", "mtls"] }
rand = "0.8"
figment = { version = "0.10", features = ["toml", "env"] }
tokio = { version = "1", features = ["macros", "io-std"] }
rand = "0.8"
[dev-dependencies.rocket_dyn_templates]
path = "../../contrib/dyn_templates"

1
docs/tests/src/guide.rs Normal file
View File

@ -0,0 +1 @@
rocket::internal_guide_tests!("../guide/*.md");

View File

@ -1,5 +1,5 @@
#[cfg(any(test, doctest))] rocket::internal_guide_tests!("../guide/*.md");
#[cfg(any(test, doctest))] rocket::internal_guide_tests!("../../README.md");
#[cfg(any(test, doctest))] mod guide;
#[cfg(any(test, doctest))] mod readme;
#[macro_export]
macro_rules! map {

1
docs/tests/src/readme.rs Normal file
View File

@ -0,0 +1 @@
rocket::internal_guide_tests!("../../README.md");

View File

@ -35,10 +35,8 @@ popd > /dev/null 2>&1
echo ":::: Generating redirects..."
REDIRECTS="
/ /v0.5/rocket/ 302!
/v0.4 https://docs.rs/rocket/0.4/rocket/
/v0.4/:crate/* https://docs.rs/:crate/0.4/:crate/:splat
/rocket/ /v0.5/rocket/ 302!
/:v /:v/rocket/
/v0.5/* https://v0-5--rocket-docs.netlify.app/:splat 200
/:v/* https://:v--rocket-docs.netlify.app/:splat 200
"

View File

@ -1,46 +0,0 @@
# Rocket Website Source
This directory contains the source files for the content on [Rocket's
website](https://rocket.rs).
## Contents
This directory contains the following:
* `index.toml` - Source data for the index.
* `overview.toml` - Source data for the overview page (`overview/`).
* `news/index.toml` - Source data for the news page (`news/`).
* `news/*.md` - News articles linked to from `news/index.toml`.
* `guide/*.md` - Guide pages linked to from `guide.md`.
[Rocket Programming Guide]: https://rocket.rs/master/guide/
### Guide Links
Cross-linking guide pages is accomplished via relative links. Outside of the
index, this is: `../{page}#anchor`. For instance, to link to the **Quickstart >
Running Examples** page, use `../quickstart#running-examples`.
### Aliases
Aliases are shorthand URLs that start with `@` (e.g, `@api`). They are used
throughout the guide to simplify versioning URLs to Rocket's source code and the
Rocket API. They are replaced at build time with a URL prefix. At present, the
following aliases are available, where `${version}` is Rocket's version string
at the time of compilation:
* `@example`: https://github.com/rwf2/Rocket/tree/${version}/examples
* `@github`: https://github.com/rwf2/Rocket/tree/${version}
* `@api`: https://api.rocket.rs/${version}
For example, to link to `Rocket::launch()`, you might write:
```md
Launch an instance of your application using the [`launch()`] method.
[`launch()`]: @api/rocket/struct.Rocket.html#method.launch
```
## License
The Rocket website source is licensed under the [GNU General Public License v3.0](LICENSE).

View File

@ -1,14 +0,0 @@
# Upgrading
This a placeholder for an eventual migration guide from v0.5 to v0.6.
## Getting Help
If you run into any issues upgrading, we encourage you to ask questions via
[GitHub discussions] or via chat at [`#rocket:mozilla.org`] on Matrix or the
bridged [`#rocket`] IRC channel at `irc.libera.chat`. The [FAQ](../faq/) also
provides answers to commonly asked questions.
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket

View File

@ -1,27 +0,0 @@
# Conclusion
We hope you agree that Rocket is a refreshing take on web frameworks. As with
any software project, Rocket is _alive_. There are always things to improve, and
we're happy to take the best ideas. If you have something in mind, please
[submit an issue](https://github.com/rwf2/Rocket/issues).
## Getting Help
If you find yourself having trouble developing Rocket applications, you can get
help via chat at [`#rocket:mozilla.org`] on Matrix or the bridged [`#rocket`]
IRC channel on Libera.Chat at `irc.libera.chat`. We recommend joining us on
[Matrix via Element]. If you prefer IRC, you can join via the [Kiwi IRC client]
or a client of your own. The [FAQ](../faq/) also provides answers to commonly
asked questions.
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket
[Matrix via Element]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[Kiwi IRC Client]: https://kiwiirc.com/client/irc.libera.chat/#rocket
## What's next?
The best way to learn Rocket is to _build something_. It should be fun and easy,
and there's always someone to help. Alternatively, you can read through the
[Rocket examples](@example) or the [Rocket source code](@github/core/lib/src).
Whatever you decide to do next, we hope you have a blast!

View File

@ -1,46 +0,0 @@
# The Rocket Programming Guide
Welcome to Rocket!
This is the official guide for Rocket master. It is designed to serve as a
starting point to writing web applications with Rocket and Rust. The guide is
also designed to be a reference for experienced Rocket developers. This guide is
conversational in tone. For purely technical documentation with examples, see
the [API documentation](@api).
The guide is split into several sections, each with a focus on a different
aspect of Rocket. The sections are:
- **[Introduction](introduction/):** introduces Rocket and its philosophy.
- **[Quickstart](quickstart/):** presents the minimal steps necessary to
run your first Rocket application.
- **[Upgrading from v0.5](upgrading/):** a migration guide from v0.5 to v0.6.
- **[Getting Started](getting-started/):** a gentle introduction to getting
your first Rocket application running.
- **[Overview](overview/):** describes the core concepts of Rocket.
- **[Requests](requests/):** discusses handling requests: control-flow,
parsing, and validating.
- **[Responses](responses/):** discusses generating responses.
- **[State](state/):** how to manage state in a Rocket application.
- **[Fairings](fairings/):** provides an overview of Rocket's structured
middleware.
- **[Testing](testing/):** how to unit and integration test a Rocket
application.
- **[Configuration](configuration/):** how to configure a Rocket application.
- **[Pastebin Tutorial](pastebin-tutorial/):** a tutorial creating a pastebin
with Rocket.
- **[Conclusion](conclusion/):** concludes the guide and discusses next steps
for learning.
- **[FAQ](faq/):** answers to frequently asked questions about Rocket and
using it.
## Getting Help
The official community support channels are via Matrix chat on
[`#rocket:mozilla.org`] and via [GitHub Discussions]. To join us on Matrix, we
recommend the browser-based [Element] client. The [FAQ](faq/) also provides
answers to commonly asked questions.
[GitHub Discussions]: https://github.com/rwf2/Rocket/discussions
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[Element]: https://chat.mozilla.org/#/room/#rocket:mozilla.org

View File

@ -1,446 +0,0 @@
###############################################################################
# Release info: displayed between bars in the header
###############################################################################
[release]
version = "0.5.0"
date = "Nov 17, 2023"
###############################################################################
# Top features: displayed in the header under the introductory text.
###############################################################################
[[top_features]]
title = "Type Safe"
text = "Type safety turned up to 11 means security and robustness come at compile-time."
image = "helmet"
button = "Learn More"
url = "overview/#how-rocket-works"
width = "69px"
height = "71px"
[[top_features]]
title = "Boilerplate Free"
text = "Spend your time writing code that really matters and let Rocket handle the rest."
image = "robot-free"
button = "See Examples"
url = "overview/#anatomy-of-a-rocket-application"
width = "78px"
height = "71px"
[[top_features]]
title = "Easy To Use"
text = "Simple, intuitive APIs make Rocket approachable, no matter your background."
image = "sun"
button = "Get Started"
url = "guide"
margin = 2
width = "68px"
height = "69px"
[[top_features]]
title = "Extensible"
text = "Create your own first-class primitives that any Rocket application can use."
image = "telescope"
button = "See How"
url = "overview/#anatomy-of-a-rocket-application"
margin = 9
width = "71px"
height = "62px"
###############################################################################
# Sections: make sure there are an odd number so colors work out.
###############################################################################
[[sections]]
title = "Hello, Rocket!"
code = '''
#[macro_use] extern crate rocket;
#[get("/hello/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![hello])
}
'''
text = '''
This is a **complete Rocket application**. It does exactly what you would
expect. If you were to visit **/hello/John/58**, youd see:
<span class="callout">Hello, 58 year old named John!</span>
If someone visits a path with an `<age>` that isnt a `u8`, Rocket doesnt
just call `hello`. Instead, it tries other matching routes or returns a
**404**.
'''
[[sections]]
title = "Forms? Check!"
code = '''
#[derive(FromForm)]
struct Task<'r> {
#[field(validate = len(1..))]
description: &'r str,
completed: bool
}
#[post("/", data = "<task>")]
fn new(task: Form<Task<'_>>) -> Flash<Redirect> {
Flash::success(Redirect::to(uri!(home)), "Task added.")
}
'''
text = '''
Form handling **is simple, declarative, and complete**: derive
[`FromForm`](@api/rocket/derive.FromForm.html) for your structure and set the
`data` parameter to a `Form` type. Rocket automatically **parses and
validates** the form data into your structure and calls your function.
File uploads? A breeze with [`TempFile`](@api/rocket/fs/enum.TempFile.html).
Bad form request? Rocket doesnt call your function! Need to know what went
wrong? Use a `data` parameter of `Result`! Want to rerender the form with user
input and errors? Use [`Context`](guide/requests/#context)!
'''
[[sections]]
title = "JSON, always on."
code = '''
#[derive(Serialize, Deserialize)]
struct Message<'r> {
contents: &'r str,
}
#[put("/<id>", data = "<msg>")]
fn update(db: &Db, id: Id, msg: Json<Message<'_>>) -> Value {
if db.contains_key(&id) {
db.insert(id, msg.contents);
json!({ "status": "ok" })
} else {
json!({ "status": "error" })
}
}
'''
text = '''
Rocket has first-class support for JSON, right out of the box. Simply derive
`Deserialize` or `Serialize` to receive or return JSON, respectively.
Look familiar? Forms, JSON, and all kinds of body data types work through
Rockets [`FromData`](@api/rocket/data/trait.FromData.html) trait, Rockets
approach to deriving types from body data. A `data` route parameter can be
_any_ type that implements `FromData`. A value of that type will be
deserialized automatically from the incoming request body. You can even
implement `FromData` for your own types!
'''
###############################################################################
# Bottom features: displayed above the footer.
###############################################################################
[[bottom_features]]
title = 'Templating'
text = "Rocket makes templating a breeze with built-in templating support."
image = 'templating-icon'
url = 'guide/responses/#templates'
button = 'Learn More'
color = 'blue'
width = '101px'
height = '52px'
[[bottom_features]]
title = 'Cookies'
text = "View, add, or remove cookies, with or without encryption, without hassle."
image = 'cookies-icon'
width = '72px'
height = '58px'
url = 'guide/requests/#cookies'
button = 'Learn More'
color = 'fucsia'
margin = -6
[[bottom_features]]
title = 'WebSockets + Streams'
text = "Create and return potentially infinite async streams of data with ease."
image = 'streams-icon'
url = 'guide/responses/#async-streams'
button = 'Learn More'
color = 'red'
width = '82px'
height = '81px'
margin = -29
[[bottom_features]]
title = 'Config Profiles'
text = "Configure your application your way for debug, release, or anything else!"
image = 'config-icon'
url = 'guide/configuration/#profiles'
button = 'Learn More'
color = 'yellow'
width = '57px'
height = '57px'
margin = -3
[[bottom_features]]
title = 'Type-Checked URIs'
text = "Never mistype or forget to update a URI again with Rocket's typed URIs."
image = 'pencil-icon'
url = 'guide/requests/#private-cookies'
button = 'Learn More'
color = 'orange'
width = '60px'
height = '60px'
margin = -3
[[bottom_features]]
title = 'Structured Middleware'
text = "Fairings are Rocket's simpler approach to structured middleware."
image = 'ship-icon'
url = 'guide/fairings/#fairings'
button = 'Learn More'
color = 'green'
width = '98px'
height = '74px'
margin = -20
[[bottom_features]]
title = 'Database Support'
text = "Store data with ease with Rocket's built-in ORM agnostic database support."
image = 'query-icon'
url = 'guide/state/#databases'
button = 'Learn More'
color = 'pink'
width = '73px'
height = '57px'
margin = -3
[[bottom_features]]
title = 'Testing'
text = "Unit and integration test using the comprehensive, built-in testing library."
image = 'testing-icon'
url = 'guide/testing#testing'
button = 'Learn More'
color = 'aqua'
width = '47px'
height = '54px'
[[bottom_features]]
title = 'Community'
text = "Join an extensive community of 20,000+ Rocketeers that love Rocket."
image = 'globe'
url = 'https://github.com/rwf2/Rocket/network/dependents'
button = 'See Dependents'
color = 'purple'
width = '55px'
height = '55px'
margin = -1
###############################################################################
# Panels: displayed in a tabbed arrangement.
###############################################################################
[[panels]]
name = "Routing"
checked = true
content = '''
Rocket's main task is to route incoming requests to the appropriate request
handler using your application's declared routes. Routes are declared using
Rocket's _route_ attributes. The attribute describes the requests that match the
route. The attribute is placed on top of a function that is the request handler
for that route.
As an example, consider the simple route below:
```rust
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
```
This `index` route matches any incoming HTTP `GET` request to `/`, the index.
The handler returns a `String`. Rocket automatically converts the string into a
well-formed HTTP response that includes the appropriate `Content-Type` and body
encoding metadata.
'''
[[panels]]
name = "Dynamic Params"
content = '''
Rocket automatically parses dynamic data in path segments into any desired type.
To illustrate, let's use the following route:
```rust
#[get("/hello/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
```
This `hello` route has two dynamic parameters, identified with angle brackets,
declared in the route URI: `<name>` and `<age>`. Rocket maps each parameter to
an identically named function argument: `name: &str` and `age: u8`. The dynamic
data in the incoming request is parsed automatically into a value of the
argument's type. The route is called only when parsing succeeds.
Parsing is directed by the
[`FromParam`](@api/rocket/request/trait.FromParam.html) trait. Rocket implements
`FromParam` for many standard types, including both `&str` and `u8`. You can
implement it for your own types, too!
'''
[[panels]]
name = "Handling Data"
content = '''
Rocket can automatically parse body data, too!
```rust
#[post("/login", data = "<login>")]
fn login(login: Form<UserLogin>) -> String {
format!("Hello, {}!", login.name)
}
```
The dynamic parameter declared in the `data` route attribute parameter again
maps to a function argument. Here, `login` maps to `login: Form<UserLogin>`.
Parsing is again trait-directed, this time by the
[`FromData`](@api/rocket/data/trait.FromData.html) trait.
The [`Form`](@api/rocket/form/struct.Form.html) type is Rocket's [robust form
data parser](@guide/requests/#forms). It automatically parses the request body into the internal type,
here `UserLogin`. Other built-in `FromData` types include
[`Data`](@api/rocket/struct.Data.html),
[`Json`](@api/rocket/serde/json/struct.Json.html), and
[`MsgPack`](@api/rocket/serde/msgpack/struct.MsgPack.html). As always, you can
implement `FromData` for your own types, too!
'''
[[panels]]
name = "Request Guards"
content = '''
In addition to dynamic path and data parameters, request handlers can also
contain a third type of parameter: _request guards_. Request guards aren't
declared in the route attribute, and any number of them can appear in the
request handler signature.
Request guards _protect_ the handler from running unless some set of conditions
are met by the incoming request metadata. For instance, if you are writing an
API that requires sensitive calls to be accompanied by an API key in the request
header, Rocket can protect those calls via a custom `ApiKey` request guard:
```rust
#[get("/sensitive")]
fn sensitive(key: ApiKey) { ... }
```
`ApiKey` protects the `sensitive` handler from running incorrectly. In order for
Rocket to call the `sensitive` handler, the `ApiKey` type needs to be derived
through a [`FromRequest`](@api/rocket/request/trait.FromRequest.html)
implementation, which in this case, validates the API key header. Request guards
are a powerful and unique Rocket concept; they centralize application policy and
invariants through types.
'''
[[panels]]
name = "Responders"
content = '''
The return type of a request handler can be any type that implements
[`Responder`](@api/rocket/response/trait.Responder.html):
```rust
#[get("/")]
fn route() -> T { ... }
```
Above, T must implement `Responder`. Rocket implements `Responder` for many of
the standard library types including `&str`, `String`, `File`, `Option`, and
`Result`. Rocket also implements custom responders such as
[`Redirect`](@api/rocket/response/struct.Redirect.html),
[`Flash`](@api/rocket/response/struct.Flash.html), and
[`Template`](@api/rocket_dyn_templates/struct.Template.html).
The task of a `Responder` is to generate a
[`Response`](@api/rocket/response/struct.Response.html), if possible.
`Responder`s can fail with a status code. When they do, Rocket calls the
corresponding error catcher, a `catch` route, which can be declared as follows:
```rust
#[catch(404)]
fn not_found() -> T { ... }
```
'''
[[panels]]
name = "Launching"
content = '''
Finally, we get to launch our application! Rocket begins dispatching requests to
routes after they've been _mounted_ and the application has been _launched_.
These two steps, usually wrtten in a `rocket` function, look like:
```rust
#[launch]
fn rocket() -> _ {
rocket::build().mount("/base", routes![index, another])
}
```
The `mount` call takes a _base_ and a set of routes via the `routes!` macro. The
base path (`/base` above) is prepended to the path of every route in the list,
effectively namespacing the routes. `#[launch]` creates a `main` function that
starts the server. In development, Rocket prints useful information to the
console to let you know everything is okay.
```sh
🚀 Rocket has launched from http://127.0.0.1:8000
```
'''
###############################################################################
# Sponsors
###############################################################################
[sponsors.diamond]
name = "💎 Diamond"
tag = "$500/month"
color = "#addcde"
height = "110px"
[[sponsors.diamond.sponsors]]
name = "Kindness"
url = "https://kindness.ai"
img = "kindness.png"
blurb = "Supporting customers with Kindness"
width = "110px"
[sponsors.gold]
name = "💛 Gold"
tag = "$250/month"
color = "#fffbba"
height = "55px"
[[sponsors.gold.sponsors]]
name = "ohne-makler"
url = "https://www.ohne-makler.net/"
img = "ohne-makler.svg"
width = "173px"
[[sponsors.gold.sponsors]]
name = "RWF2"
url = "https://rwf2.org"
img = "rwf2.gif"
blurb = "Rocket Web Framework Foundation"
width = "55px"
[sponsors.bronze]
name = "🤎 Bronze"
tag = "$50/month"
color = "#c7a483"
height = "30px"
[[sponsors.bronze.sponsors]]
name = "1Password"
url = "https://1password.com"
img = "1password.svg"
blurb = "The worlds most-loved password manager"
width = "30px"

View File

@ -1,394 +0,0 @@
# Rocket v0.2: Managed State & More
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on February 06, 2017
</strong></p>
<!-- we should be able to generate the title and subheading -->
Today marks the first major release since Rocket's debut a little over a month
ago. Rocket v0.2 packs a ton of new features, fixes, and general improvements.
Much of the development in v0.2 was led by the community, either through reports
via the [GitHub issue tracker](https://github.com/rwf2/Rocket/issues)
or via direct contributions. In fact, there have been **20 unique contributors**
to Rocket's codebase since Rocket's initial introduction! Community feedback has
been incredible. As a special thank you, we include the names of these
contributors at the end of this article.
## 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.
> Rocket's so simple, you feel like you're doing something wrong. It's like if
> you're making fire with rocks and suddenly someone gives you a lighter. Even
> though you know the lighter makes fire, and does it even faster and better and
> with a simple flick, the rock's still in your brain.
>
> -- <cite>Artem "impowski" Biryukov, January 17, 2017, on **#rocket**</cite>
## New Features
Rocket v0.2 includes several new features that make developing Rocket
applications simpler, faster, and safer than ever before.
### Managed State
Undoubtedly, the star feature of this release is **managed state**. Managed
state allows you to pass state to Rocket prior to launching your application and
later retrieve that state from any request handler by simply including the
state's type in the function signature. It works in two easy steps:
1. Call `manage` on the `Rocket` instance corresponding to your application
with the initial value of the state.
2. Add a `State<T>` type to any request handler, where `T` is the type of the
value passed into `manage`.
Rocket takes care of the rest! `State` works through Rocket's [request
guards](@guide-v0.3/requests/#request-guards). You can call `manage` any number
of times, as long as each call corresponds to a value of a different type.
As a simple example, consider the following "hit counter" example application:
```rust
struct HitCount(AtomicUsize);
#[get("/")]
fn index(hit_count: State<HitCount>) -> &'static str {
hit_count.0.fetch_add(1, Ordering::Relaxed);
"Your visit has been recorded!"
}
#[get("/count")]
fn count(hit_count: State<HitCount>) -> String {
hit_count.0.load(Ordering::Relaxed).to_string()
}
fn main() {
rocket::ignite()
.mount("/", routes![index, count])
.manage(HitCount(AtomicUsize::new(0)))
.launch()
}
```
Visiting `/` will record a visit by incrementing the hit count by 1. Visiting
the `/count` path will display the current hit count.
One concern when using _managed state_ is that you might forget to call `manage`
with some state's value before launching your application. Not to worry: Rocket
has your back! Let's imagine for a second that we forgot to add the call to
`manage` on line 17 in the example above. Here's what the compiler would emit
when we compile our buggy application:
```rust
warning: HitCount is not currently being managed by Rocket
--> src/main.rs:4:21
|
4 | fn index(hit_count: State<HitCount>) -> &'static str {
| ^^^^^^^^^^^^^^^
|
= note: this State request guard will always fail
help: maybe add a call to 'manage' here?
--> src/main.rs:15:5
|
15| rocket::ignite()
| ^^^^^^^^^^^^^^^^
warning: HitCount is not currently being managed by Rocket
--> src/main.rs:10:21
|
10 | fn count(hit_count: State<HitCount>) -> String {
| ^^^^^^^^^^^^^^^
|
= note: this State request guard will always fail
help: maybe add a call to 'manage' here?
--> src/main.rs:15:5
|
15 | rocket::ignite()
| ^^^^^^^^^^^^^^^^
```
You can read more about managed state in the [guide](@guide-v0.3/state/), the
API docs for [manage](@api-v0.3/rocket/struct.Rocket.html#method.manage), and the API
docs for [State](@api-v0.3/rocket/struct.State.html).
### Unmounted Routes Lint
A common mistake that new Rocketeers make is forgetting to
[mount](@guide-v0.3/overview/#mounting) declared routes. In Rocket v0.2, Rocket
adds a _lint_ that results in a compile-time warning for unmounted routes. As a
simple illustration, consider the canonical "Hello, world!" Rocket application
below, and note that we've forgotten to mount the `hello` route:
```rust
#[get("/")]
fn hello() -> &'static str {
"Hello, world!"
}
fn main() {
rocket::ignite().launch();
}
```
When this program is compiled, the compiler emits the following warning:
```rust
warning: the 'hello' route is not mounted
--> src/main.rs:2:1
|
2 | fn hello() -> &'static str {
| _^ starting here...
3 | | "Hello, world!"
4 | | }
| |_^ ...ending here
|
= note: Rocket will not dispatch requests to unmounted routes.
help: maybe add a call to 'mount' here?
--> src/main.rs:7:5
|
7 | rocket::ignite().launch();
| ^^^^^^^^^^^^^^^^
```
The lint can be disabled selectively per route by adding an
`#[allow(unmounted_route)]` annotation to a given route declaration. It can also
be disabled globally by adding `#![allow(unmounted_route)]`. You can read more
about this lint in the [codegen documentation](@api-v0.3/rocket_codegen/index.html).
### Configuration via Environment Variables
A new feature that makes deploying Rocket apps to the cloud a little easier is
configuration via environment variables. Simply put, any configuration parameter
can be set via an environment variable of the form `ROCKET_{PARAM}`, where
`{PARAM}` is the name of the configuration parameter. For example, to set the
`port` Rocket listens on, simply set the `ROCKET_PORT` environment variable:
```sh
ROCKET_PORT=3000 cargo run --release
```
Configuration parameters set via environment variables take precedence over
parameters set via the `Rocket.toml` configuration file. Note that _any_
parameter can be set via an environment variable, include _extras_. For more
about configuration in Rocket, see the [configuration section of the
guide](@guide-v0.3/configuration).
### And Plenty More!
Rocket v0.2 is full of many new features! In addition to the three features
described above, v0.2 also includes the following:
* `Config` structures can be built via `ConfigBuilder`, which follows the
builder pattern.
* Logging can be enabled or disabled on custom configuration via a second
parameter to the `Rocket::custom` method.
* `name` and `value` methods were added to `Header` to retrieve the name and
value of a header.
* A new configuration parameter, `workers`, can be used to set the number of
threads Rocket uses.
* The address of the remote connection is available via `Request.remote()`.
Request preprocessing overrides remote IP with value from the `X-Real-IP`
header, if present.
* During testing, the remote address can be set via `MockRequest.remote()`.
* The `SocketAddr` request guard retrieves the remote address.
* A `UUID` type has been added to `contrib`.
* `rocket` and `rocket_codegen` will refuse to build with an incompatible
nightly version and emit nice error messages.
* Major performance and usability improvements were upstreamed to the `cookie`
crate, including the addition of a `CookieBuilder`.
* When a checkbox isn't present in a form, `bool` types in a `FromForm`
structure will parse as `false`.
* The `FormItems` iterator can be queried for a complete parse via `completed`
and `exhausted`.
* Routes for `OPTIONS` requests can be declared via the `options` decorator.
* Strings can be percent-encoded via `URI::percent_encode()`.
## Breaking Changes
This release includes several breaking changes. These changes are listed below
along with a short note about how to handle the breaking change in existing
applications.
* **`Rocket::custom` takes two parameters, the first being `Config` by
value.**
A call in v0.1 of the form `Rocket::custom(&config)` is now
`Rocket::custom(config, false)`.
* **Tera templates are named without their extension.**
A templated named `name.html.tera` is now simply `name`.
* **`JSON` `unwrap` method has been renamed to `into_inner`.**
A call to `.unwrap()` should be changed to `.into_inner()`.
* **The `map!` macro was removed in favor of the `json!` macro.**
A call of the form `map!{ "a" => b }` can be written as: `json!({ "a": b
})`.
* **The `hyper::SetCookie` header is no longer exported.**
Use the `Cookie` type as an `Into<Header>` type directly.
* **The `Content-Type` for `String` is now `text/plain`.**
Use `content::HTML<String>` for HTML-based `String` responses.
* **`Request.content_type()` returns an `Option<ContentType>`.**
Use `.unwrap_or(ContentType::Any)` to get the old behavior.
* **The `ContentType` request guard forwards when the request has no
`Content-Type` header.**
Use an `Option<ContentType>` and `.unwrap_or(ContentType::Any)` for the old
behavior.
* **A `Rocket` instance must be declared _before_ a `MockRequest`.**
Change the order of the `rocket::ignite()` and `MockRequest::new()` calls.
* **A route with `format` specified only matches requests with the same
format.**
Previously, a route with a `format` would match requests without a format
specified. There is no workaround to this change; simply specify formats
when required.
* **`FormItems` can no longer be constructed directly.**
Instead of constructing as `FormItems(string)`, construct as
`FormItems::from(string)`.
* **`from_from_string(&str)` in `FromForm` removed in favor of
`from_form_items(&mut FormItems)`.**
Most implementation should be using `FormItems` internally; simply use the
passed in `FormItems`. In other cases, the form string can be retrieved via
the `inner_str` method of `FormItems`.
* **`Config::{set, default_for}` are deprecated.**
Use the `set_{param}` methods instead of `set`, and `new` or `build` in
place of `default_for`.
* **Route paths must be absolute.**
Prepend a `/` to convert a relative path into an absolute one.
* **Route paths cannot contain empty segments.**
Remove any empty segments, including trailing ones, from a route path.
## Bug Fixes
Three bugs were fixed in this release:
* Handlebars partials were not properly registered
([#122](https://github.com/rwf2/Rocket/issues/122)).
* `Rocket::custom` did not set the custom configuration as the `active`
configuration.
* Route path segments with more than one dynamic parameter were erroneously
allowed.
## General Improvements
In addition to new features, Rocket saw the following smaller improvements:
* Rocket no longer overwrites a catcher's response status.
* The `port` `Config` type is now a proper `u16`.
* Clippy issues injected by codegen are resolved.
* Handlebars was updated to `0.25`.
* The `PartialEq` implementation of `Config` doesn't consider the path or
session key.
* Hyper dependency updated to `0.10`.
* The `Error` type for `JSON as FromData` has been exposed as `SerdeError`.
* SVG was added as a known Content-Type.
* Serde was updated to `0.9`.
* Form parse failure now results in a **422** error code.
* Tera has been updated to `0.7`.
* `pub(crate)` is used throughout to enforce visibility rules.
* Query parameters in routes (`/path?<param>`) are now logged.
* Routes with and without query parameters no longer _collide_.
Rocket v0.2 also includes all of the new features, bug fixes, and improvements
from versions 0.1.1 through 0.1.6. You can read more about these changes in the
[v0.1
CHANGELOG](https://github.com/rwf2/Rocket/blob/v0.1/CHANGELOG.md).
## What's next?
Work now begins on Rocket v0.3! The focus of the next major release will be on
security. In particular, three major security features are planned:
1. **Automatic CSRF protection across all payload-based requests
([#14](https://github.com/rwf2/Rocket/issues/14)).**
Rocket will automatically check the origin of requests made for HTTP `PUT`,
`POST`, `DELETE`, and `PATCH` requests, allowing only authorized requests to
be dispatched. This includes checking `POST`s from form submissions and any
requests made via JavaScript.
2. **Encryption and signing of session-based cookies
([#20](https://github.com/rwf2/Rocket/issues/20)).**
Built-in session support will encrypt and sign cookies using a user supplied
`session_key`. Encryption and signing will occur automatically for
session-based cookies.
3. **Explicit typing of raw HTTP data strings
([#43](https://github.com/rwf2/Rocket/issues/43)).**
A present, the standard `&str` type is used to represent raw HTTP data
strings. In the next release, a new type, `&RawStr`, will be used for this
purpose. This will make it clear when raw data is being handled. The type
will expose convenient methods such as `.url_decode()` and `.html_escape()`.
Work on Rocket v0.3 will also involve exploring built-in support for user
authentication and authorization as well as automatic parsing of multipart
forms.
## Contributors to v0.2
The following wonderful people helped make Rocket v0.2 happen:
<ul class="columns">
<li>Cliff H</li>
<li>Dru Sellers</li>
<li>Eijebong</li>
<li>Eric D. Reichert</li>
<li>Ernestas Poskus</li>
<li>FliegendeWurst</li>
<li>Garrett Squire</li>
<li>Giovanni Capuano</li>
<li>Greg Edwards</li>
<li>Joel Roller</li>
<li>Josh Holmer</li>
<li>Liigo Zhuang</li>
<li>Lori Holden</li>
<li>Marcus Ball</li>
<li>Matt McCoy</li>
<li>Reilly Tucker Siemens</li>
<li>Robert Balicki</li>
<li>Sean Griffin</li>
<li>Seth Lopez</li>
<li>tborsa</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/rwf2/Rocket#contributing) and start
contributing!
## Start using Rocket today!
Not already using Rocket? Rocket is extensively documented, making it easy for
you to start writing your web applications in Rocket! See the
[overview](../../overview) or start writing code immediately by reading through
[the guide](@guide-v0.3).

View File

@ -1,331 +0,0 @@
# Rocket v0.3: Fairings, TLS, Private Cookies
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on July 14, 2017
</strong></p>
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](@guide-v0.3) or learning more from
[the overview](../../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].
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.3.0/CHANGELOG.md#version-030-jul-14-2017
### 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.
[`Fairing`]: @api-v0.3/rocket/fairing/trait.Fairing.html
[fairings guide]: @guide-v0.3/fairings
### 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:
```toml
[global.tls]
certs = "/path/to/certs.pem"
key = "/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.
[`rustls`]: https://github.com/ctz/rustls
[configuring TLS]: @guide-v0.3/configuration/#configuring-tls
### 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:
```rust
/// Retrieve the user's ID, if any.
#[get("/user_id")]
fn user_id(cookies: Cookies) -> Option<String> {
request.cookies()
.get_private("user_id")
.map(|cookie| format!("User ID: {}", cookie.value()))
}
/// Remove the `user_id` cookie.
#[post("/logout")]
fn logout(mut cookies: Cookies) -> Flash<Redirect> {
cookies.remove_private(Cookie::named("user_id"));
Flash::success(Redirect::to("/"), "Successfully logged out.")
}
```
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.
[`Cookies`]: @api-v0.3/rocket/http/enum.Cookies.html
[`get_private`]: @api-v0.3/rocket/http/enum.Cookies.html#method.get_private
[`add_private`]: @api-v0.3/rocket/http/enum.Cookies.html#method.add_private
[`remove_private`]: @api-v0.3/rocket/http/enum.Cookies.html#method.remove_private
[private cookies]: @guide-v0.3/requests/#private-cookies
### 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:
```rust
#[derive(FromForm)]
struct External {
type: String
}
```
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:
```rust
#[derive(FromForm)]
struct External {
#[form(field = "type")]
api_type: String
}
```
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](@guide-v0.3/requests/#field-renaming) section of the guide.
[`FromForm`]: @api-v0.3/rocket/request/trait.FromForm.html
### And Plenty More!
In addition to the four highlighted above, Rocket 0.3 also ships with the
following new features:
* A [`MsgPack`] type 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 [`Accept`] header structure was added.
* The [`Accept`] request header can be retrieved via [`Request::accept()`].
* All active routes can be retrieved via [`Rocket::routes()`].
* [`Response::body_string()`] was added to retrieve the response body as a
`String`.
* [`Response::body_bytes()`] was added to retrieve the response body as a
`Vec<u8>`.
* [`Response::content_type()`] was added to retrieve the Content-Type header
of a response.
* Data limits on incoming data are [now
configurable](@guide-v0.3/configuration/#data-limits).
* [`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.
* [`&Route`] is now a request guard.
* The base mount path of a [`Route`] can be retrieved via `Route::base` or
`Route::base()`.
* `Config::{development, staging, production}` constructors were added for
[`Config`].
* [`Config::get_datetime()`] was added to retrieve an extra as a `Datetime`.
* Forms can be now parsed _leniently_ via the new [`LenientForm`] data guard.
* The `?` operator can now be used with `Outcome`.
* Quoted string, array, and table [configuration parameters] can be set via
environment variables.
* Log coloring is disabled when `stdout` is not a TTY.
* [`FromForm`] is implemented for `Option<T: FromForm>`, `Result<T: FromForm,
T::Error>`.
* The [`NotFound`] responder was added for simple **404** response
construction.
[`MsgPack`]: @api-v0.3/rocket_contrib/msgpack/struct.MsgPack.html
[`Rocket::launch()`]: @api-v0.3/rocket/struct.Rocket.html#method.launch
[`LaunchError`]: @api-v0.3/rocket/error/struct.LaunchError.html
[Default rankings]: @api-v0.3/rocket/struct.Route.html
[`&Route`]: @api-v0.3/rocket/struct.Route.html
[`Route`]: @api-v0.3/rocket/struct.Route.html
[`Accept`]: @api-v0.3/rocket/http/struct.Accept.html
[`Request::accept()`]: @api-v0.3/rocket/struct.Request.html#method.accept
[`contrib`]: @api-v0.3/rocket_contrib/
[`Rocket::routes()`]: @api-v0.3/rocket/struct.Rocket.html#method.routes
[`Response::body_string()`]: @api-v0.3/rocket/struct.Response.html#method.body_string
[`Response::body_bytes()`]: @api-v0.3/rocket/struct.Response.html#method.body_bytes
[`Response::content_type()`]: @api-v0.3/rocket/struct.Response.html#method.content_type
[`Request::guard()`]: @api-v0.3/rocket/struct.Request.html#method.guard
[`Request::limits()`]: @api-v0.3/rocket/struct.Request.html#method.limits
[`Request::route()`]: @api-v0.3/rocket/struct.Request.html#method.route
[`Config`]: @api-v0.3/rocket/struct.Config.html
[`Cookies`]: @api-v0.3/rocket/http/enum.Cookies.html
[`Config::get_datetime()`]: @api-v0.3/rocket/struct.Config.html#method.get_datetime
[`LenientForm`]: @api-v0.3/rocket/request/struct.LenientForm.html
[configuration parameters]: @api-v0.3/rocket/config/index.html#environment-variables
[`NotFound`]: @api-v0.3/rocket/response/status/struct.NotFound.html
## 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](https://github.com/rwf2/Rocket/blob/v0.3.0/CHANGELOG.md#breaking-changes)
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 `Server` HTTP header.
* The generic parameter of `rocket_contrib::Json` defaults to `json::Value`.
* The trailing '...' in the launch message was removed.
* The launch message prints regardless of the config environment.
* For debugging, `FromData` is implemented for `Vec<u8>` and `String`.
* The port displayed on launch is the port resolved, not the one configured.
* The `uuid` dependency was updated to `0.5`.
* The `base64` dependency was updated to `0.6`.
* The `toml` dependency was updated to `0.4`.
* The `handlebars` dependency was updated to `0.27`.
* The `tera` dependency was updated to `0.10`.
* [`yansi`] is now used for all terminal coloring.
* The `dev` `rustc` release channel is supported during builds.
* [`Config`] is now exported from the root.
* [`Request`] implements `Clone` and `Debug`.
* The `workers` config parameter now defaults to `num_cpus * 2`.
* Console logging for table-based config values is improved.
* `PartialOrd`, `Ord`, and `Hash` are now implemented for [`State`].
* The format of a request is always logged when available.
[`yansi`]: https://crates.io/crates/yansi
[`Request`]: @api-v0.3/rocket/struct.Request.html
[`State`]: @api-v0.3/rocket/struct.State.html
[`Config`]: @api-v0.3/rocket/struct.Config.html
## 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:
1. **Automatic CSRF protection across all payload-based requests
([#14](https://github.com/rwf2/Rocket/issues/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.
2. **First-class database support
([#167](https://github.com/rwf2/Rocket/issues/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.
3. **Typed URL generation from routes
([#263](https://github.com/rwf2/Rocket/issues/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.
[much wordier than necessary]: @guide-v0.3/state/#databases
## Contributors to v0.3
The following wonderful people helped make Rocket v0.3 happen:
<ul class="columns">
<li>Alan Stoate</li>
<li>Alexey Zabelin</li>
<li>Anton Pirker</li>
<li>Fabrice Desré</li>
<li>Ivar Abrahamsen</li>
<li>Josh Holmer</li>
<li>Joshua Rombauer</li>
<li>Lance Carlson</li>
<li>Lori Holden</li>
<li>Roman Frołow</li>
<li>Ryan Leckey</li>
<li>Stephan Buys</li>
<li>Tomek Wałkuski</li>
<li>Vesa Kaihlavirta</li>
<li>Yong Wen Chua</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/rwf2/Rocket#contributing) and start
contributing!

View File

@ -1,41 +0,0 @@
# Rocket v0.4 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on October 31, 2018
</strong></p>
I am delighted to announce that a release candidate for Rocket v0.4 is available
today! This release brings over a year of features, improvements, and
refinements, resolving some of the most called for requests and bringing Rocket
measurably closer to stable compatibility.
The release candidate is an opportunity to discover issues with Rocket v0.4 and
its documentation before its general release. We encourage all users to migrate
their applications to the release candidate and report any issues to the [GitHub
issue tracker].
Barring any major issues, the general release of Rocket v0.4 is planned for
Friday, November 9th, when we'll post a full news article covering the biggest
features and changes in Rocket v0.4. Until then, the [CHANGELOG] contains every
feature addition, change, and improvement since v0.3, as well as information on
migrating your applications to v0.4. All documentation, including the [guide]
and [API docs], has been updated in full for v0.4.
We're excited for your feedback, and we look forward to seeing you again on
Friday, November 9th for the general release!
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[API docs]: https://api.rocket.rs/v0.4/rocket/
[guide]: @guide-v0.4
[CHANGELOG]: https://github.com/rwf2/Rocket/tree/v0.4/CHANGELOG.md#version-040-rc-oct-31-2018
## 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 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-v0.4) or learning
more from [the overview](../../overview).

View File

@ -1,48 +0,0 @@
# Rocket's 2nd v0.4 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on November 30, 2018
</strong></p>
After a successful and productive initial v0.4 release candidate, I am happy to
announce that the second release candidate for Rocket v0.4 is now available.
This release candidate fixes issues identified during the first release
candidate, introduces further features, and leverages upstream `rustc`
contributions for improved diagnostics and stability. As before, this is an
opportunity to discover issues with Rocket v0.4 and its documentation before its
general release. We encourage all users to migrate their applications to the
second release candidate and report any issues to the [GitHub issue tracker].
To update to `v0.4.0`, manually update `rocket` in your `Cargo.toml` file:
```toml
[dependencies]
rocket = "0.4.0"
```
Barring any major issues, of which none are expected, the general release of
Rocket v0.4 is planned for Wednesday, December 5th, when we'll post a full news
article covering the biggest features and changes in Rocket v0.4. Until then,
the [CHANGELOG] contains every feature addition, change, and improvement since
v0.4.0-rc.1 and v0.3, as well as information on migrating your applications to
v0.4. All documentation, including the [guide] and [API docs], has been updated
in full for the second release candidate.
We're excited for your feedback, and we look forward to seeing you again on
Wednesday, December 5th for the general release!
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[API docs]: @api-v0.4
[guide]: @guide-v0.4
[CHANGELOG]: https://github.com/rwf2/Rocket/tree/v0.4/CHANGELOG.md#version-040-rc2-nov-30-2018
## 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 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-v0.4) or learning
more from [the overview](../../overview).

View File

@ -1,574 +0,0 @@
# Rocket v0.4: Typed URIs, Database Support, Revamped Queries, & More!
<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-v0.4) 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/rwf2/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-v0.4/rocket_codegen/macro.uri.html
[Typed URIs]: @guide-v0.4/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-v0.4/state/#databases
[`rocket_contrib::databases`]: @api-v0.4/rocket_contrib/databases/index.html
### Revamped Queries
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,
and [`FromFormValue`] can be derived.
For more details on handling query strings, see the new [Query Strings] guide
section and the updated [`route` attribute] documentation.
[`FromFormValue`]: @api-v0.4/rocket/request/trait.FromFormValue.html
[`FromQuery`]: @api-v0.4/rocket/request/trait.FromQuery.html
[`route` attribute]: @api-v0.4/rocket_codegen/attr.get.html
[Query Strings]: @guide-v0.4/requests/#query-strings
[#608]: https://github.com/rwf2/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-v0.4/rocket/trait.Handler.html
[`StaticFiles`]: @api-v0.4/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
#[derive(Responder, Debug)]
enum Error {
#[response(status = 401)]
Unauthorized(Json<Info>),
#[response(status = 404)]
NotFound(NamedFile, ContentType),
}
```
A value of this type can then be returned from a handler 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-v0.4/responses/#custom-responders
[`Responder` derive]: @api-v0.4/rocket_codegen/derive.Responder.html
[`Responder`]: @api-v0.4/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!
In addition to the features highlighted above, Rocket 0.4 also contains the
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/rwf2/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 maintenance release _only_. All users are
encouraged to migrate their applications to 0.4.
## 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-v0.4/rocket/request/enum.FormItems.html
[`Config::active()`]: @api-v0.4/rocket/config/struct.Config.html#method.active
[`Flash`]: @api-v0.4/rocket/response/struct.Flash.html
[`AdHoc::on_attach()`]: @api-v0.4/rocket/fairing/struct.AdHoc.html#method.on_attach
[`AdHoc::on_launch()`]: @api-v0.4/rocket/fairing/struct.AdHoc.html#method.on_launch
[`Config::root_relative()`]: @api-v0.4/rocket/struct.Config.html#method.root_relative
[`Config::tls_enabled()`]: @api-v0.4/rocket/struct.Config.html#method.tls_enabled
[`rocket_codegen`]: @api-v0.4/rocket_codegen/index.html
[`FromParam`]: @api-v0.4/rocket/request/trait.FromParam.html
[`FromFormValue`]: @api-v0.4/rocket/request/trait.FromFormValue.html
[`Data`]: @api-v0.4/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.
2. **Asynchronous Request Handling** ([#17])
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/rwf2/Rocket/issues/17
[#19]: https://github.com/rwf2/Rocket/issues/19
[#106]: https://github.com/rwf2/Rocket/issues/106
[#14]: https://github.com/rwf2/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/rwf2/Rocket#contributing) and start
contributing!

View File

@ -1,43 +0,0 @@
# Rocket v0.5 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on June 09, 2021
</strong></p>
Rocket `0.5.0-rc.1`, a release candidate for Rocket v0.5, is now available.
This release actualizes over _two years_ of development, bringing Rocket to Rust
stable and `async` to Rocket. Every facet, from core request handling to error
messages, has been subjected to Rocket's exacting standards.
This release candidate is an opportunity to discover issues with Rocket v0.5 and
its documentation before a general release. We encourage all users to migrate
their applications to the release candidate. All documentation, including the
[guide] and [API docs], has been updated in full for v0.5. Please report issues
to the [GitHub issue tracker]. Questions or concerns should instead be raised on
Rocket's newly available [GitHub discussions].
The Rocket v0.5 general release is planned for Friday, June 18th. A complete
migration guide and news article will accompany the general release. Until then,
the [CHANGELOG] contains every feature addition, change, and improvement since
v0.4.
We hope you enjoy Rocket v0.5 as much as we enjoyed creating it. We look forward
to your feedback!
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.5.0-rc.1/CHANGELOG.md
[API docs]: @api-v0.5
[guide]: @guide-v0.5
## About Rocket
Rocket is a web framework for Rust with a focus on usability, security,
extensibility, and speed. Rocket makes it simple to write fast, secure web
applications without sacrificing usability.
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 by [reading through the guide](../../guide) or learning more
from [the overview](../../overview).

View File

@ -1,43 +0,0 @@
# Rocket's 2nd v0.5 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on May 09, 2022
</strong></p>
Rocket `0.5.0-rc.2`, a release candidate for Rocket v0.5, is now available.
This release builds on the previous release candidate and brings further
features, improvements, and fixes to Rocket. As before, this is an opportunity
to discover issues with Rocket v0.5 and its documentation before its general
release. We encourage all users to migrate their applications to the second
release candidate and report any issues to the [GitHub issue tracker]. Please
see the new [migration guide] for complete details on how to upgrade from Rocket
v0.4. For changes since Rocket v0.5.0-rc.1, please see the [CHANGELOG].
Barring any major issues, of which none are expected, the general release of
Rocket v0.5 is planned for late May 2022, when we'll post a full news article
covering the biggest features and changes in Rocket v0.5. Until then, the
[CHANGELOG] contains every feature addition, change, and improvement since
v0.5.0-rc.1 and v0.4. All documentation, including the [guide] and [API docs],
has been updated in full for the second release candidate.
We're excited for your feedback, and we look forward to seeing you again soon
for the general release!
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[migration guide]: @guide-v0.5/upgrading
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.5.0-rc.2/CHANGELOG.md
[API docs]: @api-v0.5
[guide]: @guide-v0.5
## About Rocket
Rocket is a web framework for Rust with a focus on usability, security,
extensibility, and speed. Rocket makes it simple to write fast, secure web
applications without sacrificing usability.
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 by [reading through the guide](../../guide) or learning more
from [the overview](../../overview).

View File

@ -1,31 +0,0 @@
# Rocket's 3rd v0.5 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on March 23, 2023
</strong></p>
Rocket `0.5.0-rc.3`, a release candidate for Rocket v0.5, is now available.
This release builds on the previous release candidate and brings further
features, improvements, and fixes to Rocket. As before, this is an opportunity
to discover issues with Rocket v0.5 and its documentation before its general
release. We encourage all users to migrate their applications to the third
release candidate and report any issues to the [GitHub issue tracker]. Please
see the new [migration guide] for complete details on how to upgrade from Rocket
v0.4. For changes since Rocket v0.5.0-rc.2, please see the [CHANGELOG].
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[migration guide]: @guide-v0.5/upgrading
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.5.0-rc.3/CHANGELOG.md
## About Rocket
Rocket is a web framework for Rust with a focus on usability, security,
extensibility, and speed. Rocket makes it simple to write fast, secure web
applications without sacrificing usability.
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 by [reading through the guide](../../guide) or learning more
from [the overview](../../overview).

View File

@ -1,31 +0,0 @@
# Rocket's 4th v0.5 Release Candidate
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on November 01, 2023
</strong></p>
Rocket `0.5.0-rc.4`, a release candidate for Rocket v0.5, is now available.
This release builds on the previous release candidate and brings further
features, improvements, and fixes to Rocket. As before, this is an opportunity
to discover issues with Rocket v0.5 and its documentation before its general
release. We encourage all users to migrate their applications to the fourth
release candidate and report any issues to the [GitHub issue tracker]. Please
see the new [migration guide] for complete details on how to upgrade from Rocket
v0.4. For changes since Rocket v0.5.0-rc.3, please see the [CHANGELOG].
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[migration guide]: @guide-v0.5/upgrading
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.5.0-rc.4/CHANGELOG.md
## About Rocket
Rocket is a web framework for Rust with a focus on usability, security,
extensibility, and speed. Rocket makes it simple to write fast, secure web
applications without sacrificing usability.
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 by [reading through the guide](../../guide) or learning more
from [the overview](../../overview).

View File

@ -1,253 +0,0 @@
# Building a Better Foundation for Rocket's Future
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on Nov 17, 2023
</strong></p>
Along with the [release of Rocket v0.5], today I'm sharing plans to launch the
Rocket Web Framework Foundation, or [_RWF2_]. The RWF2 is a nonprofit
organization designed to support Rocket and the surrounding ecosystem,
financially and organizationally.
I'm also directly addressing the community's concerns regarding the pace of
Rocket's development, leadership, and release cadence. My hope is to assuage any
and all concerns about Rocket's future. I hope reading this leaves you feeling
confident that Rocket is here to stay, and that the RWF2 is the right step
towards increased community contributions and involvement.
! note: This is a co-announcement [along with release of Rocket v0.5].
[along with release of Rocket v0.5]: ../2023-11-17-version-0.5/
[release of Rocket v0.5]: ../2023-11-17-version-0.5/
[_RWF2_]: https://rwf2.org
[RWF2]: https://rwf2.org
## Background
I released Rocket in 2016 to fanfare. It was lauded as _the_ web framework for
Rust. But in the last few years, I'd be remiss to claim the same. New frameworks
have emerged, Rocket's recent development has been nothing short of erratic, and
four years went by without a major release.
The community rightfully voiced its disappointment and concern. Posts inquired
about the project's status: was it dead? I received copious email ranging from
concern over my well-being, to anger, to requests to transfer the project
entirely. The community ~~wasn't~~ isn't happy with Rocket.
And I get it. I failed to adequately lead the project. I failed to communicate
when it mattered most. I couldn't control the life events that pulled me away
from Rocket and most of my responsibilities, but I could have done more to
communicate what was going on. And I certainly could have done _something_ to
make it easy, make it _possible_ for others to push the project forward in my
absense.
But I did none of that. I couldn't make it happen. And I'm truly, sincerely
sorry.
## A Better Foundation for Rocket's Future
I'd like to make it impossible to repeat these mistakes. That's why today I'm
announcing plans for a new independent nonprofit foundation designed to support
and bolster Rocket's development, increase transparency, and diversify project
leadership: [RWF2].
> The **R**ocket **W**eb **F**ramework **F**oundation, _RWF2_, is a
> <abbr title="RWF2 is granted 501(c)(3) status via its fiscal host, the OCF.">
> 501(c)(3) nonprofit</abbr> and <a href="https://opencollective.com/rwf2">
> collective</a> that supports the development and community of free and open
> source software, like <a href="https://rocket.rs">Rocket</a>, as well as
> education for a more secure web.
Moving forward, the RWF2 will be responsible for governing Rocket and dictating
its trajectory. The goal is to distribute control of the project and prohibit
one person from being able to stall its development. The RWF2 will also act as a
vehicle for tax-deductible contributions, funds management, and development
grant distribution, all with the aim of increasing high-quality contributions
and educational material.
In summary, the RWF2 exists to enable:
* **Diversified Leadership**
Key responsibilities, such as releases, security, infrastructure, and
community engagement will be distributed to community members under the
umbrella of the foundation.
* **Tax-Deductible Contributions**
Because the RWF2 is a 501(c)(3) organization, contributions are
tax-deductible. We particularly hope this encourages corporate sponsorship,
especially from those who depend on Rocket. As a nonprofit, the RWF2 must
transparently manage and disburse all funds.
* **Development Grants**
A key use for contributions is the foundation's sponsorship and
administration of µGrants: small (≤ $1k) grants for concrete work on
Rocket or related projects. Compensation is staged upon completion of
predefined milestones and quality requirements.
* **Increased Transparency**
Milestones, release schedules, and periodic updates form part of the
foundation's responsibilities. The aim is to keep the community informed on
Rocket's development and plans, making it easier to get and remain involved.
* **Educational Resource Expansion**
The RWF2 aims to enhance the accessibility of educational resources,
training, and mentorship for web application security, especially for
traditionally marginalized groups. Our focus lies in delivering
high-quality, practical materials for building secure web applications.
## What's Happening Now
There's a lot to do to realize these goals, but the process starts today. Here's
what's being done now:
0. **Open Sponsorship**
Starting now, you can sponsor the RWF2 through [GitHub Sponsors] or
[Open Collective]. Tiers are still a work in progress, but for now, consider
all tiers on Open Collective, and Bronze+ tiers on GitHub, as intended for
corporate sponsors. Note that only contributions made directly via Open
Collective are guaranteed to be tax-deductible.
A special shout out to `@martynp`, `@nathanielford`, and `@wezm` for
jumping the gun in the best of ways and sponsoring the RWF2 via GitHub
ahead of schedule. Thank you!
0. **Team Assembly**
Initially, RWF2 governance will be exceedingly simple and consist of a
president <small>(hi!)</small> and a handful of team leads. Individuals can
fill multiple positions, though the intent is for every position to be held
by a different individual. Positions are by appointment, either by the
presiding team lead, by the president in their absence, and by other team
leads in the president's absence.
The initial teams and their responsibilities are listed below. If you're
interested in leading any of the teams (or another team you think should
exist), please reach out via the [Matrix channel] or directly via
[foundation@rwf2.org](mailto:foundation@rwf2.org).
- *Maintenance*
Reviews issues, pull requests, and discussions, and acts on them as
necessary. This largely means triaging issues, closing resolved or
duplicate issues and discussions, closing or merging stale or approved
pull requests, respectively, and pinging the appropriate individuals to
prevent issues or PRs from becoming stale.
- *Release*
Publishes code and documentation releases. This includes partitioning
commits according to scope and impact on breakage, writing and updating
CHANGELOGs, and testing and publishing new releases and their
documentation.
- *Knowledge*
Creates, maintains and improves materials that help others learn about
Rocket or web security. This includes documentation like API docs and the
Rocket guide, code such as examples and tutorials, and materials for live
or in-person education.
- *Community*
Keeps the community adjourned on happenings. This involves writing
periodic project updates as well as digesting and communicating
development milestones and schedules to a broad audience.
- *Infrastructure*
Maintains infrastructure including: building, testing, and release
scripts, static site generation, CI and other automated processes, and
domain registrar and cloud computing services.
0. **Transfer of Assets**
The majority of Rocket's assets, including its domain, website, source
code, and associated infrastructure, are managed under personal accounts.
All assets are being transferred to foundation-owned accounts, and access
will be given to the appropriate teams. The [migration project on GitHub]
is tracking the progress of asset migration.
0. **Process Documentation**
Some of Rocket's core processes, including releases and site building, are
generally inaccessible to others. These will be documented, and access will
be granted to the appropriate teams.
0. **Open Planning & Development**
While Rocket's development has generally been done in the open through
GitHub issues, PRs, and projects, little has been done to publicize those
efforts. Furthermore, _planning_ has largely been a closed process. Moving
forward, planning will be done in the open, and the community team will be
engaged to publicize development efforts and progress.
[GitHub Sponsors]: https://github.com/sponsors/rwf2
[Open Collective]: https://opencollective.com/rwf2
[Matrix channel]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[migration project on GitHub]: https://github.com/orgs/rwf2/projects/1
## What's Coming Soon
* **µGrants**
The µGrant specification is a work-in-progress. We simulatenously want to
encourage and financially incentivize high-quality contributions while not
disincentivizing existing contributors. This is a delicate balance, and we
want to take the time to get it right. To get involved, see the current
[draft proposal](https://github.com/rwf2/rwf2.org/blob/master/docs/micro-grants.md) and
share your thoughts in the [GitHub discussion](https://github.com/orgs/rwf2/discussions/8).
As soon as we have a specification that feels fair, the first µGrants will
be offered.
* **Foundation Website**
The [RWF2 website](https://rwf2.org) as it stands is a placeholder for a
more fully featured website. Besides articulating the foundation's mission
and goals, the RWF2's website will also serve as a source of truth for the
status of and means to engaging with ongoing projects, grants, and finances.
* **Membership**
While certainly premature at this point in time, a consideration for the
future comes in the form of foundation _membership_ whereby governance is
expanded to include foundation _members_. The [governance proposal
document](https://github.com/rwf2/rwf2.org/blob/master/docs/governance.md)
has one take on how this might work. Until such a proposal is accepted,
governance will follow the president + teams model articulated above.
## How to Get Involved
The RWF2 represents a conscious effort to transfer control of Rocket from an
individual (me) to the community (you). Without your involvement, the RWF2
ceases to exist. If you're excited about Rocket or the foundation, or simply
want to see Rocket continue to exist and flourish, please get involved.
* **Join the Discussion**
Communicate with us via the [Matrix channel], via [GitHub
discussions](https://github.com/orgs/rwf2/discussions), or via email at
[foundation@rwf2.org](mailto:foundation@rwf2.org). The foundation bring-up
itself is designed to be collaborative, and any input you have is
invaluable.
* **Make a Contribution**
Any easy way to get involved is to financially contribute. You can sponsor
the RWF2 through [GitHub Sponsors] or [Open Collective]. If your company
uses Rocket, encourage it to sponsor the project through the foundation.
* **Become a Team Lead**
If you're interested in leading or learning more about any one of the
*Maintenance*, *Release*, *Knowledge*, *Community*, or *Infrastructure*
teams, or think another team should exist, please get in touch via the
[Matrix channel] or via email at [foundation@rwf2.org](mailto:foundation@rwf2.org).
I'm excited for this next step in Rocket's history, and I hope you'll join me in
making it a success.

View File

@ -1,622 +0,0 @@
# Rocket v0.5: Stable, Async, Sentinels, Streams, SSE, Forms, WebSockets, & So Much More
<p class="metadata"><strong>
Posted by <a href="https://sergio.bz">Sergio Benitez</a> on Nov 17, 2023
</strong></p>
Four years, four release candidates, a thousand commits, and over a thousand
issues, discussions, and PRs later, I am ~~relieved~~ thrilled to announce the
general availability of Rocket v0.5.
> **Rocket** is an async backend web framework for Rust with a focus on
> usability, security, extensibility, and speed. Rocket makes it simple to write
> secure web applications without sacrificing productivity or performance.
We encourage all users to upgrade. For a guided migration from Rocket v0.4 to
Rocket v0.5, please consult the newly available [upgrading guide]. Rocket v0.4
will continue to be supported and receive security updates until the time Rocket
v0.6 is released.
! note: This is a co-announcement [along with the prelaunch] of [RWF2].
We're addressing the community's concerns regarding the pace of Rocket's
development, leadership, and release cadence in a separate announcement.
Please see the accompanying [RWF2 prelaunch announcement](../2023-11-17-rwf2-prelaunch/)
to learn more and see how you can get involved.
[RWF2]: https://rwf2.org
[along with the prelaunch]: ../2023-11-17-rwf2-prelaunch/
[upgrading guide]: @guide-v0.5/upgrading
## What's New?
Almost every bit has been reevaluated with a focus on usability and developer
productivity, security, and consistency across the library and [broader
ecosystem]. The changes are numerous, so we focus on the most noteworthy changes
here and encourage everyone to read the [CHANGELOG] for a complete list. For
answers to frequently asked questions, see the new [FAQ].
[CHANGELOG]: https://github.com/rwf2/Rocket/blob/v0.5.0/CHANGELOG.md
[broader ecosystem]: @guide-v0.5/faq/#releases
[FAQ]: @guide-v0.5/faq
### ⚓ Support for Stable `rustc` <badge>since `rc.1`</badge>
Rocket v0.5 compiles and builds on Rust stable. You can now compile and build
Rocket applications with `rustc` from the stable release channel and remove all
`#![feature(..)]` crate attributes. The complete canonical example with a single
`hello` route becomes:
```rust
#[macro_use] extern crate rocket;
#[get("/<name>/<age>")]
fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/hello", routes![hello])
}
```
<details>
<summary>See a <code>diff</code> of the changes from v0.4.</summary>
```diff
- #![feature(proc_macro_hygiene, decl_macro)]
-
#[macro_use] extern crate rocket;
#[get("/<name>/<age>")]
- fn hello(name: String, age: u8) -> String {
+ fn hello(name: &str, age: u8) -> String {
format!("Hello, {} year old named {}!", age, name)
}
- fn main() {
- rocket::ignite().mount("/hello", routes![hello]).launch();
- }
+ #[launch]
+ fn rocket() -> _ {
+ rocket::build().mount("/hello", routes![hello])
+ }
```
</details>
Note the new [`launch`] attribute, which simplifies starting an `async` runtime
for Rocket applications. See the [migration guide] for more on transitioning to
a stable toolchain.
[`launch`]: @api-v0.5/rocket/attr.launch.html
### 📥 Async I/O <badge>since `rc.1`</badge>
Rocket's core request handling was rebuilt in v0.5 to take advantage of the
latest `async` networking facilities in Rust. Backed by `tokio`, Rocket
automatically multiplexes request handling across `async` tasks on all of the
available cores on the machine. As a result, route handlers can now be declared
`async` and make use of `await` syntax:
```rust
use rocket::tokio;
use rocket::data::{Data, ToByteUnit};
#[post("/debug", data = "<data>")]
async fn debug(data: Data<'_>) -> std::io::Result<()> {
// Stream at most 512KiB all of the body data to stdout.
data.open(512.kibibytes())
.stream_to(tokio::io::stdout())
.await?;
Ok(())
}
```
See the [Blocking I/O](@guide-v0.5/upgrading#blocking-io) section of the upgrading
guide for complete details on the `async` I/O transition.
### 💂 Sentinels <badge>since `rc.1`</badge>
Rocket v0.5 introduces [sentinels]. Entirely unique to Rocket, sentinels offer
an automatic last line of defense against runtime errors by enabling any type
that appears in a route to abort application launch under invalid conditions.
For example, the [`&State<T>`] guard in v0.5 is a [`Sentinel`] that aborts
launch if the type `T` is not in managed state, thus preventing associated
runtime errors.
[`Sentinel`]s can be implemented outside of Rocket, too, and you should seek to
do so whenever possible. For instance, the [`Template`] type from
[`rocket_dyn_templates`] is a sentinel that ensures templates are properly
registered. As another example, consider a `MyResponder` that expects:
* A specific type `T` to be in managed state.
* An catcher to be registered for the `400` status code.
Making `MyResponder` a sentinel that guards against these conditions is as
simple as:
```rust
use rocket::{Rocket, Ignite, Sentinel};
# struct MyResponder;
# struct T;
impl Sentinel for MyResponder {
fn abort(r: &Rocket<Ignite>) -> bool {
r.state::<T>().is_none() || !r.catchers().any(|c| c.code == Some(400))
}
}
```
[sentinels]: @api-v0.5/rocket/trait.Sentinel.html
[`Sentinel`]: @api-v0.5/rocket/trait.Sentinel.html
[`&State<T>`]: @api-v0.5/rocket/struct.State.html
[`Template`]: @api-v0.5/rocket_dyn_templates/struct.Template.html
[`rocket_dyn_templates`]: @api-v0.5/rocket_dyn_templates/index.html
### ☄️ Streams and SSE <badge>since `rc.1`</badge>
Powered by the new asynchronous core, Rocket v0.5 introduces real-time, typed
`async` [streams]. The new [async streams] section of the guide contains further
details, and we encourage all interested parties to see the new real-time,
multi-room [chat example].
As a taste of what's possible, the following `stream` route emits a `"pong"`
Server-Sent Event every `n` seconds, defaulting to `1`:
```rust
# use rocket::*;
use rocket::tokio::time::{interval, Duration};
use rocket::response::stream::{Event, EventStream};;
#[get("/ping?<n>")]
fn stream(n: Option<u64>) -> EventStream![] {
EventStream! {
let mut timer = interval(Duration::from_secs(n.unwrap_or(1)));
loop {
yield Event::data("pong");
timer.tick().await;
}
}
}
```
[streams]: @api-v0.5/rocket/response/stream/index.html
[async streams]: @guide-v0.5/responses/#async-streams
[chat example]: @example/chat
### 🔌 WebSockets <badge>since `rc.4`</badge>
Rocket v0.5 introduces support for HTTP connection upgrades via a new [upgrade
API]. The API allows responders to assume control of raw I/O with the client in
an existing HTTP connection, thus allowing HTTP connections to be _upgraded_ to
any protocol, including WebSockets!
The newly introduced [`rocket_ws`] library takes advantage of the new API to
implement first-class support for WebSockets entirely outside of Rocket's core.
Working with `rocket_ws` to implement an echo server looks like this:
```rust
# use rocket::get;
use rocket_ws::{WebSocket, Stream};
#[get("/echo")]
fn echo_compose(ws: WebSocket) -> Stream!['static] {
ws.stream(|io| io)
}
```
Just like the newly introduced `async` streams, `rocket_ws` also supports using
generator syntax for WebSocket messages:
```rust
# use rocket::get;
use rocket_ws::{WebSocket, Stream};
#[get("/echo")]
fn echo_stream(ws: WebSocket) -> Stream!['static] {
Stream! { ws =>
for await message in ws {
yield message?;
}
}
}
```
For complete usage details, see the [`rocket_ws`] documentation.
[upgrade API]: @api-v0.5/rocket/response/struct.Response.html#upgrading
[`rocket_ws`]: @api-v0.5/rocket_ws
### 📝 Comprehensive Forms <badge>since `rc.1`</badge>
Rocket v0.5 entirely revamps [forms] with support for [multipart uploads],
[arbitrary collections] with [arbitrary nesting], [ad-hoc validation], and an
improved [`FromForm` derive], obviating the need for nearly all custom
implementations of `FromForm` or `FromFormField`. Rocket's new wire protocol for
forms allows applications to express _any structure_ with _any level of nesting
and collection_ without any custom code, eclipsing what's offered by other web
frameworks.
As an illustrative example, consider the following structures:
```rust
use rocket::form::FromForm;
#[derive(FromForm)]
struct MyForm<'r> {
owner: Person<'r>,
pet: Pet<'r>,
}
#[derive(FromForm)]
struct Person<'r> {
name: &'r str
}
#[derive(FromForm)]
struct Pet<'r> {
name: &'r str,
#[field(validate = eq(true))]
good_pet: bool,
}
```
To parse request data into a `MyForm`, a form with fields of `owner.name`,
`pet.name`, and `pet.good_pet` must be submitted. The ad-hoc validation on
`good_pet` validates that `good_pet` parses as `true`. Such a form, URL-encoded,
may look like:
```rust,ignore
"owner.name=Bob&pet.name=Sally&pet.good_pet=yes"
```
Rocket's derived `FromForm` implementation for `MyForm` will automatically parse
such a submission into the correct value:
```rust,ignore
MyForm {
owner: Person {
name: "Bob".into()
},
pet: Pet {
name: "Sally".into(),
good_pet: true,
}
}
# };
```
The rewritten [forms guide] provides complete details on revamped forms support.
[forms guide]: @guide-v0.5/requests/#forms
[ad-hoc validation]: @guide-v0.5/requests#ad-hoc-validation
[arbitrary nesting]: @guide-v0.5/requests#nesting
[multipart uploads]: @guide-v0.5/requests#multipart
[forms]: @guide-v0.5/requests#forms
[`FromFormField`]: @api-v0.5/rocket/form/trait.FromFormField.html
[arbitrary collections]: @guide-v0.5/requests#collections
[`FromForm` derive]: @api-v0.5/rocket/derive.FromForm.html
### 🚀 And so much more!
Rocket v0.5 introduces over **40** new features and major improvements! We
encourage everyone to review the [CHANGELOG] to learn about them all. Here are a
few more we don't want you to miss:
* An automatically enabled [`Shield`]: security and privacy headers for all responses.
* [Graceful shutdown] with configurable grace periods, [notification], and [shutdown fairings].
* An entirely new, flexible and robust [configuration system] based on [Figment].
* Type-system enforced [incoming data limits] to mitigate memory-based DoS attacks.
* Support for [mutual TLS] and client [`Certificate`]s.
* Asynchronous database pooling support via [`rocket_db_pools`].
* Compile-time URI literals via a fully revamped [`uri!`] macro.
[`Shield`]: @api-v0.5/rocket/shield/struct.Shield.html
[graceful shutdown]: @api-v0.5/rocket/config/struct.Shutdown.html#summary
[notification]: @api-v0.5/rocket/struct.Shutdown.html
[shutdown fairings]: @api-v0.5/rocket/fairing/trait.Fairing.html#shutdown
[configuration system]: @guide-v0.5/configuration/#configuration
[Figment]: https://docs.rs/figment/
[incoming data limits]: @guide-v0.5/requests/#streaming
[mutual TLS]: @guide-v0.5/configuration/#mutual-tls
[`uri!`]: @api-v0.5/rocket/macro.uri.html
[`rocket_db_pools`]: @api-v0.5/rocket_db_pools/index.html
[`Certificate`]: @api-v0.5/rocket/mtls/struct.Certificate.html
[migration guide]: @guide-v0.5/upgrading
## What's Next?
We think Rocket provides the most productive and confidence-inspiring web
development experience in Rust today, but as always, there's room for
improvement. To that end, here's what's on the docket for the next major
release:
0. **Migration to RWF2**
Discussed further in the [RWF2 prelaunch announcement], Rocket will
transition to being managed by the newly formed Rocket Web Framework
Foundation: _RWF2_. The net effect is increased development transparency,
including public roadmaps and periodic updates, financial support for
high-quality contributions, and codified pathways into the project's
governance.
0. **Pluggable Connection Listeners**
Rocket currently expects and enjoins connection origination via
TCP/IP. While sufficient for the common case, it excludes other desirable
interfaces such as Unix Domain Sockets (UDS).
In the next major release, Rocket will expose [an interface for implementing
and plugging-in custom connection listeners]. Rocket itself will make use
of this interface to expose more common mediums out-of-the-box, such as the
aforementioned UDS.
0. **Native `async` Traits**
Given the [stabilization of `async fn` in traits], the next major release
will seek to eliminate Rocket's dependence on `#[async_trait]` opting instead
for native `async` traits. This will greatly improve our documentation, which
currently calls out the attribute for each affected trait, as well as offer
modest performance improvements.
0. [**Typed Catchers**](https://github.com/rwf2/Rocket/issues/749)
Today's catchers cannot receive strictly typed error data. This results
in workarounds where error data is queried for well-typedness at runtime.
While it _has_ been possible to implement a form of typed error catching
prior, doing so necessitated limiting error data to `'static` values, as
other Rust web frameworks do, a concession we're unwilling to make.
After much experimentation, we have an approach that is ergonomic to use,
safe, and correct, all without the `'static` limitation. This will allow error
catchers to "pattern match" against error types at compile-time. At runtime,
Rocket will match emerging error types against the declared catchers and
call the appropriate catcher with the fully-typed value.
0. **Short-Circuitable Request Processing**
Whether with success or failure, fairings and guards cannot presently
terminate request processing early. The rationale for forbidding this
functionality was that it would allow third-party crates and plugins to
dictate responses without offering any recourse to the top-level application.
With the advent of typed catchers, however, we now have a mechanism by which
a top-level application can intercept early responses via their type,
resolving the prior concern. As such, in the next major release, fairings and
guards will be able to respond to requests early, and catchers will be able to
intercept those early responses at will.
0. **Associated Resources**
Often a set of routes will share a set requirements. For example, they
may share a URI prefix, subset of guards, and some managed state. In today's
Rocket, these common requirements must be repeatedly specified for each route.
While this is by design (we _want_ a route's requirements to be obvious), the
repetition is arduous and potentially error prone.
In an upcoming major release, Rocket will introduce new mechanisms by which
a set of routes can share an explicitly declared set of requirements. Their
_explicit_ and _declarative_ nature results in requirements that are
simultaneously obvious _and_ declared once.
We're really excited about this upcoming change and will be announcing more
in the near future.
0. **Performance Improvements**
Rocket appears to lag behind other Rust web frameworks in benchmarks. This is
partly due to [poor benchmarking], partly due to security-minded design
decisions, and partially due to unexploited opportunities. In the next
release, we'll be addressing the latter points. Specifically:
- _Explore making work stealing optional._
Rocket currently defaults to using tokio's multithreaded, work-stealing
scheduler. This avoids tail latency issues when faced with irregular and
heterogeneous tasks at the expense of throughput due to higher bookkeeping costs
associated with work stealing. Other Rust web frameworks instead opt to use
tokio's single-threaded scheduler, which while theoretically suboptimal,
may yield better performance results in practice, especially when
benchmarking homogeneous workloads.
While we believe work-stealing schedulers are the right choice for the
majority of applications desireing robust performance characteristics, we also
believe the choice should be the user's. We'll seek to make this choice
easier in the next release.
- _Reduce conversions from external to internal HTTP types._
Rocket revalidates and sometimes copies incoming HTTP request data.
In Rocket v0.5, we began transitioning to a model where we revalidate
security insensitive data in debug mode only, allowing for bugs to be
caught and reported while reducing performance impacts in production. In
the next release, we seek to extend this approach.
[an interface for implementing and plugging-in custom connection listeners]:
https://github.com/rwf2/Rocket/issues/1070#issuecomment-1491101952
[stabilization of `async fn` in traits]: https://github.com/rust-lang/rust/pull/115822
[poor benchmarking]: @guide-v0.5/faq/#performance
<!-- custom routers? -->
## ❤️ Thank You
A very special thank you to [Jeb Rosen], Rocket's maintainer from v0.4 to
v0.5-rc.1, without whom Rocket v0.5 wouldn't exist. Jeb is responsible for
leading the migration to `async` and Rust stable along with tireless efforts to
improve Rocket's documentation and address the community. Rocket is better for
having had Jeb along for the ride. Thank you, Jeb.
[Jeb Rosen]: https://github.com/rwf2/Rocket/commits?author=jebrosen
A special thank you to all of Rocket's users, especially those who diligently
waded through all four release candidates, raised issues, and participated on
[GitHub] and the [Matrix channel]. You all are an awesome, kind, and thoughtful
bunch. Thank you.
A heartfelt _thank you_ as well to _all_ **148** who contributed to Rocket v0.5:
<ul class="columns">
<li>Aaron Leopold</li>
<li>Abdullah Alyan</li>
<li>Aditya</li>
<li>Alex Macleod</li>
<li>Alex Sears</li>
<li>Alexander van Ratingen</li>
<li>ami-GS</li>
<li>Antoine Martin</li>
<li>arctic-alpaca</li>
<li>arlecchino</li>
<li>Arthur Woimbée</li>
<li>atouchet</li>
<li>Aurora</li>
<li>badoken</li>
<li>Beep LIN</li>
<li>Ben Sully</li>
<li>Benedikt Weber</li>
<li>Benjamin B</li>
<li>BlackDex</li>
<li>Bonex</li>
<li>Brenden Matthews</li>
<li>Brendon Federko</li>
<li>Brett Buford</li>
<li>Cedric Hutchings</li>
<li>Cezar Halmagean</li>
<li>Charles-Axel Dein</li>
<li>Compro Prasad</li>
<li>cui fliter</li>
<li>Daniel Wiesenberg</li>
<li>David Venhoek</li>
<li>Dimitri Sabadie</li>
<li>Dinu Blanovschi</li>
<li>Dominik Boehi</li>
<li>Doni Rubiagatra</li>
<li>Edgar Onghena</li>
<li>Edwin Svensson</li>
<li>est31</li>
<li>Felix Suominen</li>
<li>Fenhl</li>
<li>Filip Gospodinov</li>
<li>Flying-Toast</li>
<li>Follpvosten</li>
<li>Francois Stephany</li>
<li>Gabriel Fontes</li>
<li>gcarq</li>
<li>George Cheng</li>
<li>Giles Cope</li>
<li>Gonçalo Ribeiro</li>
<li>hiyoko3m</li>
<li>Howard Su</li>
<li>hpodhaisky</li>
<li>Ian Jackson</li>
<li>IFcoltransG</li>
<li>Indosaram</li>
<li>inyourface34456</li>
<li>J. Cohen</li>
<li>Jacob Pratt</li>
<li>Jacob Sharf</li>
<li>Jacob Simpson</li>
<li>Jakub Dąbek</li>
<li>Jakub Wieczorek</li>
<li>James Tai</li>
<li>Jason Hinch</li>
<li>Jeb Rosen</li>
<li>Jeremy Kaplan</li>
<li>Jieyou Xu</li>
<li>Joakim Soderlund</li>
<li>Johannes Liebermann</li>
<li>John-John Tedro</li>
<li>Jonah Brüchert</li>
<li>Jonas Møller</li>
<li>Jonathan Dickinson</li>
<li>Jonty</li>
<li>Joscha</li>
<li>Joshua Nitschke</li>
<li>JR Heard</li>
<li>Juhasz Sandor</li>
<li>Julian Büttner</li>
<li>Juraj Fiala</li>
<li>Kenneth Allen</li>
<li>Kevin Wang</li>
<li>Kian-Meng Ang</li>
<li>Konrad Borowski</li>
<li>Leonora Tindall</li>
<li>Lev Kokotov</li>
<li>lewis</li>
<li>Lionel G</li>
<li>Lucille Blumire</li>
<li>Mai-Lapyst</li>
<li>Manuel</li>
<li>Manuel Transfeld</li>
<li>Marc Schreiber</li>
<li>Marc-Stefan Cassola</li>
<li>Marshall Bowers</li>
<li>Martin1887</li>
<li>Martinez</li>
<li>Matthew Pomes</li>
<li>Maxime Guerreiro</li>
<li>meltinglava</li>
<li>Michael Howell</li>
<li>Mikail Bagishov</li>
<li>mixio</li>
<li>multisn8</li>
<li>Necmettin Karakaya</li>
<li>Ning Sun</li>
<li>Nya</li>
<li>Paolo Barbolini</li>
<li>Paul Smith</li>
<li>Paul van Tilburg</li>
<li>Paul Weaver</li>
<li>pennae</li>
<li>Petr Portnov</li>
<li>philipp</li>
<li>Pieter Frenssen</li>
<li>PROgrm_JARvis</li>
<li>Razican</li>
<li>Redrield</li>
<li>Riley Patterson</li>
<li>Rodolphe Bréard</li>
<li>Roger Mo</li>
<li>RotesWasser</li>
<li>rotoclone</li>
<li>Ruben Schmidmeister</li>
<li>Rudi Floren</li>
<li>Rémi Lauzier</li>
<li>Samuele Esposito</li>
<li>Scott McMurray</li>
<li>Sergio Benitez</li>
<li>Silas Sewell</li>
<li>Soham Roy</li>
<li>Steven Murdoch</li>
<li>Stuart Hinson</li>
<li>Thibaud Martinez</li>
<li>Thomas Eckert</li>
<li>ThouCheese</li>
<li>Tilen Pintarič</li>
<li>timando</li>
<li>timokoesters</li>
<li>toshokan</li>
<li>TotalKrill</li>
<li>Unpublished</li>
<li>Vasili</li>
<li>Vladimir Ignatev</li>
<li>Wesley Norris</li>
<li>xelivous</li>
<li>YetAnotherMinion</li>
<li>Yohannes Kifle</li>
<li>Yusuke Kominami</li>
</ul>
[GitHub discussions]: https://github.com/rwf2/Rocket/discussions
[Matrix channel]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
## Get Involved
Looking to help with Rocket? To contribute code, head over to [GitHub]. To get
involved with the project, see the [RWF2 prelaunch announcement]. We'd love to have you.
[GitHub]: https://github.com/rwf2/Rocket
[RWF2 prelaunch announcement]: ../2023-11-17-rwf2-prelaunch/

View File

@ -1,180 +0,0 @@
[[articles]]
title = """
Rocket v0.5: Stable, Async, Feature-Packed
"""
slug = "2023-11-17-version-0.5"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "Nov 17, 2023"
snippet = """
I am _elated_ to announce that Rocket v0.5 is now generally available. 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 afford toolchain stability.
"""
[[articles]]
title = """
Building a Better Foundation for Rocket's Future
"""
slug = "2023-11-17-rwf2-prelaunch"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "Nov 17, 2023"
snippet = """
Today I'm excited to share plans to launch the Rocket Web Framework Foundation
(RWF2), a 501(c)(3) nonprofit and collective to support Rocket and the
surrounding ecosystem.
"""
[[articles]]
title = """
Rocket's 4th v0.5 Release Candidate
"""
slug = "2023-11-01-version-0.5-rc.4"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "November 01, 2023"
snippet = """
Rocket `0.5.0-rc.4`, a release candidate for Rocket v0.5, is now available.
"""
[[articles]]
title = """
Rocket's 3rd v0.5 Release Candidate
"""
slug = "2023-03-23-version-0.5-rc.3"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "March 23, 2023"
snippet = """
Rocket `0.5.0-rc.3`, a release candidate for Rocket v0.5, is now available.
"""
[[articles]]
title = """
Rocket's 2nd v0.5 Release Candidate
"""
slug = "2022-05-09-version-0.5-rc.2"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "May 09, 2022"
snippet = """
Rocket `0.5.0-rc.2`, a release candidate for Rocket v0.5, is now available.
This release builds on the previous release candidate and brings further
features, improvements, and fixes to Rocket. As before, this is an opportunity
to discover issues with Rocket v0.5 and its documentation before its general
release.
"""
[[articles]]
title = """
Rocket v0.5 Release Candidate
"""
slug = "2021-06-09-version-0.5-rc.1"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "June 09, 2021"
snippet = """
Rocket `0.5.0-rc.1`, a release candidate for Rocket v0.5, is now available.
This release actualizes over _two years_ of development, bringing Rocket to Rust
stable and `async` to Rocket. Every facet, from core request handling to error
messages, has been subjected to Rocket's exacting standards.
"""
[[articles]]
title = """
Rocket v0.4: Typed URIs, Database Support, Revamped Queries, & More!
"""
slug = "2018-12-08-version-0.4"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "December 08, 2018"
snippet = """
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!
"""
[[articles]]
title = "Rocket's 2nd v0.4 Release Candidate"
slug = "2018-11-30-version-0.4-rc-2"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "November 30, 2018"
snippet = """
After a successful and productive initial v0.4 release candidate, I am happy to
announce that the second release candidate for Rocket v0.4 is now available.
This release candidate fixes issues identified during the first release
candidate, introduces further features, and leverages upstream `rustc`
contributions for improved diagnostics and stability. As before, this is an
opportunity to discover issues with Rocket v0.4 and its documentation before its
general release. We encourage all users to migrate their applications to the
second release candidate and report any issues to the [GitHub issue tracker].
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
"""
[[articles]]
title = "Rocket v0.4 Release Candidate"
slug = "2018-10-31-version-0.4-rc"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "October 31, 2018"
snippet = """
I am delighted to announce that a release candidate for Rocket v0.4 is available
today! This release brings over a year of features, improvements, and
refinements, resolving some of the most called for requests and bringing Rocket
measurably closer to stable compatibility.
The release candidate is an opportunity to discover issues with Rocket v0.4 and
its documentation before its general release. We encourage all users to migrate
their applications to the release candidate and report any issues to the [GitHub
issue tracker].
[GitHub issue tracker]: https://github.com/rwf2/Rocket/issues
"""
[[articles]]
title = "Rocket v0.3: Fairings, TLS, Private Cookies"
slug = "2017-07-14-version-0.3"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "July 14, 2017"
snippet = """
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!
"""
[[articles]]
title = "Rocket v0.2: Managed State & More"
slug = "2017-02-06-version-0.2"
author = "Sergio Benitez"
author_url = "https://sergio.bz"
date = "February 06, 2017"
snippet = """
Today marks the first major release since Rocket's debut a little over a month
ago. Rocket v0.2 packs a ton of new features, fixes, and general improvements.
Much of the development in v0.2 was led by the community, either through reports
via the [GitHub issue tracker](https://github.com/rwf2/Rocket/issues)
or via direct contributions. In fact, there have been **20 unique contributors**
to Rocket's codebase since Rocket's initial introduction! Community feedback has
been incredible. As a special thank you, we include the names of these
contributors at the end of this article.
"""

View File

@ -1,69 +0,0 @@
###############################################################################
# Steps to "How Rocket Works"
###############################################################################
[[steps]]
name = "Validation"
color = "blue"
content = '''
First, Rocket validates a matching request by ensuring that all of the types in
a given handler can be derived from the incoming request. If the types cannot be
derived, the request is forwarded to the next matching route until a routes
types validate or there are no more routes to try. If all routes fail, a
customizable **404** error is returned.
```rust
#[post("/user", data = "<new_user>")]
fn new_user(admin: AdminUser, new_user: Form<User>) -> T {
...
}
```
For the `new_user` handler above to be called, the following conditions must
hold:
* The request method must be `POST`.
* The request path must be `/user`.
* The request must contain `data` in its body.
* The request metadata must authenticate an `AdminUser`.
* The request body must be a form that parses into a `User` struct.
'''
[[steps]]
name = "Processing"
color = "purple"
content = '''
Next, the request is processed by an arbitrary handler. This is where most of
the business logic in an application resides, and the part of your applications
youll likely spend the most time writing. In Rocket, handlers are simply
functions - thats it! The only caveat is that the functions return type must
implement the `Responder` trait. The `new_user` function above is an example of
a handler.
'''
[[steps]]
name = "Response"
color = "red"
content = '''
Finally, Rocket responds to the client by transforming the return value of the
handler into an HTTP response. The HTTP response generated from the returned
value depends on the types specific `Responder` trait implementation.
```rust
fn route() -> T { ... }
```
If the function above is used as a handler, for instance, then the type `T` must
implement `Responder`. Rocket provides many useful responder types out of the
box. They include:
* `Json<T>`: Serializes the structure T into JSON and returns it to
the client.
* `Template`: Renders a template file and returns it to the client.
* `Redirect`: Returns a properly formatted HTTP redirect.
* `NamedFile`: Streams a given file to the client with the
Content-Type taken from the files extension.
* `Stream`: Streams data to the client from an arbitrary `Read` value.
* Many Primitive Types: `String`, `&str`, `File`, `Option`, `Result`, and
others all implement the `Responder` trait.
'''