Commit Graph

126 Commits

Author SHA1 Message Date
Sergio Benitez 0bdb6b7bc7 Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.

This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:

  1. A instance of 'Rocket' with async attach fairings requires an async
     runtime to be constructed.
  2. The instance is accessible in non-async contexts.
  3. The async attach fairings have no runtime in which to be run.

Here's an example:

```rust
let rocket = rocket::ignite()
    .attach(AttachFairing::from(|rocket| async {
        Ok(rocket.manage(load_from_network::<T>().await))
    }));

let state = rocket.state::<T>();
```

This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.

The new Rocket application lifecycle is this:

  * Build - A Rocket instance is constructed. No fairings are run.
  * Ignition - All launch fairings are run.
  * Liftoff - If all launch fairings succeeded, the server is started.

New 'liftoff' fairings are run in this third phase.
2021-04-07 23:09:00 -07:00
Sergio Benitez 17dd8dafd0 Move examples to their own workspace.
This allows us to test all of the "core" crates (and the guide) by
testing the root workspace, and all of the examples by testing in the
examples workspace.
2021-03-09 21:57:30 -08:00
Sergio Benitez 63a14525d8 UTF-8 routes. Forms revamp. Temp files. Capped.
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.
2021-03-04 01:51:21 -08:00
Jeb Rosen 9d45e786bb Update 'rand' dependency to 0.8. 2021-02-28 16:34:38 -08:00
Sergio Benitez 374ad8804c Fix 'legacy_derive_helpers' warning in todo example. 2021-02-22 19:33:50 -08:00
atouchet 0c5e184299 Update various dead hyperlinks; change some links from http to https. 2021-02-20 12:01:44 -08:00
Sergio Benitez ec9b5816a8 Remove 'rocket::inspect()', 'Cargo'.
This commit reverts most of dea940c7 and d89c7024. The "fix" is to run
attach fairings on a new thread. If a runtime is already running, it is
used. Otherwise, the future is executed in a single-threaded executor.
2020-10-22 03:27:04 -07:00
Sergio Benitez 5d9035ddc1 Keep an op-log for sync 'CookieJar'.
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.
2020-10-14 21:37:16 -07:00
Sergio Benitez dee11966b6 Borrow 'self' in 'Connection::run()'.
This simulates the pre-async behavior of serialization attempts to use a
connection by using an `async` Mutex.
2020-09-10 03:34:26 -07:00
Jeb Rosen bc8c5b9ee2 Use 'spawn_blocking' in '#[database]'.
The connection guard type generated by `#[database]` no longer
implements `Deref` and `DerefMut`. Instead, it provides an `async fn
run()` that gives access to the underlying connection on a closure run
through `spawn_blocking()`.

Additionally moves most of the implementation of `#[database]` out
of generated code and into library code for better type-checking.
2020-09-10 03:34:26 -07:00
Sergio Benitez a115eaa633 Add 'serve::crate_relative!' for relative paths.
The macro generates crate-relative paths for easier serving of files
stored relative to the crate root.
2020-07-23 20:12:17 -07:00
Sergio Benitez adc79016cd Rearrange top-level exports. Use '#[launch]'.
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.
2020-07-22 16:10:02 -07:00
Jeb Rosen 31ddb0de45 Use 'serde' 'derive' feature, not 'serde_derive'. 2020-07-22 12:28:18 -07:00
Jeb Rosen cde0b1cefd Upgrade 'parking_lot' to 0.11 in the 'todo' example.
Also remove the use of the 'nightly' feature.
2020-07-21 10:54:07 -07:00
Sergio Benitez 62355b424f Remove use of stable 'proc_macro_hygiene' feature. 2020-07-11 10:48:08 -07:00
Jeb Rosen 06975bfaea Use the blocking testing API everywhere.
Co-authored-by: Sergio Benitez <sb@sergio.bz>
2020-07-11 09:24:30 -07:00
Sergio Benitez 03127f4dae Add blocking variant of 'local'.
This commit adds the 'local::blocking' module and moves the existing
asynchronous testing to 'local::asynchronous'. It also includes several
changes to improve the local API, bringing it to parity (and beyond)
with master. These changes are:

  * 'LocalRequest' implements 'Clone'.
  * 'LocalResponse' doesn't implement 'DerefMut<Target=Response>'.
    Instead, direct methods on the type, such as 'into_string()', can
    be used to read the 'Response'.
  * 'Response::body()' returns an '&ResponseBody' as opposed to '&mut
    ResponseBody', which is returned by a new 'Response::body_mut()'.
  * '&ResponseBody' implements 'known_size()` to retrieve a body's size,
    if it is known.

Co-authored-by: Jeb Rosen <jeb@jebrosen.com>
2020-07-11 09:24:30 -07:00
Sergio Benitez 12308b403f Add '#[rocket::launch]' attribute.
The attribute is applied everywhere it can be across the codebase and is
the newly preferred method for launching an application. This commit
also makes '#[rocket::main]` stricter by warning when it is applied to
functions other than 'main'.
2020-07-11 09:24:29 -07:00
Jeb Rosen bc1b90cbdb Add '#[rocket::main]' attribute and make 'launch()' an 'async fn'.
'#[rocket::main]' works like '#[rocket::async_test]', but it uses
tokio's multithreaded scheduler.
2020-07-11 09:24:29 -07:00
Jeb Rosen b0238e5110 Make 'Fairing::on_attach()' async.
This transitively requires that 'Rocket::inspect()', 'Client::new()',
and 'Client::untracked()' also become async.
2020-07-11 09:24:29 -07:00
Jeb Rosen dea940c7a8 Defer execution of operations on 'Rocket' until their effects will be
observed.

This is a prerequisite for async on_attach fairings. 'Rocket' is now a
builder wrapper around the 'Manifest' type, with operations being
applied when needed by 'launch()', 'Client::new()', or 'inspect()'.
'inspect()' returns an '&Manifest', which now provides the methods that
could be called on an '&Rocket'.
2020-07-11 09:24:29 -07:00
Jeb Rosen 7c4cd068d1 Update for rust-lang/rust#64856.
Raise the nightly version to one that accepts '...(format!(...)).await'.

This additionally reverts commit bdbf80f2da.
2020-07-11 09:24:29 -07:00
Jeb Rosen 62a99e9e49 Fix a minor compilation error, possibly caused by rust-lang/rust#64292. 2020-07-11 09:24:28 -07:00
Jacob Pratt cd6a80c230 Implement an API to request a graceful shutdown.
Additionally listen for Ctrl-C as a shutdown signal by default.
2020-07-11 09:24:28 -07:00
Jeb Rosen 560f0977d3 Revamp testing system for async.
* body_string_wait and body_bytes_wait are removed; use `.await` instead
* `dispatch()` is now an async fn and must be .await-ed
* Add `#[rocket::async_test]` macro, similar in purpose to `tokio::test`
* Tests now use either `rocket::async_test(async { })` or
  `#[rocket::async_test]` in order to `.await` the futures returned
  from `dispatch()` and `body_{string,bytes}()`
* Update 'test.sh' to reflect the tests that should be passing.

Broken:

* Cloned dispatch and mut_dispatch() with a live previous response now both fail, due to a (partial) check for mutable aliasing in LocalRequest.
* Some tests are still failing and need example-specific changes.
2020-07-11 09:24:28 -07:00
Jacob Pratt e44c5896b8 Remove stabilized 'async_await' feature gate and update the minimum nightly version. 2020-07-11 09:24:28 -07:00
Jeb Rosen 5d439bafc0 Convert core to async and add support for async routes.
Minimum rustc bump required for rust-lang/rust#61775
2020-07-11 09:24:28 -07:00
Sergio Benitez e1a3d2b6e8 Fix minor formatting issues in 'todo' example. 2020-06-08 12:18:34 -07:00
Sergio Benitez a4f5be93ef Clean up todo example. 2020-06-08 12:12:02 -07:00
Cedric Hutchings da34b66eb4 Use 'Result's instead of 'bool's in todo example. 2020-06-08 12:11:41 -07:00
Razican f4bb8bb511 Update depedencies:
* contrib: 'rmp-serde', 'tera', 'memcache', 'mysql', 'postgres', 'redis'.
* examples: 'parking-lot', 'rand'
2020-01-19 11:01:11 -08:00
Jeb Rosen 3e4f8453ce Remove use of the 'decl_macro' feature.
Also removes one internal use in the 'typed-uris' codegen test.
2019-07-19 11:39:56 -07:00
Sergio Benitez 7f2c9f426c Fix tests for Windows. 2019-07-06 00:59:01 -07:00
Jeb Rosen d9f989a496 Migrate all examples to Rust 2018. 2019-06-25 11:30:43 -07:00
Sergio Benitez 23f5ebcc4f Update 'parking_lot' to 0.8 in 'todo' example. 2019-05-16 13:50:54 -07:00
jeb b9c3a5c64b Remove test bootstrapping. 2019-02-08 16:50:14 -08:00
Sergio Benitez 76c830a467 Update 'base64', 'crossbeam', 'rand' dependencies. 2018-11-18 03:47:12 -08:00
Sergio Benitez f857f81d9c Import 'database' attribute with 'macro_use'. 2018-10-09 04:31:09 -07:00
Sergio Benitez 9cb031a47d Modularize contrib. 2018-10-09 04:31:09 -07:00
Sergio Benitez 2839aca8ce Update features for latest nightly. 2018-10-09 04:31:09 -07:00
Sergio Benitez 61f107f550 Reimplement route attribute as a proc-macro.
This commits also implement the query reform from #608. It also consists
of many, many breaking changes. Among them are:

  * Query parts in route paths use new query reform syntax.
  * Routing for queries is now lenient.
    - Default ranking has changed to reflect query reform.
  * Format routing matching has been fixed.
    - Routes with formats matching "accept" will always collide.
    - Routes with formats matching "content-type" require requests to
      have an equivalent content-type header to match.
    - Requests with imprecise content-types are treated as not having a
      content-type.
  * Generated routes and catchers respect visibility modifiers.
  * Raw getter methods from request were renamed and retooled.
    - In particular, the index parameter is based on segments in the
      route path, not dynamic parameters.
  * The method-based attributes no longer accept a keyed 'path'.
  * The 'rocket_codegen' crate is gone and will no longer be public.
  * The 'FormItems' iterator emits values of type 'FormItem'.
    - The internal form items' string can no longer be retrieved.
  * In general, routes are more strictly validated.
  * Logging from codegen now funnels through logging infrastructure.
  * Routing has been optimized by caching routing metadata.

Resolves #93.
Resolves #608.
Resolves #693.
Resolves #476.
2018-10-09 04:18:04 -07:00
jeb 8e779610c4 Reimplement 'routes!' and 'catchers!' as proc-macros. 2018-09-16 18:52:23 -07:00
jeb 30cf75335b Embed the diesel database migrations in the `todo` example.
`diesel_cli` is no longer needed for running the example or its tests.
2018-09-11 12:38:10 -07:00
jeb 1da506ea5d Remove use of the 'const_fn' feature. 2018-09-03 19:41:31 -07:00
Sergio Benitez cb18954ef2 Use 'StaticFiles' in todo example. 2018-08-24 14:00:36 -07:00
Sergio Benitez fd6d577158 Remove 'use_extern_macros' feature: stabilized. 2018-08-18 17:06:28 -07:00
Sergio Benitez fe9fad339e Clean up connection pooling documentation. 2018-08-15 23:31:49 -07:00
Eric Dattore 60b9f06407 Implement connection pooling support in contrib.
Resolves #167.
2018-08-15 22:11:53 -07:00
Sergio Benitez d7f6d82fe4 Implement 'FromForm[Value]', 'Responder' proc-macro derives.
This completes the migration of custom derives to proc-macros, removing
the need for the `custom_derive` feature in consumer code. This commit
also includes documentation, unit tests, and compile UI tests for each
of the derives.

Additionally, this commit improves the existing `FromForm` and
`FromFormValue` derives. The generated code for `FromForm` now returns
an error value indicating the error condition. The `FromFormValue`
derive now accepts a `form` attribute on variants for specifying the
exact value string to match against.

Closes #590.
Closes #670.
2018-08-06 19:58:07 -07:00
Sergio Benitez b0f86dcba0 Fix URI normalization checks in 'Rocket::mount()'. 2018-07-29 18:40:24 -07:00