Commit Graph

619 Commits

Author SHA1 Message Date
Sergio Benitez fd294049c7 Update to hyper 1. Enable custom + unix listeners.
This commit completely rewrites Rocket's HTTP serving. In addition to
significant internal cleanup, this commit introduces the following major
features:

  * Support for custom, external listeners in the `listener` module.

    The new `listener` module contains new `Bindable`, `Listener`, and
    `Connection` traits which enable composable, external
    implementations of connection listeners. Rocket can launch on any
    `Listener`, or anything that can be used to create a listener
    (`Bindable`), via a new `launch_on()` method.

  * Support for Unix domain socket listeners out of the box.

    The default listener backwards compatibly supports listening on Unix
    domain sockets. To do so, configure an `address` of
    `unix:path/to/socket` and optional set `reuse` to `true` (the
    default) or `false` which controls whether Rocket will handle
    creating and deleting the unix domain socket.

In addition to these new features, this commit makes the following major
improvements:

  * Rocket now depends on hyper 1.

  * Rocket no longer depends on hyper to handle connections. This allows
    us to handle more connection failure conditions which results in an
    overall more robust server with fewer dependencies.

  * Logic to work around hyper's inability to reference incoming request
    data in the response results in a 15% performance improvement.

  * `Client`s can be marked secure with `Client::{un}tracked_secure()`,
    allowing Rocket to treat local connections as running under TLS.

  * The `macros` feature of `tokio` is no longer used by Rocket itself.
    Dependencies can take advantage of this reduction in compile-time
    cost by disabling the new default feature `tokio-macros`.

  * A new `TlsConfig::validate()` method allows checking a TLS config.

  * New `TlsConfig::{certs,key}_reader()`,
    `MtlsConfig::ca_certs_reader()` methods return `BufReader`s, which
    allow reading the configured certs and key directly.

  * A new `NamedFile::open_with()` constructor allows specifying
    `OpenOptions`.

These improvements resulted in the following breaking changes:

  * The MSRV is now 1.74.
  * `hyper` is no longer exported from `rocket::http`.
  * `IoHandler::io` takes `Box<Self>` instead of `Pin<Box<Self>>`.
    - Use `Box::into_pin(self)` to recover the previous type.
  * `Response::upgrade()` now returns an `&mut dyn IoHandler`, not
    `Pin<& mut _>`.
  * `Config::{address,port,tls,mtls}` methods have been removed.
    - Use methods on `Rocket::endpoint()` instead.
  * `TlsConfig` was moved to `tls::TlsConfig`.
  * `MutualTls` was renamed and moved to `mtls::MtlsConfig`.
  * `ErrorKind::TlsBind` was removed.
  * The second field of `ErrorKind::Shutdown` was removed.
  * `{Local}Request::{set_}remote()` methods take/return an `Endpoint`.
  * `Client::new()` was removed; it was previously deprecated.

Internally, the following major changes were made:

  * A new `async_bound` attribute macro was introduced to allow setting
    bounds on futures returned by `async fn`s in traits while
    maintaining good docs.

  * All utility functionality was moved to a new `util` module.

Resolves #2671.
Resolves #1070.
2024-01-29 22:38:55 -08:00
Sergio Benitez e9b568d9b2 Fixup docs for 'proxy_proto_header'. 2024-01-22 18:41:20 -08:00
Arjen 5c85ea3db5 Support configurable 'X-Forwarded-Proto'.
Co-authored-by: Sergio Benitez <sb@sergio.bz>
2024-01-22 18:41:20 -08:00
Sergio Benitez 915c1181da Forward whole-form errors in 'FromForm' derive.
Resolves #2672.
2024-01-17 12:15:01 -08:00
Sergio Benitez b3abc760ae Introduce chainable data transformers.
Resolves #775.
2023-12-27 20:02:14 -08:00
Paul Lietar 67ad8316dc Ensure 'TempFile' flushes when persisted.
Tokio's `File::write_all()` method has an unexpected quirk: it doesn't
actually write all the requested content to the file when the returned
future resolves. Instead, the write is attempted and queued. This means
that the `persist()` method can resolve without the data being persisted
to the file system. Subsequent reads of the ostensibly written-to file
can thus fail to contain the expected data.

An call to `flush()` following `write_all()` would circumvent the issue.
Alternatively, calling `fs::write()` actually writes to the file system
before returning and requires fewer lines of code. This commit thus
swaps the call to `write_all()` with `fs::write()`.
2023-12-19 16:01:00 -08:00
Martyn ae7e0040e8 Document "reconnect ad-infinitum" SSE pitfall. 2023-12-19 14:41:28 -08:00
Sergio Benitez 7cf8b1368f Doc, fix, and test 'cli_colors' deserialization. 2023-12-18 16:37:56 -08:00
Lev Kokotov f4e8987a46 Make 'cli_colors' an enum, add "always" option.
Resolves #2649.
2023-12-18 16:34:13 -08:00
cui fliter 485c490b1f Fix typos: 'preceeding', 'occured'. 2023-12-18 15:39:09 -08:00
Sergio Benitez 9c2b74b23c Upgrade 'rustls' to '0.22'.
In the process, the following improvements were also made:

  * Error messages related to TLS were improved.
  * 'Redirector' in 'tls' example was improved.
2023-12-15 16:50:08 -08:00
Sergio Benitez a59f3c4c1f Fix min dependency versions. Update MSRV to 1.64.
Also includes a work-around for a buggy `format_args!` macro found in
rustc 1.67 and 1.68.

Resolves #2670.
2023-12-13 17:49:05 -08:00
Sergio Benitez e526fa04d4 Update 'SergioBenitez/Rocket' to 'rwf2/Rocket'.
Resolves rwf2/rwf2#5.
2023-11-21 16:32:25 +01:00
Sergio Benitez 44ac3f1eb6 Move to 0.6.0-dev on master. 2023-11-18 11:30:50 +01:00
Sergio Benitez 6d467564d6 Update version numbers for 0.5.0. 2023-11-17 17:04:59 +01:00
Sergio Benitez 124ec94b46 Fix typos.
Co-authored-by: cui fliter <imcusg@gmail.com>
2023-11-17 17:04:49 +01:00
Sergio Benitez a1c29c735c New version: 0.5.0-rc.4.
New contrib versions: 0.1.0-rc.4.
2023-11-17 17:04:44 +01:00
Sergio Benitez 15637186ba Document '&[u8]' form/data guard, limits. 2023-11-01 18:51:26 -05:00
Sergio Benitez fa0c778276 Set 'SameSite' to 'Lax' on removal cookies.
This avoids needless warnings from certain browsers.
2023-11-01 12:08:26 -05:00
Sergio Benitez fbd1a0d069 Improve forwarding status code precision.
Previously, the `NotFound` status code was used to signal many kinds of
recoverable, forwarding errors. This included validation errors, incorrect
Content-Type errors, and more.

This commit modifies the status code used to forward in these instances to more
precisely indicate the forwarding condition. In particular:

  * Parameter `FromParam` errors now forward as 422 (`UnprocessableEntity`).
  * Query paramater errors now forward as 422 (`UnprocessableEntity`).
  * Use of incorrect form content-type forwards as 413 (`UnsupportedMediaType`).
  * `WebSocket` guard now forwards as 400 (`BadRequest`).
  * `&Host`, `&Accept`, `&ContentType`, `IpAddr`, and `SocketAddr` all forward
    with a 500 (`InternalServerError`).

Additionally, the `IntoOutcome` trait was overhauled to support functionality
previously offered by methods on `Outcome`. The `Outcome::forward()` method now
requires a status code to use for the forwarding outcome.

Finally, logging of `Outcome`s now includes the relevant status code.

Resolves #2626.
2023-10-31 18:44:37 -05:00
Sergio Benitez c90812051e Rename 'Outcome::Failure' to 'Outcome::Error'.
The primary motivation is to deconflate the leading `F`s in `Failure` and
`Forward`. In particular, when using a generics, we used `F` for forward, which
could easily be confused for `F` for `Failure`. This resolves the conflation.
2023-10-31 12:17:28 -05:00
Ruben Schmidmeister 58adc48965 Set 'color-scheme' in default catcher HTML. 2023-10-16 15:29:51 -07:00
Sergio Benitez ae68742048 Update dependencies.
* notify: 5 -> 6
  * indexmap: 1 -> 2
  * cookie: 0.18.0-rc.0 -> 0.18
2023-10-09 17:03:21 -07:00
Sergio Benitez 47faac6080 Document that '&[u8]' is a form guard. 2023-10-02 11:59:03 -07:00
Sergio Benitez 5d31ad4efb Update 'cookie' to 0.18. 2023-09-28 23:50:29 -07:00
Sergio Benitez f41474dd61 Fix broken links between codegen and http crates.
Also resolves link warnings emitted by rustdoc.

Closes #2594
2023-09-20 17:17:22 -07:00
Sergio Benitez ddeac5ddcf Remove unnecessary braces. 2023-08-14 14:16:56 -04:00
Sergio Benitez c337f75f32 Fix 'get_pending()' docs, functionality.
The `get_pending()` method now properly decrypts private cookies that were
present in the jar originally.

Resolves #2591.
2023-08-10 16:22:28 -04:00
Sergio Benitez c2936fcb1e Update 'yansi' to 1.0.0-rc. 2023-07-11 13:18:35 -07:00
Sergio Benitez e3f1b53efa Update 'state' to 0.6. 2023-05-25 11:54:27 -07:00
Sergio Benitez b6b060f75c Document built-in data guards. 2023-05-18 18:22:40 -07:00
Sergio Benitez 29cd271f8a Only extract needed values in 'async_main'.
Previously, `async_main` would extract a full `Config`. This mean that values
like `address` were read and parsed even when they were unused. Should they
exist and be malformed, a configuration error would needlessly arise.

This commit fixes this by only extract values that are subsequently used.
2023-05-18 17:33:57 -07:00
Sergio Benitez f1f533c1e5 Improve and fix panic in 'AdHoc::normalizer()'.
The normalizer now handles more cases.
2023-05-05 11:41:44 -07:00
Sergio Benitez 311a82e3d7 Add 'Error::pretty_print()'. 2023-05-05 11:41:10 -07:00
Sergio Benitez 615e70fdad Log config provenance in debug.
This helps identify configuration issues by printing the source of every
configuration value used by Rocket.
2023-05-04 18:32:27 -07:00
Sergio Benitez db535812b0 Factor out 'Catcher' rank computation. 2023-05-04 18:32:25 -07:00
Sergio Benitez d24b5d4d6d Handle more cases in 'AdHoc::normalizer()'.
The compatibility normalizer previously missed or was overly egregious
in several cases. This commit resolves those issue. In particular:

  * Only request URIs that would not match any route are normalized.

  * Synthetic routes are added to the igniting `Rocket` so that requests
    with URIs of the form `/foo` match routes with URIs of the form
    `/foo/<b..>`, as they did prior to the trailing slash overhaul.

Tests are added for all of these cases.
2023-05-04 17:30:37 -07:00
Sergio Benitez 541952bc58 Paint route URI query parts yellow. 2023-05-04 17:30:23 -07:00
Sergio Benitez 56cf905c6e Introduce more flexible mounting.
Prior to this commit, a route with a URI of `/` could not be mounted in
such a way that the resulting effective URI contained a trailing slash.
This commit changes the semantics of mounting so that mounting such a
route to a mount point with a trailing slash yields an effective URI
with a trailing slash. When mounted to points without a trailing slash,
the effective URI does not have a trailing slash.

This commit also introduces the `Route::rebase()` and
`Catcher::rebase()` methods for easier rebasing of existing routes and
catchers.

Finally, this commit improves logging such that mount points of `/`
are underlined in the logs.

Tests and docs were added and modified as necessary.

Resolves #2533.
2023-05-03 20:03:45 -07:00
Sergio Benitez 9b0564ed27 Tidy custom forward status changes, update docs. 2023-04-11 12:55:57 -07:00
Benedikt Weber 055ad107df Allow status customization in 'Forward' outcomes.
Prior to this commit, all forward outcomes resulted in a 404. This
commit changes request and data guards so that they are able to provide
a `Status` on `Forward` outcomes. The router uses this status, if the
final outcome is to forward, to identify the catcher to invoke.

The net effect is that guards can now customize the status code of a
forward and thus the error catcher invoked if the final outcome of a
request is to forward.

Resolves #1560.
2023-04-11 12:47:20 -07:00
Sergio Benitez b61ac6eb18 Expose 'Route', 'Catcher' collision and matching.
This commit exposes four new methods:

  * `Route::collides_with(&Route)`
  * `Route::matches(&Request)`
  * `Catcher::collides_with(&Catcher)`
  * `Catcher::matches(Status, &Request)`

Each method checks the corresponding condition: whether two routes
collide, whether a route matches a request, whether two catchers
collide, and whether a catcher matches an error arising from a request.

This functionality is used internally by Rocket to make routing
decisions. By exposing these methods, external libraries can use
guaranteed consistent logic to check the same routing conditions.

Resolves #1561.
2023-04-10 22:00:54 -07:00
Sergio Benitez 0c80f7d9e0 Return 'Path' from 'Catcher::base()'. 2023-04-10 13:42:20 -07:00
Sergio Benitez c13a6c6a79 Emit warning when 'String' is used as a parameter.
The warning is only emitted when Rocket is compiled in debug.
2023-04-10 13:38:51 -07:00
Sergio Benitez 3a44b1b28e Hide 'RouteUri' fields to ensure URI coherence.
Prior to this commit, several `RouteUri` fields were public, allowing
those values to be changed at will. These changes were at times not
reflected by the rest of the library, meaning that the values in the
route URI structure for a route became incoherent with the reflected
values. This commit makes all fields private, forcing all changes to go
through methods that can ensure coherence. All values remain accessible
via getter methods.
2023-04-10 13:26:54 -07:00
Sergio Benitez 51ed332127 Make trailing slashes significant during routing.
This commit modifies request routing in a backwards incompatible manner.
The change is summarized as: trailing slashes are now significant and
never transparently disregarded. This has the following implications,
all representing behavior that differs from that before this change:

  * Route URIs with trailing slashes (`/foo/`, `/<a>/`) are legal.
  * A request `/foo/` is routed to route `/foo/` but not `/foo`.
  * Similarly, a request `/bar/` is routed to `/<a>/` but not `/<a>`.
  * A request `/bar/foo` is not routed to `/<a>/<b>/<c..>`.

A new `AdHoc::uri_normalizer()` fairing was added that recovers the
previous behavior.

In addition to the above, the `Options::NormalizeDirs` `FileServer`
option is now enabled by default to remain consistent with the above
changes and reduce breaking changes at the `FileServer` level.
2023-04-10 12:40:39 -07:00
Sergio Benitez 908a918e8b Fuzz to validate routing collision safety.
The fuzzing target introduced in this commit attemps to assert
"collision safety". Formally, this is the property that:

  matches(request, route) := request is matched to route
  collides(route1, route2) := there is a a collision between routes

  forall requests req. !exist routes r1, r2 s.t.
    matches(req, r1) AND matches(req, r2) AND not collides(r1, r2)

Alternatively:

  forall requests req, routes r1, r2.
    matches(req, r1) AND matches(req, r2) => collides(r1, r2)

The target was run for 20 CPU hours without failure.
2023-04-07 20:27:56 -07:00
Sergio Benitez ac0a77bae2 Allow dynamic parameters to match empty segments.
The net effect of this commit is three-fold:

  * A request to `/` now matches `/<a>`. `/foo/` matches `/<a>/<b>`.
  * A segment matched to a dynamic parameter may be empty.
  * A request to `/foo/` no longer matches `/foo` or `/<a>`. Instead,
    such a request would match `/foo/<a>` or `/foo/`.

The `&str` and `String` parameter guards were updated to reflect this
change: they now error, with a newly introduced error type `Empty` in
the `rocket::error` module, when the parameter is empty. As this was the
only built-in parameter guard that would be effected by this change (all
other guards already required nonempty parameters to succeed), the
majority of applications will see no effect as a result.

For applications wanting the previous functionality, a new
`AdHoc::uri_normalizer()` fairing was introduced.
2023-04-07 20:00:09 -07:00
Sergio Benitez 0a56312607 Implement more conservative URI normalization.
* Trailing slashes are now allowed in all normalized URI paths, except
    for route attribute URIs: `/foo/` is considered normalized.
  * Query parts of URIs may now be empty: `/foo?` and `/foo/?` are now
    considered normalized.
  * The `base` field of `Catcher` is now only accessible via a new
    getter method: `Catcher::base()`.
  * `RawStr::split()` returns a `DoubleEndedIterator`.
  * Introduced a second normalization for `Origin`, "nontrailing", and
    associated methods: `Origin::normalize_nontrailing()`, and
    `Origin::is_normalized_nontrailing()`.
  * Added `Origin::has_trailing_slash()`.
  * The `Segments<Path>` iterator will now return an empty string if
    there is a trailing slash in the referenced path.
  * `Segments::len()` is now `Segments::num()`.
  * Added `RawStr::trim()`.

Resolves #2512.
2023-04-07 19:59:57 -07:00
Sergio Benitez a82508b403 Set 'Secure' cookie flag by default under TLS.
If TLS is enabled and active, Rocket will now set the `Secure` cookie
attribute by default.

Resolves #2425.
2023-04-05 13:15:24 -07:00