So. Many. Changes.
This is an insane commit: simultaneously one of the best (because of all
the wonderful improvements!) and one of the worst (because it is just
massive) in the project's history.
Routing:
* All UTF-8 characters are accepted everywhere in route paths. (#998)
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
Forms Revamp
* All form related types now reside in a new `form` module.
* Multipart forms are supported. (resolves#106)
* Collections are supported in forms and queries. (resolves#205)
* Nested structures in forms and queries are supported. (resolves#313)
* Form fields can be ad-hoc validated with `#[field(validate = expr)]`.
* `FromFormValue` is now `FromFormField`, blanket implements `FromForm`.
* Form field values are always percent-decoded apriori.
Temporary Files
* A new `TempFile` data and form guard allows streaming data directly to a
file which can then be persisted.
* A new `temp_dir` config parameter specifies where to store `TempFile`.
* The limits `file` and `file/$ext`, where `$ext` is the file extension,
determines the data limit for a `TempFile`.
Capped
* A new `Capped` type is used to indicate when data has been truncated due to
incoming data limits. It allows checking whether data is complete or
truncated.
* `DataStream` methods return `Capped` types.
* `DataStream` API has been revamped to account for `Capped` types.
* Several `Capped<T>` types implement `FromData`, `FromForm`.
* HTTP 413 (Payload Too Large) errors are now returned when data limits are
exceeded. (resolves#972)
Hierarchical Limits
* Data limits are now hierarchical, delimited with `/`. A limit of `a/b/c`
falls back to `a/b` then `a`.
Core
* `&RawStr` no longer implements `FromParam`.
* `&str` implements `FromParam`, `FromData`, `FromForm`.
* `FromTransformedData` was removed.
* `FromData` gained a lifetime for use with request-local data.
* The default error HTML is more compact.
* `&Config` is a request guard.
* The `DataStream` interface was entirely revamped.
* `State` is only exported via `rocket::State`.
* A `request::local_cache!()` macro was added for storing values in
request-local cache without consideration for type uniqueness by using a
locally generated anonymous type.
* `Request::get_param()` is now `Request::param()`.
* `Request::get_segments()` is now `Request::segments()`, takes a range.
* `Request::get_query_value()` is now `Request::query_value()`, can parse any
`FromForm` including sequences.
* `std::io::Error` implements `Responder` like `Debug<std::io::Error>`.
* `(Status, R)` where `R: Responder` implements `Responder` by overriding the
`Status` of `R`.
* The name of a route is printed first during route matching.
* `FlashMessage` now only has one lifetime generic.
HTTP
* `RawStr` implements `serde::{Serialize, Deserialize}`.
* `RawStr` implements _many_ more methods, in particular, those related to the
`Pattern` API.
* `RawStr::from_str()` is now `RawStr::new()`.
* `RawStr::url_decode()` and `RawStr::url_decode_lossy()` only allocate as
necessary, return `Cow`.
* `Status` implements `Default` with `Status::Ok`.
* `Status` implements `PartialEq`, `Eq`, `Hash`, `PartialOrd`, `Ord`.
* Authority and origin part of `Absolute` can be modified with new
`Absolute::{with,set}_authority()`, `Absolute::{with,set}_origin()` methods.
* `Origin::segments()` was removed in favor of methods split into query and
path parts and into raw and decoded versions.
* The `Segments` iterator is smarter, returns decoded `&str` items.
* `Segments::into_path_buf()` is now `Segments::to_path_buf()`.
* A new `QuerySegments` is the analogous query segment iterator.
* Once set, `expires` on private cookies is not overwritten. (resolves#1506)
* `Origin::path()` and `Origin::query()` return `&RawStr`, not `&str`.
Codegen
* Preserve more spans in `uri!` macro.
* Preserve spans `FromForm` field types.
* All dynamic parameters in a query string must typecheck as `FromForm`.
* `FromFormValue` derive removed; `FromFormField` added.
* The `form` `FromForm` and `FromFormField` field attribute is now named
`field`. `#[form(field = ..)]` is now `#[field(name = ..)]`.
Contrib
* `Json` implements `FromForm`.
* `MsgPack` implements `FromForm`.
* The `json!` macro is exported as `rocket_contrib::json::json!`.
* Added clarifying docs to `StaticFiles`.
Examples
* `form_validation` and `form_kitchen_sink` removed in favor of `forms`.
* The `hello_world` example uses unicode in paths.
* The `json` example only allocates as necessary.
Internal
* Codegen uses new `exports` module with the following conventions:
- Locals starts with `__` and are lowercased.
- Rocket modules start with `_` and are lowercased.
- `std` types start with `_` and are titlecased.
- Rocket types are titlecased.
* A `header` module was added to `http`, contains header types.
* `SAFETY` is used as doc-string keyword for `unsafe` related comments.
* The `Uri` parser no longer recognizes Rocket route URIs.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes#1420.
This commit completely overhauls Rocket's configuration systems, basing
it on the new Figment library. It includes many breaking changes
pertaining to configuration. They are:
* "Environments" are replaced by "profiles".
* 'ROCKET_PROFILE' takes the place of 'ROCKET_ENV'.
* Profile names are now arbitrary, but 'debug' and 'release' are given
special treatment as default profiles for the debug and release
compilation profiles.
* A 'default' profile now sits along-side the meta 'global' profile.
* The concept of "extras" is no longer present; users can extract any
values they want from the configured 'Figment'.
* The 'Poolable' trait takes an '&Config'.
* The 'secrets' feature is disabled by default.
* It is a hard error if 'secrets' is enabled under the 'release'
profile and no 'secret_key' is configured.
* 'ConfigBuilder' no longer exists: all fields of 'Config' are public
with public constructors for each type.
* 'keep_alive' is disabled with '0', not 'false' or 'off'.
* Inlined error variants into the 'Error' structure.
* 'LoggingLevel' is now 'LogLevel'.
* Limits can now be specified in SI units: "1 MiB".
The summary of other changes are:
* The default config file can be configured with 'ROCKET_CONFIG'.
* HTTP/1 and HTTP/2 keep-alive configuration is restored.
* 'ctrlc' is now a recognized config option.
* 'serde' is now a core dependency.
* TLS misconfiguration errors are improved.
* Several example use '_' as the return type of '#[launch]' fns.
* 'AdHoc::config()' was added for simple config extraction.
* Added more documentation for using 'Limits'.
* Launch information is no longer treated specially.
* The configuration guide was rewritten.
Resolves#852.
Resolves#209.
Closes#1404.
Closes#652.
In brief, this commit:
* Updates to the latest upstream 'cookie', fixing a memory leak.
* Make changes to 'CookieJar' observable only through 'pending()'.
* Deprecates 'Client::new()' in favor of 'Client::tracked()'.
* Makes 'dispatch()' on tracked 'Client's synchronize on cookies.
* Makes 'Client::untracked()' actually untracked.
This commit updates to the latest 'cookie' which removes support for
'Sync' cookie jars. Instead of relying on 'cookie', this commit
implements an op-log based 'CookieJar' which internally keeps track of
changes. The API is such that changes are only observable through
specialized '_pending()' methods.
The user-facing changes effected by this commit are:
* The 'http::Cookies<'_>' guard is now '&http::CookieJar<'_>'.
* The "one-at-a-time" jar restriction is no longer imposed.
* 'CookieJar' retrieval methods return 'http::CookieCrumb'.
* The 'private-cookies' feature is now called 'secrets'.
* Docs flag private cookie methods with feature cfg.
* Local, async request dispatching is never serialized.
* 'Client::cookies()' returns the tracked 'CookieJar'.
* 'LocalResponse::cookies()' returns a 'CookieJar'.
* 'Response::cookies()' returns an 'impl Iterator'.
* A path of '/' is set by default on all cookies.
* 'SameSite=strict' is set by default on all cookies.
* 'LocalRequest::cookies()' accepts any 'Cookie' iterator.
* The 'Debug' impl for 'Request' prints the cookie jar.
Resolves#1332.
The bulk of the changes in this commit are for creating an
'ErrorHandler' trait that works like the 'Handler' trait, but for
errors. Furthermore, Rocket's default catcher now responds with a JSON
payload if the preferred 'Accept' media type is JSON.
This commit also fixes a bug in 'LocalRequest' where the internal
'Request' contained an correct 'URI'.
This commits makes the following high-level changes:
* 'ShutdownHandle' is renamed to 'Shutdown'.
* 'Rocket::shutdown_handle()' is renamed to 'Rocket::shutdown()'.
* '#[launch]` is preferred to '#[rocket::launch]'.
* Various docs phrasings are improved.
* Fixed various broken links in docs.
This commits rearranges top-level exports as follows:
* 'shutdown' module is no longer exported.
* 'Shutdown' is exported from the crate root.
* 'Outcome' is not longer exported from the root.
* 'Handler', 'ErrorHandler' are no longer exported from the root.