Commit Graph

25 Commits

Author SHA1 Message Date
Sergio Benitez 72c91958b7 Support routes that match any method.
This commit introduces support for method-less routes and route
attributes, which match _any_ valid method: `#[route("/")]`. The `Route`
structure's `method` field is now accordingly of type `Option<Route>`.

The syntax for the `route` attribute has changed in a breaking manner.
To set a method, a key/value of `method = NAME` must be introduced:

```rust
#[route("/", method = GET)]
```

If the method's name is a valid identifier, it can be used without
quotes. Otherwise it must be quoted:

```rust
// `GET` is a valid identifier, but `VERSION-CONTROL` is not
#[route("/", method = "VERSION-CONTROL")]
```

Closes #2731.
2024-08-24 03:00:52 -07:00
Sergio Benitez 926e06ef3c Finalize 'tracing' migration.
This commit complete the migration to 'tracing' for all logging. Below
is a summary of all relevant commits, including this one:

Log improvements:
  - All log (trace) messages are structured which means they contain fields
    that can formatted by any subscriber.
  - Logging can be disabled entirely by disabling the default `trace` feature.
  - Routes and catchers now contain location (file/line) information.
  - Two log format kinds: pretty and compact via ROCKET_LOG_FORMAT
  - Coloring is not disabled globally. Thus applications can color even if
    Rocket is configured not to.
  - Rocket is more conservative about 'warn' and 'error' messages, reserving
    those log levels for messages useful in production.
  - Errors from guards logged by codegen now use the 'Display' implementation of
    those errors when one exists.
  - Secrets are never logged, even when directly asked for.

New features:
  - Many Rocket types know how to trace themselves via a new `Trace` trait.
  - `Either` types can now be used in `uri!()` calls.
  - A `RequestIdLayer` tags all requests with a unique ID.

Breaking changes to configuration:
  - `Config::log_level` is of type `Option<Level>`. `None` disables tracing.
  - `log_level` now uses the traditional log level names: "off", "error",
    "warn", "info", "debug", "trace", or 0-5. This replace the Rocket-specific
    "normal", "debug", "critical".
  - A new option, `log_format`, which is either `compact` or `pretty`,
    determines how Rocket's tracing subscriber log trace messages.

Breaking changes:
  - Hidden `rocket::Either` is now publicly available at `rocket::either::Either`.
  - `rocket::Error` no longer panics when dropped.
  - `main` generated by `#[launch]` returns an `ExitCode`.
  - `FromParam` `Err` now always returns the actual error as opposed to the
    string that failed to parse. To recover the original string, use `Either<T,
    &str>`, where `T: FromParam`, as a parameter guard.
  - Many types that implemented `Display` now instead implement `Trace`.
  - `Error::pretty_print()` was removed. Use `Error::trace()` via `Trace` impl.

Internal improvements:
  - Made more space in CI machines for tasks.
  - Cleaned up testbench code using `inventory`.

Resolves #21.
2024-06-03 15:02:44 -07:00
Sergio Benitez b12b7f27d7 Remove old 'log' macros. Color via subscriber.
This commit:
  - Removes painting outside trace subscriber in core.
  - Removes all non-subscriber uses of yansi.
  - Removes all uses of old log macros.
  - Fix trace exports.
2024-06-03 14:39:12 -07:00
Sergio Benitez d767694861 Remove 'Error' panic-on-drop behavior.
Instead, the `#[launch]` attribute traces the error and panics,
replicating the old behavior in the common case.
2024-06-03 14:38:34 -07:00
Sergio Benitez 8a1c91b7d5 Implement 'Trace' trait. Use structured logging.
This commit:
  - Converts most log messages into structured messages.
  - Implements an initial request ID layer.
  - Implements pretty and compact loggers.
2024-06-03 14:33:24 -07:00
Sergio Benitez ff6da900a0 Migrate to 'tracing' for logging.
This commit:
  - Remove all traces of 'log'.
  - Send all logs unedited via tracing.
  - Parses and propagate log_level.
  - Implements an initial formatting subscriber.

Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Co-authored-by: Jeb Rosen <jeb@jebrosen.com>
2024-06-03 14:32:01 -07:00
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 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 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 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
Konrad Borowski 4d258739f5 Migrate Rocket to Rust 2021 edition. 2022-04-19 18:35:38 -07:00
Sergio Benitez 29c5bfd6cc Add usage comments to 'hello' example. 2021-06-01 11:16:40 -07:00
Sergio Benitez a7cfa4c8b7 Don't disable default 'Shield' in 'hello' example. 2021-05-22 17:20:36 -07:00
Sergio Benitez f6a7087c84 Graduate 'helmet' as 'shield' into core.
The 'SpaceHelmet' fairing is now called 'Shield'. It features the
following changes and improvements:

  * Headers which are now ignored by browsers are removed.
  * 'XssFilter' is no longer an on-by-default policy.
  * A new 'Permission' policy is introduced.
  * 'Shield' is attached to all 'Rocket' instances by default.
  * Default headers never allocate on 'Clone'.
  * Policy headers are rendered once and cached at start-up.
  * Improved use of typed URIs in policy types.
2021-05-22 11:01:00 -07:00
Sergio Benitez ad36b769bc Rename 'rocket::ignite()' to 'rocket::build()'.
...because loading up a Rocket while it's ignited is a bad idea.

More seriously, because 'Rocket.ignite()' will become an "execute
everything up to here" method.
2021-04-08 01:07:52 -07:00
Sergio Benitez 50c9e88cf9 Completely revamp, redo examples.
The new examples directory...

  * Contains a `README.md` explaining each example.
  * Consolidates examples into more complete chunks.
  * Is just better.

Resolves #1447.
2021-04-07 23:09:05 -07:00
Sergio Benitez 877b37c903 Polished examples directory. Fixed `File` response bug. 2016-03-22 16:27:12 -07:00
Sergio Benitez 433a9119bd It works! Next steps: clean-up, error handling, docs. 2016-03-21 22:04:39 -07:00
Sergio Benitez 40559736fc Cleaned up to get rid of warnings. 2016-03-17 20:37:34 -07:00
Sergio Benitez 2a58800b35 initial implementation of collision detection in routing. 2016-03-17 03:29:55 -07:00
Sergio Benitez da2b0ed35a Somewhat good infrastructure for params and responses.
Can actually return strings and what-not from a route. Yay!
2016-03-17 01:57:04 -07:00
Sergio Benitez dcb150bde7 Something works! A simple hacked-up handler, that is.
At the moment, I simply install the first route I see into the Rocket struct
directly. This is quite terrible. What's worse is that I assume that the Route's
path and handler are static! The handler, actually, does have to be static, but
its response may have whatever (valid) lifetime, though I'm not sure anything
but `static makes sense. I'll think about it.

In any case, the weird `static` restrictions need to be removed, and I need to
think about which lifetimes are safe here. IE: Must all routes be static? Can I
use a closure as a route? (that'd be neat). If so, how do we make that work?

In any case, it's nice to see SOMETHING work. Yay!
2016-03-15 00:41:22 -07:00
Sergio Benitez ad08fe1d04 Major changes. FN params are now being used! Woo!
Subset of list of changes:
  * Split up decorator and macro into their own files.
  * Fully parsing the path parameter and verifying against the function's args.
  * Actually calling methods to fetch and convert the request parameters.
  * Actually calling methods to convert the handler's return type.
  * Sketched out more of the Request/Response structures.

Pretty close to having a fully working MVP.
2016-03-14 20:43:52 -07:00
Sergio Benitez 2e2cc3c216 Rocket is almost operational! `routes!` macro complete.
Here's what works so far:

  * The `route` decorator checks its inputs correctly. There's a nice utility
    for doing this, and it's working quite well at the moment.

  * The `route` decorator emits a `route_fn` and a `route_struct`. The `routes`

  * macro prepends the path terminator with the route struct prefix. The

  * `Rocket` library can read mount information (though not act on it properly
    just yet) and launch a server using Hyper.
2016-03-12 10:45:19 -08:00