rocket/
lib.rs

1#![recursion_limit="256"]
2
3#![doc(html_root_url = "https://api.rocket.rs/v0.5")]
4#![doc(html_favicon_url = "https://rocket.rs/images/favicon.ico")]
5#![doc(html_logo_url = "https://rocket.rs/images/logo-boxed.png")]
6#![cfg_attr(nightly, feature(doc_cfg))]
7#![cfg_attr(nightly, feature(decl_macro))]
8
9#![warn(rust_2018_idioms)]
10#![warn(missing_docs)]
11
12//! # Rocket - Core API Documentation
13//!
14//! Hello, and welcome to the core Rocket API documentation!
15//!
16//! This API documentation is highly technical and is purely a reference.
17//! There's an [overview] of Rocket on the main site as well as a [full,
18//! detailed guide]. If you'd like pointers on getting started, see the
19//! [quickstart] or [getting started] chapters of the guide.
20//!
21//! [overview]: https://rocket.rs/v0.5/overview
22//! [full, detailed guide]: https://rocket.rs/v0.5/guide
23//! [quickstart]: https://rocket.rs/v0.5/guide/quickstart
24//! [getting started]: https://rocket.rs/v0.5/guide/getting-started
25//!
26//! ## Usage
27//!
28//! Depend on `rocket` in `Cargo.toml`:
29//!
30//! ```toml
31//! [dependencies]
32//! rocket = "0.5.1"
33//! ```
34//!
35//! <small>Note that development versions, tagged with `-dev`, are not published
36//! and need to be specified as [git dependencies].</small>
37//!
38//! See the [guide](https://rocket.rs/v0.5/guide) for more information on how
39//! to write Rocket applications. Here's a simple example to get you started:
40//!
41//! [git dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-git-repositories
42//!
43//! ```rust,no_run
44//! #[macro_use] extern crate rocket;
45//!
46//! #[get("/")]
47//! fn hello() -> &'static str {
48//!     "Hello, world!"
49//! }
50//!
51//! #[launch]
52//! fn rocket() -> _ {
53//!     rocket::build().mount("/", routes![hello])
54//! }
55//! ```
56//!
57//! ## Features
58//!
59//! To avoid compiling unused dependencies, Rocket gates certain features. With
60//! the exception of `http2`, all are disabled by default:
61//!
62//! | Feature   | Description                                             |
63//! |-----------|---------------------------------------------------------|
64//! | `secrets` | Support for authenticated, encrypted [private cookies]. |
65//! | `tls`     | Support for [TLS] encrypted connections.                |
66//! | `mtls`    | Support for verified clients via [mutual TLS].          |
67//! | `http2`   | Support for HTTP/2 (enabled by default).                |
68//! | `json`    | Support for [JSON (de)serialization].                   |
69//! | `msgpack` | Support for [MessagePack (de)serialization].            |
70//! | `uuid`    | Support for [UUID value parsing and (de)serialization]. |
71//!
72//! Disabled features can be selectively enabled in `Cargo.toml`:
73//!
74//! ```toml
75//! [dependencies]
76//! rocket = { version = "0.5.1", features = ["secrets", "tls", "json"] }
77//! ```
78//!
79//! Conversely, HTTP/2 can be disabled:
80//!
81//! ```toml
82//! [dependencies]
83//! rocket = { version = "0.5.1", default-features = false }
84//! ```
85//!
86//! [JSON (de)serialization]: crate::serde::json
87//! [MessagePack (de)serialization]: crate::serde::msgpack
88//! [UUID value parsing and (de)serialization]: crate::serde::uuid
89//! [private cookies]: https://rocket.rs/v0.5/guide/requests/#private-cookies
90//! [TLS]: https://rocket.rs/v0.5/guide/configuration/#tls
91//! [mutual TLS]: crate::mtls
92//!
93//! ## Configuration
94//!
95//! Rocket offers a rich, extensible configuration system built on [Figment]. By
96//! default, Rocket applications are configured via a `Rocket.toml` file
97//! and/or `ROCKET_{PARAM}` environment variables, but applications may
98//! configure their own sources. See the [configuration guide] for full details.
99//!
100//! ## Testing
101//!
102//! The [`local`] module contains structures that facilitate unit and
103//! integration testing of a Rocket application. The top-level [`local`] module
104//! documentation and the [testing guide] include detailed examples.
105//!
106//! [configuration guide]: https://rocket.rs/v0.5/guide/configuration/
107//! [testing guide]: https://rocket.rs/v0.5/guide/testing/#testing
108//! [Figment]: https://docs.rs/figment
109
110// Allows using Rocket's codegen in Rocket itself.
111extern crate self as rocket;
112
113/// These are public dependencies! Update docs if these are changed, especially
114/// figment's version number in docs.
115#[doc(hidden)] pub use yansi;
116#[doc(hidden)] pub use async_stream;
117pub use futures;
118pub use tokio;
119pub use figment;
120pub use time;
121
122#[doc(hidden)]
123#[macro_use] pub mod log;
124#[macro_use] pub mod outcome;
125#[macro_use] pub mod data;
126#[doc(hidden)] pub mod sentinel;
127pub mod local;
128pub mod request;
129pub mod response;
130pub mod config;
131pub mod form;
132pub mod fairing;
133pub mod error;
134pub mod catcher;
135pub mod route;
136pub mod serde;
137pub mod shield;
138pub mod fs;
139
140// Reexport of HTTP everything.
141pub mod http {
142    //! Types that map to concepts in HTTP.
143    //!
144    //! This module exports types that map to HTTP concepts or to the underlying
145    //! HTTP library when needed.
146
147    #[doc(inline)]
148    pub use rocket_http::*;
149
150    /// Re-exported hyper HTTP library types.
151    ///
152    /// All types that are re-exported from Hyper reside inside of this module.
153    /// These types will, with certainty, be removed with time, but they reside here
154    /// while necessary.
155    pub mod hyper {
156        #[doc(hidden)]
157        pub use rocket_http::hyper::*;
158
159        pub use rocket_http::hyper::header;
160    }
161
162    #[doc(inline)]
163    pub use crate::cookies::*;
164}
165
166#[cfg(feature = "mtls")]
167#[cfg_attr(nightly, doc(cfg(feature = "mtls")))]
168pub mod mtls;
169
170/// TODO: We need a futures mod or something.
171mod trip_wire;
172mod shutdown;
173mod server;
174mod ext;
175mod state;
176mod cookies;
177mod rkt;
178mod router;
179mod phase;
180
181#[doc(inline)] pub use crate::response::Response;
182#[doc(inline)] pub use crate::data::Data;
183#[doc(inline)] pub use crate::config::Config;
184#[doc(inline)] pub use crate::catcher::Catcher;
185#[doc(inline)] pub use crate::route::Route;
186#[doc(hidden)] pub use either::Either;
187#[doc(inline)] pub use phase::{Phase, Build, Ignite, Orbit};
188#[doc(inline)] pub use error::Error;
189#[doc(inline)] pub use sentinel::Sentinel;
190#[doc(inline)] pub use crate::request::Request;
191#[doc(inline)] pub use crate::rkt::Rocket;
192#[doc(inline)] pub use crate::shutdown::Shutdown;
193#[doc(inline)] pub use crate::state::State;
194#[doc(inline)] pub use rocket_codegen::*;
195
196/// Creates a [`Rocket`] instance with the default config provider: aliases
197/// [`Rocket::build()`].
198pub fn build() -> Rocket<Build> {
199    Rocket::build()
200}
201
202/// Creates a [`Rocket`] instance with a custom config provider: aliases
203/// [`Rocket::custom()`].
204pub fn custom<T: figment::Provider>(provider: T) -> Rocket<Build> {
205    Rocket::custom(provider)
206}
207
208/// Retrofits support for `async fn` in trait impls and declarations.
209///
210/// Any trait declaration or trait `impl` decorated with `#[async_trait]` is
211/// retrofitted with support for `async fn`s:
212///
213/// ```rust
214/// # use rocket::*;
215/// #[async_trait]
216/// trait MyAsyncTrait {
217///     async fn do_async_work();
218/// }
219///
220/// #[async_trait]
221/// impl MyAsyncTrait for () {
222///     async fn do_async_work() { /* .. */ }
223/// }
224/// ```
225///
226/// All `impl`s for a trait declared with `#[async_trait]` must themselves be
227/// decorated with `#[async_trait]`. Many of Rocket's traits, such as
228/// [`FromRequest`](crate::request::FromRequest) and
229/// [`Fairing`](crate::fairing::Fairing) are `async`. As such, implementations
230/// of said traits must be decorated with `#[async_trait]`. See the individual
231/// trait docs for trait-specific details.
232///
233/// For more details on `#[async_trait]`, see [`async_trait`](mod@async_trait).
234#[doc(inline)]
235pub use async_trait::async_trait;
236
237/// WARNING: This is unstable! Do not use this method outside of Rocket!
238#[doc(hidden)]
239pub fn async_run<F, R>(fut: F, workers: usize, sync: usize, force_end: bool, name: &str) -> R
240    where F: std::future::Future<Output = R>
241{
242    let runtime = tokio::runtime::Builder::new_multi_thread()
243        .thread_name(name)
244        .worker_threads(workers)
245        .max_blocking_threads(sync)
246        .enable_all()
247        .build()
248        .expect("create tokio runtime");
249
250    let result = runtime.block_on(fut);
251    if force_end {
252        runtime.shutdown_timeout(std::time::Duration::from_millis(500));
253    }
254
255    result
256}
257
258/// WARNING: This is unstable! Do not use this method outside of Rocket!
259#[doc(hidden)]
260pub fn async_test<R>(fut: impl std::future::Future<Output = R>) -> R {
261    async_run(fut, 1, 32, true, "rocket-worker-test-thread")
262}
263
264/// WARNING: This is unstable! Do not use this method outside of Rocket!
265#[doc(hidden)]
266pub fn async_main<R>(fut: impl std::future::Future<Output = R> + Send) -> R {
267    // FIXME: We need to run `fut` to get the user's `Figment` to properly set
268    // up the async env, but we need the async env to run `fut`. So we're stuck.
269    // Tokio doesn't let us take the state from one async env and migrate it to
270    // another, so we need to use one, making this impossible.
271    //
272    // So as a result, we only use values from Rocket's figment. These
273    // values won't reflect swaps of `Rocket` in attach fairings with different
274    // config values, or values from non-Rocket configs. See tokio-rs/tokio#3329
275    // for a necessary resolution in `tokio`.
276    use config::bail_with_config_error as bail;
277
278    let fig = Config::figment();
279    let workers = fig.extract_inner(Config::WORKERS).unwrap_or_else(bail);
280    let max_blocking = fig.extract_inner(Config::MAX_BLOCKING).unwrap_or_else(bail);
281    let force = fig.focus(Config::SHUTDOWN).extract_inner("force").unwrap_or_else(bail);
282    async_run(fut, workers, max_blocking, force, "rocket-worker-thread")
283}
284
285/// Executes a `future` to completion on a new tokio-based Rocket async runtime.
286///
287/// The runtime is terminated on shutdown, and the future's resolved value is
288/// returned.
289///
290/// # Considerations
291///
292/// This function is a low-level mechanism intended to be used to execute the
293/// future returned by [`Rocket::launch()`] in a self-contained async runtime
294/// designed for Rocket. It runs futures in exactly the same manner as
295/// [`#[launch]`](crate::launch) and [`#[main]`](crate::main) do and is thus
296/// _never_ the preferred mechanism for running a Rocket application. _Always_
297/// prefer to use the [`#[launch]`](crate::launch) or [`#[main]`](crate::main)
298/// attributes. For example [`#[main]`](crate::main) can be used even when
299/// Rocket is just a small part of a bigger application:
300///
301/// ```rust,no_run
302/// #[rocket::main]
303/// async fn main() {
304///     # let should_start_server_in_foreground = false;
305///     # let should_start_server_in_background = false;
306///     let rocket = rocket::build();
307///     if should_start_server_in_foreground {
308///         rocket::build().launch().await;
309///     } else if should_start_server_in_background {
310///         rocket::tokio::spawn(rocket.launch());
311///     } else {
312///         // do something else
313///     }
314/// }
315/// ```
316///
317/// See [Rocket#launching] for more on using these attributes.
318///
319/// # Example
320///
321/// Build an instance of Rocket, launch it, and wait for shutdown:
322///
323/// ```rust,no_run
324/// use rocket::fairing::AdHoc;
325///
326/// let rocket = rocket::build()
327///     .attach(AdHoc::on_liftoff("Liftoff Printer", |_| Box::pin(async move {
328///         println!("Stalling liftoff for a second...");
329///         rocket::tokio::time::sleep(std::time::Duration::from_secs(1)).await;
330///         println!("And we're off!");
331///     })));
332///
333/// rocket::execute(rocket.launch());
334/// ```
335///
336/// Launch a pre-built instance of Rocket and wait for it to shutdown:
337///
338/// ```rust,no_run
339/// use rocket::{Rocket, Ignite, Phase, Error};
340///
341/// fn launch<P: Phase>(rocket: Rocket<P>) -> Result<Rocket<Ignite>, Error> {
342///     rocket::execute(rocket.launch())
343/// }
344/// ```
345///
346/// Do async work to build an instance of Rocket, launch, and wait for shutdown:
347///
348/// ```rust,no_run
349/// use rocket::fairing::AdHoc;
350///
351/// // This line can also be inside of the `async` block.
352/// let rocket = rocket::build();
353///
354/// rocket::execute(async move {
355///     let rocket = rocket.ignite().await?;
356///     let config = rocket.config();
357///     rocket.launch().await
358/// });
359/// ```
360pub fn execute<R, F>(future: F) -> R
361    where F: std::future::Future<Output = R> + Send
362{
363    async_main(future)
364}