rocket/rocket.rs
1use std::fmt;
2use std::ops::{Deref, DerefMut};
3use std::sync::Arc;
4use std::time::Duration;
5use std::any::Any;
6use std::future::Future;
7use std::panic::Location;
8
9use either::Either;
10use figment::{Figment, Provider};
11use futures::TryFutureExt;
12
13use crate::shutdown::{Stages, Shutdown};
14use crate::trace::{Trace, TraceAll};
15use crate::{sentinel, shield::Shield, Catcher, Config, Route};
16use crate::listener::{Bind, DefaultListener, Endpoint, Listener};
17use crate::router::Router;
18use crate::fairing::{Fairing, Fairings};
19use crate::phase::{Phase, Build, Building, Ignite, Igniting, Orbit, Orbiting};
20use crate::phase::{Stateful, StateRef, StateRefMut, State};
21use crate::http::uri::Origin;
22use crate::http::ext::IntoOwned;
23use crate::error::{Error, ErrorKind};
24
25/// The application server itself.
26///
27/// # Phases
28///
29/// A `Rocket` instance represents a web server and its state. It progresses
30/// through three statically-enforced phases: build, ignite, orbit.
31///
32/// * **Build**: _application and server configuration_
33///
34/// This phase enables:
35///
36/// * setting configuration options
37/// * mounting/registering routes/catchers
38/// * managing state
39/// * attaching fairings
40///
41/// This is the _only_ phase in which an instance can be modified. To finalize
42/// changes, an instance is ignited via [`Rocket::ignite()`], progressing it
43/// into the _ignite_ phase, or directly launched into orbit with
44/// [`Rocket::launch()`] which progress the instance through ignite into
45/// orbit.
46///
47/// * **Ignite**: _verification and finalization of configuration_
48///
49/// An instance in the [`Ignite`] phase is in its final configuration,
50/// available via [`Rocket::config()`]. Barring user-supplied interior
51/// mutation, application state is guaranteed to remain unchanged beyond this
52/// point. An instance in the ignite phase can be launched into orbit to serve
53/// requests via [`Rocket::launch()`].
54///
55/// * **Orbit**: _a running web server_
56///
57/// An instance in the [`Orbit`] phase represents a _running_ application,
58/// actively serving requests.
59///
60/// # Launching
61///
62/// To launch a `Rocket` application, the suggested approach is to return an
63/// instance of `Rocket<Build>` from a function named `rocket` marked with the
64/// [`#[launch]`](crate::launch) attribute:
65///
66/// ```rust,no_run
67/// # use rocket::launch;
68/// #[launch]
69/// fn rocket() -> _ {
70/// rocket::build()
71/// }
72/// ```
73///
74/// This generates a `main` function with an `async` runtime that runs the
75/// returned `Rocket` instance.
76///
77/// * **Manual Launching**
78///
79/// To launch an instance of `Rocket`, it _must_ progress through all three
80/// phases. To progress into the ignite or launch phases, a tokio `async`
81/// runtime is required. The [`#[main]`](crate::main) attribute initializes a
82/// Rocket-specific tokio runtime and runs the attributed `async fn` inside of
83/// it:
84///
85/// ```rust,no_run
86/// #[rocket::main]
87/// async fn main() -> Result<(), rocket::Error> {
88/// let _rocket = rocket::build()
89/// .ignite().await?
90/// .launch().await?;
91///
92/// Ok(())
93/// }
94/// ```
95///
96/// Note that [`Rocket::launch()`] automatically progresses an instance of
97/// `Rocket` from any phase into orbit:
98///
99/// ```rust,no_run
100/// #[rocket::main]
101/// async fn main() -> Result<(), rocket::Error> {
102/// let _rocket = rocket::build().launch().await?;
103/// Ok(())
104/// }
105/// ```
106///
107/// For extreme and rare cases in which [`#[main]`](crate::main) imposes
108/// obstinate restrictions, use [`rocket::execute()`](crate::execute()) to
109/// execute Rocket's `launch()` future.
110///
111/// * **Automatic Launching**
112///
113/// Manually progressing an instance of Rocket though its phases is only
114/// necessary when either an instance's finalized state is to be inspected (in
115/// the _ignite_ phase) or the instance is expected to deorbit due to
116/// [`Rocket::shutdown()`]. In the more common case when neither is required,
117/// the [`#[launch]`](crate::launch) attribute can be used. When applied to a
118/// function that returns a `Rocket<Build>`, it automatically initializes an
119/// `async` runtime and launches the function's returned instance:
120///
121/// ```rust,no_run
122/// # use rocket::launch;
123/// use rocket::{Rocket, Build};
124///
125/// #[launch]
126/// fn rocket() -> Rocket<Build> {
127/// rocket::build()
128/// }
129/// ```
130///
131/// To avoid needing to import _any_ items in the common case, the `launch`
132/// attribute will infer a return type written as `_` as `Rocket<Build>`:
133///
134/// ```rust,no_run
135/// # use rocket::launch;
136/// #[launch]
137/// fn rocket() -> _ {
138/// rocket::build()
139/// }
140/// ```
141pub struct Rocket<P: Phase>(pub(crate) P::State);
142
143impl Rocket<Build> {
144 /// Create a new `Rocket` application using the default configuration
145 /// provider, [`Config::figment()`].
146 ///
147 /// This method is typically called through the
148 /// [`rocket::build()`](crate::build) alias.
149 ///
150 /// # Examples
151 ///
152 /// ```rust
153 /// # use rocket::launch;
154 /// #[launch]
155 /// fn rocket() -> _ {
156 /// rocket::build()
157 /// }
158 /// ```
159 #[must_use]
160 #[inline(always)]
161 pub fn build() -> Self {
162 Rocket::custom(Config::figment())
163 }
164
165 /// Creates a new `Rocket` application using the supplied configuration
166 /// provider.
167 ///
168 /// This method is typically called through the
169 /// [`rocket::custom()`](crate::custom()) alias.
170 ///
171 /// # Example
172 ///
173 /// ```rust
174 /// # use rocket::launch;
175 /// use rocket::figment::{Figment, providers::{Toml, Env, Format}};
176 ///
177 /// #[launch]
178 /// fn rocket() -> _ {
179 /// let figment = Figment::from(rocket::Config::default())
180 /// .merge(Toml::file("MyApp.toml").nested())
181 /// .merge(Env::prefixed("MY_APP_").global());
182 ///
183 /// rocket::custom(figment)
184 /// }
185 /// ```
186 #[must_use]
187 pub fn custom<T: Provider>(provider: T) -> Self {
188 Rocket::<Build>(Building::default())
189 .reconfigure(provider)
190 .attach(Shield::default())
191 }
192
193 /// Overrides the current configuration provider with `provider`.
194 ///
195 /// The default provider, or a provider previously set with
196 /// [`Rocket::custom()`] or [`Rocket::reconfigure()`], is overridden by
197 /// `provider`.
198 ///
199 /// # Example
200 ///
201 /// ```rust
202 /// use rocket::config::{Config, Ident};
203 /// # use std::net::Ipv4Addr;
204 /// # use std::path::{Path, PathBuf};
205 /// # type Result = std::result::Result<(), rocket::Error>;
206 ///
207 /// let config = Config {
208 /// ident: Ident::try_new("MyServer").expect("valid ident"),
209 /// temp_dir: "/tmp/config-example".into(),
210 /// ..Config::debug_default()
211 /// };
212 ///
213 /// # let _: Result = rocket::async_test(async move {
214 /// let rocket = rocket::custom(&config).ignite().await?;
215 /// assert_eq!(rocket.config().ident.as_str(), Some("MyServer"));
216 /// assert_eq!(rocket.config().temp_dir.relative(), Path::new("/tmp/config-example"));
217 ///
218 /// // Create a new figment which modifies _some_ keys the existing figment:
219 /// let figment = rocket.figment().clone()
220 /// .merge((Config::IDENT, "Example"));
221 ///
222 /// let rocket = rocket::custom(&config)
223 /// .reconfigure(figment)
224 /// .ignite().await?;
225 ///
226 /// assert_eq!(rocket.config().ident.as_str(), Some("Example"));
227 /// assert_eq!(rocket.config().temp_dir.relative(), Path::new("/tmp/config-example"));
228 /// # Ok(())
229 /// # });
230 /// ```
231 #[must_use]
232 pub fn reconfigure<T: Provider>(mut self, provider: T) -> Self {
233 // We initialize the logger here so that logging from fairings and so on
234 // are visible; we use the final config to set a max log-level in ignite
235 self.figment = Figment::from(provider);
236 crate::trace::init(Config::try_from(&self.figment).ok().as_ref());
237 span_trace!("reconfigure" => self.figment().trace_trace());
238
239 self
240 }
241
242 #[track_caller]
243 fn load<'a, B, T, F, M>(mut self, kind: &str, base: B, items: Vec<T>, m: M, f: F) -> Self
244 where B: TryInto<Origin<'a>> + Clone + fmt::Display,
245 B::Error: fmt::Display,
246 M: Fn(&Origin<'a>, T) -> T,
247 F: Fn(&mut Self, T),
248 T: Clone + Trace,
249 {
250 let mut base = match base.clone().try_into() {
251 Ok(origin) => origin.into_owned(),
252 Err(e) => {
253 error!(%base, location = %Location::caller(), "invalid {kind} base uri: {e}");
254 panic!("aborting due to {} base error", kind);
255 }
256 };
257
258 if base.query().is_some() {
259 warn!(%base, location = %Location::caller(), "query in {kind} base is ignored");
260 base.clear_query();
261 }
262
263 for unmounted_item in items {
264 f(&mut self, m(&base, unmounted_item.clone()))
265 }
266
267 self
268 }
269
270 /// Mounts all of the `routes` at the given `base` mount point.
271 ///
272 /// A route _mounted_ at `base` has an effective URI of `base/route`, where
273 /// `route` is the route URI. In other words, `base` is added as a prefix to
274 /// the route's URI. The URI resulting from joining the `base` URI and the
275 /// route URI is called the route's _effective URI_, as this is the URI used
276 /// for request matching during routing.
277 ///
278 /// A `base` URI is not allowed to have a query part. If a `base` _does_
279 /// have a query part, it is ignored when producing the effective URI.
280 ///
281 /// A `base` may have an optional trailing slash. A route with a URI path of
282 /// `/` (and any optional query) mounted at a `base` has an effective URI
283 /// equal to the `base` (plus any optional query). That is, if the base has
284 /// a trailing slash, the effective URI path has a trailing slash, and
285 /// otherwise it does not. Routes with URI paths other than `/` are not
286 /// effected by trailing slashes in their corresponding mount point.
287 ///
288 /// As concrete examples, consider the following table:
289 ///
290 /// | mount point | route URI | effective URI |
291 /// |-------------|-----------|---------------|
292 /// | `/` | `/foo` | `/foo` |
293 /// | `/` | `/foo/` | `/foo/` |
294 /// | `/foo` | `/` | `/foo` |
295 /// | `/foo` | `/?bar` | `/foo?bar` |
296 /// | `/foo` | `/bar` | `/foo/bar` |
297 /// | `/foo` | `/bar/` | `/foo/bar/` |
298 /// | `/foo/` | `/` | `/foo/` |
299 /// | `/foo/` | `/bar` | `/foo/bar` |
300 /// | `/foo/` | `/?bar` | `/foo/?bar` |
301 /// | `/foo/bar` | `/` | `/foo/bar` |
302 /// | `/foo/bar/` | `/` | `/foo/bar/` |
303 /// | `/foo/?bar` | `/` | `/foo/` |
304 /// | `/foo/?bar` | `/baz` | `/foo/baz` |
305 /// | `/foo/?bar` | `/baz/` | `/foo/baz/` |
306 ///
307 /// # Panics
308 ///
309 /// Panics if either:
310 ///
311 /// * the `base` mount point is not a valid origin URI without dynamic
312 /// parameters
313 ///
314 /// * any route URI is not a valid origin URI. (**Note:** _This kind of
315 /// panic is guaranteed not to occur if the routes were generated using
316 /// Rocket's code generation._)
317 ///
318 /// # Examples
319 ///
320 /// Use the `routes!` macro to mount routes created using the code
321 /// generation facilities. Requests to both `/world` and `/hello/world` URI
322 /// will be dispatched to the `hi` route.
323 ///
324 /// ```rust,no_run
325 /// # #[macro_use] extern crate rocket;
326 /// #
327 /// #[get("/world")]
328 /// fn hi() -> &'static str {
329 /// "Hello!"
330 /// }
331 ///
332 /// #[launch]
333 /// fn rocket() -> _ {
334 /// rocket::build()
335 /// .mount("/", routes![hi])
336 /// .mount("/hello", routes![hi])
337 /// }
338 /// ```
339 ///
340 /// Manually create a route named `hi` at path `"/world"` mounted at base
341 /// `"/hello"`. Requests to the `/hello/world` URI will be dispatched to the
342 /// `hi` route.
343 ///
344 /// ```rust
345 /// # #[macro_use] extern crate rocket;
346 /// use rocket::{Request, Route, Data, route};
347 /// use rocket::http::Method;
348 ///
349 /// fn hi<'r>(req: &'r Request, _: Data<'r>) -> route::BoxFuture<'r> {
350 /// route::Outcome::from(req, "Hello!").pin()
351 /// }
352 ///
353 /// #[launch]
354 /// fn rocket() -> _ {
355 /// let hi_route = Route::new(Method::Get, "/world", hi);
356 /// rocket::build().mount("/hello", vec![hi_route])
357 /// }
358 /// ```
359 #[must_use]
360 #[track_caller]
361 pub fn mount<'a, B, R>(self, base: B, routes: R) -> Self
362 where B: TryInto<Origin<'a>> + Clone + fmt::Display,
363 B::Error: fmt::Display,
364 R: Into<Vec<Route>>
365 {
366 self.load("route", base, routes.into(),
367 |base, route| route.rebase(base.clone()),
368 |r, route| r.0.routes.push(route))
369 }
370
371 /// Registers all of the catchers in the supplied vector, scoped to `base`.
372 ///
373 /// # Panics
374 ///
375 /// Panics if `base` is not a valid static path: a valid origin URI without
376 /// dynamic parameters.
377 ///
378 /// # Examples
379 ///
380 /// ```rust,no_run
381 /// # #[macro_use] extern crate rocket;
382 /// use rocket::Request;
383 ///
384 /// #[catch(500)]
385 /// fn internal_error() -> &'static str {
386 /// "Whoops! Looks like we messed up."
387 /// }
388 ///
389 /// #[catch(404)]
390 /// fn not_found(req: &Request) -> String {
391 /// format!("I couldn't find '{}'. Try something else?", req.uri())
392 /// }
393 ///
394 /// #[launch]
395 /// fn rocket() -> _ {
396 /// rocket::build().register("/", catchers![internal_error, not_found])
397 /// }
398 /// ```
399 #[must_use]
400 pub fn register<'a, B, C>(self, base: B, catchers: C) -> Self
401 where B: TryInto<Origin<'a>> + Clone + fmt::Display,
402 B::Error: fmt::Display,
403 C: Into<Vec<Catcher>>
404 {
405 self.load("catcher", base, catchers.into(),
406 |base, catcher| catcher.rebase(base.clone()),
407 |r, catcher| r.0.catchers.push(catcher))
408 }
409
410 /// Add `state` to the state managed by this instance of Rocket.
411 ///
412 /// This method can be called any number of times as long as each call
413 /// refers to a different `T`.
414 ///
415 /// Managed state can be retrieved by any request handler via the
416 /// [`State`](crate::State) request guard. In particular, if a value of type `T`
417 /// is managed by Rocket, adding `State<T>` to the list of arguments in a
418 /// request handler instructs Rocket to retrieve the managed value.
419 ///
420 /// # Panics
421 ///
422 /// Panics if state of type `T` is already being managed.
423 ///
424 /// # Example
425 ///
426 /// ```rust,no_run
427 /// # #[macro_use] extern crate rocket;
428 /// use rocket::State;
429 ///
430 /// struct MyInt(isize);
431 /// struct MyString(String);
432 ///
433 /// #[get("/int")]
434 /// fn int(state: &State<MyInt>) -> String {
435 /// format!("The stateful int is: {}", state.0)
436 /// }
437 ///
438 /// #[get("/string")]
439 /// fn string(state: &State<MyString>) -> &str {
440 /// &state.0
441 /// }
442 ///
443 /// #[launch]
444 /// fn rocket() -> _ {
445 /// rocket::build()
446 /// .manage(MyInt(10))
447 /// .manage(MyString("Hello, managed state!".to_string()))
448 /// .mount("/", routes![int, string])
449 /// }
450 /// ```
451 #[must_use]
452 pub fn manage<T>(self, state: T) -> Self
453 where T: Send + Sync + 'static
454 {
455 let type_name = std::any::type_name::<T>();
456 if !self.state.set(state) {
457 error!("state for type '{}' is already being managed", type_name);
458 panic!("aborting due to duplicated managed state");
459 }
460
461 self
462 }
463
464 /// Attaches a fairing to this instance of Rocket. No fairings are eagerly
465 /// executed; fairings are executed at their appropriate time.
466 ///
467 /// If the attached fairing is a [singleton] and a fairing of the same type
468 /// has already been attached, this fairing replaces it. Otherwise the
469 /// fairing gets attached without replacing any existing fairing.
470 ///
471 /// [singleton]: crate::fairing::Fairing#singletons
472 ///
473 /// # Example
474 ///
475 /// ```rust,no_run
476 /// # #[macro_use] extern crate rocket;
477 /// use rocket::Rocket;
478 /// use rocket::fairing::AdHoc;
479 ///
480 /// #[launch]
481 /// fn rocket() -> _ {
482 /// rocket::build()
483 /// .attach(AdHoc::on_liftoff("Liftoff Message", |_| Box::pin(async {
484 /// println!("We have liftoff!");
485 /// })))
486 /// }
487 /// ```
488 #[must_use]
489 pub fn attach<F: Fairing>(mut self, fairing: F) -> Self {
490 self.fairings.add(Box::new(fairing));
491 self
492 }
493
494 /// Returns a `Future` that transitions this instance of `Rocket` into the
495 /// _ignite_ phase.
496 ///
497 /// When `await`ed, the future runs all _ignite_ fairings in serial,
498 /// [attach](Rocket::attach()) order, and verifies that `self` represents a
499 /// valid instance of `Rocket` ready for launch. This means that:
500 ///
501 /// * All ignite fairings succeeded.
502 /// * A valid [`Config`] was extracted from [`Rocket::figment()`].
503 /// * If `secrets` are enabled, the extracted `Config` contains a safe
504 /// secret key.
505 /// * There are no [`Route#collisions`] or [`Catcher#collisions`]
506 /// collisions.
507 /// * No [`Sentinel`](crate::Sentinel) triggered an abort.
508 ///
509 /// If any of these conditions fail to be met, a respective [`Error`] is
510 /// returned.
511 ///
512 /// [configured]: Rocket::figment()
513 ///
514 /// # Example
515 ///
516 /// ```rust
517 /// use rocket::fairing::AdHoc;
518 ///
519 /// #[rocket::main]
520 /// async fn main() -> Result<(), rocket::Error> {
521 /// let rocket = rocket::build()
522 /// # .reconfigure(rocket::Config::debug_default())
523 /// .attach(AdHoc::on_ignite("Manage State", |rocket| async move {
524 /// rocket.manage(String::from("managed string"))
525 /// }));
526 ///
527 /// // No fairings are run until ignition occurs.
528 /// assert!(rocket.state::<String>().is_none());
529 ///
530 /// let rocket = rocket.ignite().await?;
531 /// assert_eq!(rocket.state::<String>().unwrap(), "managed string");
532 ///
533 /// Ok(())
534 /// }
535 /// ```
536 pub async fn ignite(mut self) -> Result<Rocket<Ignite>, Error> {
537 self = Fairings::handle_ignite(self).await;
538 self.fairings.audit().map_err(|f| ErrorKind::FailedFairings(f.to_vec()))?;
539
540 // Extract the configuration; initialize default trace subscriber.
541 #[allow(unused_mut)]
542 let mut config = Config::try_from(&self.figment).map_err(ErrorKind::Config)?;
543 crate::trace::init(&config);
544
545 // Check for safely configured secrets.
546 #[cfg(feature = "secrets")]
547 if !config.secret_key.is_provided() {
548 if config.profile != Config::DEBUG_PROFILE {
549 return Err(Error::new(ErrorKind::InsecureSecretKey(config.profile.clone())));
550 }
551
552 if config.secret_key.is_zero() {
553 config.secret_key = crate::config::SecretKey::generate()
554 .unwrap_or_else(crate::config::SecretKey::zero);
555 }
556 }
557
558 // Initialize the router; check for collisions.
559 let mut router = Router::new();
560 self.routes.clone().into_iter().for_each(|r| router.routes.push(r));
561 self.catchers.clone().into_iter().for_each(|c| router.catchers.push(c));
562 let router = router.finalize()
563 .map_err(|(r, c)| ErrorKind::Collisions { routes: r, catchers: c, })?;
564
565 // Finally, freeze managed state for faster access later.
566 self.state.freeze();
567
568 // Log everything we know: config, routes, catchers, fairings.
569 // TODO: Store/print managed state type names?
570 let fairings = self.fairings.unique_set();
571 span_info!("config", profile = %self.figment().profile() => {
572 config.trace_info();
573 self.figment().trace_debug();
574 });
575
576 span_info!("routes", count = self.routes.len() => self.routes().trace_all_info());
577 span_info!("catchers", count = self.catchers.len() => self.catchers().trace_all_info());
578 span_info!("fairings", count = fairings.len() => fairings.trace_all_info());
579
580 // Ignite the rocket.
581 let rocket: Rocket<Ignite> = Rocket(Igniting {
582 shutdown: Stages::new(),
583 figment: self.0.figment,
584 fairings: self.0.fairings,
585 state: self.0.state,
586 router, config,
587 });
588
589 // Query the sentinels, abort if requested.
590 let sentinels = rocket.routes().flat_map(|r| r.sentinels.iter());
591 sentinel::query(sentinels, &rocket).map_err(ErrorKind::SentinelAborts)?;
592
593 Ok(rocket)
594 }
595}
596
597impl Rocket<Ignite> {
598 /// Returns the finalized, active configuration. This is guaranteed to
599 /// remain stable through ignition and into orbit.
600 ///
601 /// # Example
602 ///
603 /// ```rust,no_run
604 /// #[rocket::main]
605 /// async fn main() -> Result<(), rocket::Error> {
606 /// let rocket = rocket::build().ignite().await?;
607 /// let config = rocket.config();
608 /// Ok(())
609 /// }
610 /// ```
611 pub fn config(&self) -> &Config {
612 &self.config
613 }
614
615 /// Returns a handle which can be used to trigger a shutdown and detect a
616 /// triggered shutdown.
617 ///
618 /// A completed graceful shutdown resolves the future returned by
619 /// [`Rocket::launch()`]. If [`Shutdown::notify()`] is called _before_ an
620 /// instance is launched, it will be immediately shutdown after liftoff. See
621 /// [`Shutdown`] and [`ShutdownConfig`](crate::config::ShutdownConfig) for
622 /// details on graceful shutdown.
623 ///
624 /// # Example
625 ///
626 /// ```rust,no_run
627 /// # use std::time::Duration;
628 /// use rocket::tokio::{self, time};
629 ///
630 /// #[rocket::main]
631 /// async fn main() -> Result<(), rocket::Error> {
632 /// let rocket = rocket::build().ignite().await?;
633 ///
634 /// let shutdown = rocket.shutdown();
635 /// tokio::spawn(async move {
636 /// time::sleep(time::Duration::from_secs(5)).await;
637 /// shutdown.notify();
638 /// });
639 ///
640 /// // The `launch()` future resolves after ~5 seconds.
641 /// let result = rocket.launch().await;
642 /// assert!(result.is_ok());
643 ///
644 /// Ok(())
645 /// }
646 /// ```
647 pub fn shutdown(&self) -> Shutdown {
648 self.shutdown.start.clone()
649 }
650
651 pub(crate) fn into_orbit(self, endpoints: Vec<Endpoint>) -> Rocket<Orbit> {
652 Rocket(Orbiting {
653 endpoints,
654 router: self.0.router,
655 fairings: self.0.fairings,
656 figment: self.0.figment,
657 config: self.0.config,
658 state: self.0.state,
659 shutdown: self.0.shutdown,
660 })
661 }
662
663 async fn _local_launch(self, endpoint: Endpoint) -> Rocket<Orbit> {
664 let rocket = self.into_orbit(vec![endpoint]);
665 Rocket::liftoff(&rocket).await;
666 rocket
667 }
668
669 async fn _launch<L: Listener + 'static>(self, listener: L) -> Result<Rocket<Ignite>, Error> {
670 let rocket = self.listen_and_serve(listener, |rocket| async move {
671 let rocket = Arc::new(rocket);
672
673 rocket.shutdown.spawn_listener(&rocket.config.shutdown);
674 if let Err(e) = tokio::spawn(Rocket::liftoff(rocket.clone())).await {
675 let rocket = rocket.try_wait_shutdown().await.map(Box::new);
676 return Err(ErrorKind::Liftoff(rocket, e).into());
677 }
678
679 Ok(rocket)
680 }).await?;
681
682 Ok(rocket.try_wait_shutdown().await.map_err(ErrorKind::Shutdown)?)
683 }
684}
685
686impl Rocket<Orbit> {
687 /// Rocket wraps all connections in a `CancellableIo` struct, an internal
688 /// structure that gracefully closes I/O when it receives a signal. That
689 /// signal is the `shutdown` future. When the future resolves,
690 /// `CancellableIo` begins to terminate in grace, mercy, and finally force
691 /// close phases. Since all connections are wrapped in `CancellableIo`, this
692 /// eventually ends all I/O.
693 ///
694 /// At that point, unless a user spawned an infinite, stand-alone task that
695 /// isn't monitoring `Shutdown`, all tasks should resolve. This means that
696 /// all instances of the shared `Arc<Rocket>` are dropped and we can return
697 /// the owned instance of `Rocket`.
698 ///
699 /// Unfortunately, the Hyper `server` future resolves as soon as it has
700 /// finished processing requests without respect for ongoing responses. That
701 /// is, `server` resolves even when there are running tasks that are
702 /// generating a response. So, `server` resolving implies little to nothing
703 /// about the state of connections. As a result, we depend on the timing of
704 /// grace + mercy + some buffer to determine when all connections should be
705 /// closed, thus all tasks should be complete, thus all references to
706 /// `Arc<Rocket>` should be dropped and we can get back a unique reference.
707 async fn try_wait_shutdown(self: Arc<Self>) -> Result<Rocket<Ignite>, Arc<Self>> {
708 info!("Shutting down. Waiting for shutdown fairings and pending I/O...");
709 tokio::spawn({
710 let rocket = self.clone();
711 async move { rocket.fairings.handle_shutdown(&rocket).await }
712 });
713
714 let config = &self.config.shutdown;
715 let wait = Duration::from_micros(250);
716 for period in [wait, config.grace(), wait, config.mercy(), wait * 4] {
717 if Arc::strong_count(&self) == 1 { break }
718 tokio::time::sleep(period).await;
719 }
720
721 match Arc::try_unwrap(self) {
722 Ok(rocket) => {
723 info!("Graceful shutdown completed successfully.");
724 Ok(rocket.deorbit())
725 }
726 Err(rocket) => {
727 warn!("Shutdown failed: outstanding background I/O.");
728 Err(rocket)
729 }
730 }
731 }
732
733 pub(crate) fn deorbit(self) -> Rocket<Ignite> {
734 Rocket(Igniting {
735 router: self.0.router,
736 fairings: self.0.fairings,
737 figment: self.0.figment,
738 config: self.0.config,
739 state: self.0.state,
740 shutdown: self.0.shutdown,
741 })
742 }
743
744 pub(crate) async fn liftoff<R: Deref<Target = Self>>(rocket: R) {
745 let rocket = rocket.deref();
746 rocket.fairings.handle_liftoff(rocket).await;
747
748 if !crate::running_within_rocket_async_rt().await {
749 warn!(
750 "Rocket is executing inside of a custom runtime.\n\
751 Rocket's runtime is enabled via `#[rocket::main]` or `#[launch]`\n\
752 Forced shutdown is disabled. Runtime settings may be suboptimal."
753 );
754 }
755
756 tracing::info!(name: "liftoff", endpoint = %rocket.endpoints[0]);
757 }
758
759 /// Returns the finalized, active configuration. This is guaranteed to
760 /// remain stable after [`Rocket::ignite()`], through ignition and into
761 /// orbit.
762 ///
763 /// # Example
764 ///
765 /// ```rust,no_run
766 /// # #[macro_use] extern crate rocket;
767 /// use rocket::fairing::AdHoc;
768 ///
769 /// #[launch]
770 /// fn rocket() -> _ {
771 /// rocket::build()
772 /// .attach(AdHoc::on_liftoff("Config", |rocket| Box::pin(async move {
773 /// println!("Rocket launch config: {:?}", rocket.config());
774 /// })))
775 /// }
776 /// ```
777 pub fn config(&self) -> &Config {
778 &self.config
779 }
780
781 pub fn endpoints(&self) -> impl Iterator<Item = &Endpoint> {
782 self.endpoints.iter()
783 }
784
785 /// Returns a handle which can be used to trigger a shutdown and detect a
786 /// triggered shutdown.
787 ///
788 /// A completed graceful shutdown resolves the future returned by
789 /// [`Rocket::launch()`]. See [`Shutdown`] and
790 /// [`ShutdownConfig`](crate::config::ShutdownConfig) for details on
791 /// graceful shutdown.
792 ///
793 /// # Example
794 ///
795 /// ```rust,no_run
796 /// # #[macro_use] extern crate rocket;
797 /// use rocket::tokio::{self, time};
798 /// use rocket::fairing::AdHoc;
799 ///
800 /// #[launch]
801 /// fn rocket() -> _ {
802 /// rocket::build()
803 /// .attach(AdHoc::on_liftoff("Shutdown", |rocket| Box::pin(async move {
804 /// let shutdown = rocket.shutdown();
805 /// tokio::spawn(async move {
806 /// time::sleep(time::Duration::from_secs(5)).await;
807 /// shutdown.notify();
808 /// });
809 /// })))
810 /// }
811 /// ```
812 pub fn shutdown(&self) -> Shutdown {
813 self.shutdown.start.clone()
814 }
815}
816
817impl<P: Phase> Rocket<P> {
818 /// Returns an iterator over all of the routes mounted on this instance of
819 /// Rocket. The order is unspecified.
820 ///
821 /// # Example
822 ///
823 /// ```rust
824 /// # use rocket::*;
825 /// use rocket::Rocket;
826 /// use rocket::fairing::AdHoc;
827 ///
828 /// #[get("/hello")]
829 /// fn hello() -> &'static str {
830 /// "Hello, world!"
831 /// }
832 ///
833 /// let rocket = rocket::build()
834 /// .mount("/", routes![hello])
835 /// .mount("/hi", routes![hello]);
836 ///
837 /// assert_eq!(rocket.routes().count(), 2);
838 /// assert!(rocket.routes().any(|r| r.uri == "/hello"));
839 /// assert!(rocket.routes().any(|r| r.uri == "/hi/hello"));
840 /// ```
841 pub fn routes(&self) -> impl Iterator<Item = &Route> {
842 match self.0.as_ref() {
843 StateRef::Build(p) => Either::Left(p.routes.iter()),
844 StateRef::Ignite(p) => Either::Right(p.router.routes.iter()),
845 StateRef::Orbit(p) => Either::Right(p.router.routes.iter()),
846 }
847 }
848
849 /// Returns an iterator over all of the catchers registered on this instance
850 /// of Rocket. The order is unspecified.
851 ///
852 /// # Example
853 ///
854 /// ```rust
855 /// # use rocket::*;
856 /// use rocket::Rocket;
857 /// use rocket::fairing::AdHoc;
858 ///
859 /// #[catch(404)] fn not_found() -> &'static str { "Nothing here, sorry!" }
860 /// #[catch(500)] fn just_500() -> &'static str { "Whoops!?" }
861 /// #[catch(default)] fn some_default() -> &'static str { "Everything else." }
862 ///
863 /// let rocket = rocket::build()
864 /// .register("/foo", catchers![not_found])
865 /// .register("/", catchers![just_500, some_default]);
866 ///
867 /// assert_eq!(rocket.catchers().count(), 3);
868 /// assert!(rocket.catchers().any(|c| c.code == Some(404) && c.base() == "/foo"));
869 /// assert!(rocket.catchers().any(|c| c.code == Some(500) && c.base() == "/"));
870 /// assert!(rocket.catchers().any(|c| c.code == None && c.base() == "/"));
871 /// ```
872 pub fn catchers(&self) -> impl Iterator<Item = &Catcher> {
873 match self.0.as_ref() {
874 StateRef::Build(p) => Either::Left(p.catchers.iter()),
875 StateRef::Ignite(p) => Either::Right(p.router.catchers.iter()),
876 StateRef::Orbit(p) => Either::Right(p.router.catchers.iter()),
877 }
878 }
879
880 /// Returns `Some` of the managed state value for the type `T` if it is
881 /// being managed by `self`. Otherwise, returns `None`.
882 ///
883 /// # Example
884 ///
885 /// ```rust
886 /// #[derive(PartialEq, Debug)]
887 /// struct MyState(&'static str);
888 ///
889 /// let rocket = rocket::build().manage(MyState("hello!"));
890 /// assert_eq!(rocket.state::<MyState>().unwrap(), &MyState("hello!"));
891 /// ```
892 pub fn state<T: Send + Sync + 'static>(&self) -> Option<&T> {
893 match self.0.as_ref() {
894 StateRef::Build(p) => p.state.try_get(),
895 StateRef::Ignite(p) => p.state.try_get(),
896 StateRef::Orbit(p) => p.state.try_get(),
897 }
898 }
899
900 /// Returns a reference to the first fairing of type `F` if it is attached.
901 /// Otherwise, returns `None`.
902 ///
903 /// To retrieve a _mutable_ reference to fairing `F`, use
904 /// [`Rocket::fairing_mut()`] instead.
905 ///
906 /// # Example
907 ///
908 /// ```rust
909 /// # use rocket::{Rocket, Request, Data, Response, Build, Orbit};
910 /// # use rocket::fairing::{self, Fairing, Info, Kind};
911 /// #
912 /// # #[rocket::async_trait]
913 /// # impl Fairing for MyFairing {
914 /// # fn info(&self) -> Info {
915 /// # Info { name: "", kind: Kind::Ignite }
916 /// # }
917 /// # }
918 /// #
919 /// # #[rocket::async_trait]
920 /// # impl Fairing for MySingletonFairing {
921 /// # fn info(&self) -> Info {
922 /// # Info { name: "", kind: Kind::Ignite | Kind::Singleton }
923 /// # }
924 /// # }
925 /// // A regular, non-singleton fairing.
926 /// struct MyFairing(&'static str);
927 ///
928 /// // A singleton fairing.
929 /// struct MySingletonFairing(&'static str);
930 ///
931 /// // fairing is not attached, returns `None`
932 /// let rocket = rocket::build();
933 /// assert!(rocket.fairing::<MyFairing>().is_none());
934 /// assert!(rocket.fairing::<MySingletonFairing>().is_none());
935 ///
936 /// // attach fairing, now returns `Some`
937 /// let rocket = rocket.attach(MyFairing("some state"));
938 /// assert!(rocket.fairing::<MyFairing>().is_some());
939 /// assert_eq!(rocket.fairing::<MyFairing>().unwrap().0, "some state");
940 ///
941 /// // it returns the first fairing of a given type only
942 /// let rocket = rocket.attach(MyFairing("other state"));
943 /// assert_eq!(rocket.fairing::<MyFairing>().unwrap().0, "some state");
944 ///
945 /// // attach fairing, now returns `Some`
946 /// let rocket = rocket.attach(MySingletonFairing("first"));
947 /// assert_eq!(rocket.fairing::<MySingletonFairing>().unwrap().0, "first");
948 ///
949 /// // recall that new singletons replace existing attached singletons
950 /// let rocket = rocket.attach(MySingletonFairing("second"));
951 /// assert_eq!(rocket.fairing::<MySingletonFairing>().unwrap().0, "second");
952 /// ```
953 pub fn fairing<F: Fairing>(&self) -> Option<&F> {
954 match self.0.as_ref() {
955 StateRef::Build(p) => p.fairings.filter::<F>().next(),
956 StateRef::Ignite(p) => p.fairings.filter::<F>().next(),
957 StateRef::Orbit(p) => p.fairings.filter::<F>().next(),
958 }
959 }
960
961 /// Returns an iterator over all attached fairings of type `F`, if any.
962 ///
963 /// # Example
964 ///
965 /// ```rust
966 /// # use rocket::{Rocket, Request, Data, Response, Build, Orbit};
967 /// # use rocket::fairing::{self, Fairing, Info, Kind};
968 /// #
969 /// # #[rocket::async_trait]
970 /// # impl Fairing for MyFairing {
971 /// # fn info(&self) -> Info {
972 /// # Info { name: "", kind: Kind::Ignite }
973 /// # }
974 /// # }
975 /// #
976 /// # #[rocket::async_trait]
977 /// # impl Fairing for MySingletonFairing {
978 /// # fn info(&self) -> Info {
979 /// # Info { name: "", kind: Kind::Ignite | Kind::Singleton }
980 /// # }
981 /// # }
982 /// // A regular, non-singleton fairing.
983 /// struct MyFairing(&'static str);
984 ///
985 /// // A singleton fairing.
986 /// struct MySingletonFairing(&'static str);
987 ///
988 /// let rocket = rocket::build();
989 /// assert_eq!(rocket.fairings::<MyFairing>().count(), 0);
990 /// assert_eq!(rocket.fairings::<MySingletonFairing>().count(), 0);
991 ///
992 /// let rocket = rocket.attach(MyFairing("some state"))
993 /// .attach(MySingletonFairing("first"))
994 /// .attach(MySingletonFairing("second"))
995 /// .attach(MyFairing("other state"))
996 /// .attach(MySingletonFairing("third"));
997 ///
998 /// let my_fairings: Vec<_> = rocket.fairings::<MyFairing>().collect();
999 /// assert_eq!(my_fairings.len(), 2);
1000 /// assert_eq!(my_fairings[0].0, "some state");
1001 /// assert_eq!(my_fairings[1].0, "other state");
1002 ///
1003 /// let my_singleton: Vec<_> = rocket.fairings::<MySingletonFairing>().collect();
1004 /// assert_eq!(my_singleton.len(), 1);
1005 /// assert_eq!(my_singleton[0].0, "third");
1006 /// ```
1007 pub fn fairings<F: Fairing>(&self) -> impl Iterator<Item = &F> {
1008 match self.0.as_ref() {
1009 StateRef::Build(p) => Either::Left(p.fairings.filter::<F>()),
1010 StateRef::Ignite(p) => Either::Right(p.fairings.filter::<F>()),
1011 StateRef::Orbit(p) => Either::Right(p.fairings.filter::<F>()),
1012 }
1013 }
1014
1015 /// Returns a mutable reference to the first fairing of type `F` if it is
1016 /// attached. Otherwise, returns `None`.
1017 ///
1018 /// # Example
1019 ///
1020 /// ```rust
1021 /// # use rocket::{Rocket, Request, Data, Response, Build, Orbit};
1022 /// # use rocket::fairing::{self, Fairing, Info, Kind};
1023 /// #
1024 /// # #[rocket::async_trait]
1025 /// # impl Fairing for MyFairing {
1026 /// # fn info(&self) -> Info {
1027 /// # Info { name: "", kind: Kind::Ignite }
1028 /// # }
1029 /// # }
1030 /// // A regular, non-singleton fairing.
1031 /// struct MyFairing(&'static str);
1032 ///
1033 /// // fairing is not attached, returns `None`
1034 /// let mut rocket = rocket::build();
1035 /// assert!(rocket.fairing_mut::<MyFairing>().is_none());
1036 ///
1037 /// // attach fairing, now returns `Some`
1038 /// let mut rocket = rocket.attach(MyFairing("some state"));
1039 /// assert!(rocket.fairing_mut::<MyFairing>().is_some());
1040 /// assert_eq!(rocket.fairing_mut::<MyFairing>().unwrap().0, "some state");
1041 ///
1042 /// // we can modify the fairing
1043 /// rocket.fairing_mut::<MyFairing>().unwrap().0 = "other state";
1044 /// assert_eq!(rocket.fairing_mut::<MyFairing>().unwrap().0, "other state");
1045 ///
1046 /// // it returns the first fairing of a given type only
1047 /// let mut rocket = rocket.attach(MyFairing("yet more state"));
1048 /// assert_eq!(rocket.fairing_mut::<MyFairing>().unwrap().0, "other state");
1049 /// ```
1050 pub fn fairing_mut<F: Fairing>(&mut self) -> Option<&mut F> {
1051 match self.0.as_mut() {
1052 StateRefMut::Build(p) => p.fairings.filter_mut::<F>().next(),
1053 StateRefMut::Ignite(p) => p.fairings.filter_mut::<F>().next(),
1054 StateRefMut::Orbit(p) => p.fairings.filter_mut::<F>().next(),
1055 }
1056 }
1057
1058 /// Returns an iterator of mutable references to all attached fairings of
1059 /// type `F`, if any.
1060 ///
1061 /// # Example
1062 ///
1063 /// ```rust
1064 /// # use rocket::{Rocket, Request, Data, Response, Build, Orbit};
1065 /// # use rocket::fairing::{self, Fairing, Info, Kind};
1066 /// #
1067 /// # #[rocket::async_trait]
1068 /// # impl Fairing for MyFairing {
1069 /// # fn info(&self) -> Info {
1070 /// # Info { name: "", kind: Kind::Ignite }
1071 /// # }
1072 /// # }
1073 /// // A regular, non-singleton fairing.
1074 /// struct MyFairing(&'static str);
1075 ///
1076 /// let mut rocket = rocket::build()
1077 /// .attach(MyFairing("some state"))
1078 /// .attach(MyFairing("other state"))
1079 /// .attach(MyFairing("yet more state"));
1080 ///
1081 /// let mut fairings: Vec<_> = rocket.fairings_mut::<MyFairing>().collect();
1082 /// assert_eq!(fairings.len(), 3);
1083 /// assert_eq!(fairings[0].0, "some state");
1084 /// assert_eq!(fairings[1].0, "other state");
1085 /// assert_eq!(fairings[2].0, "yet more state");
1086 ///
1087 /// // we can modify the fairings
1088 /// fairings[1].0 = "modified state";
1089 ///
1090 /// let fairings: Vec<_> = rocket.fairings::<MyFairing>().collect();
1091 /// assert_eq!(fairings.len(), 3);
1092 /// assert_eq!(fairings[0].0, "some state");
1093 /// assert_eq!(fairings[1].0, "modified state");
1094 /// assert_eq!(fairings[2].0, "yet more state");
1095 /// ```
1096 pub fn fairings_mut<F: Fairing>(&mut self) -> impl Iterator<Item = &mut F> {
1097 match self.0.as_mut() {
1098 StateRefMut::Build(p) => Either::Left(p.fairings.filter_mut::<F>()),
1099 StateRefMut::Ignite(p) => Either::Right(p.fairings.filter_mut::<F>()),
1100 StateRefMut::Orbit(p) => Either::Right(p.fairings.filter_mut::<F>()),
1101 }
1102 }
1103
1104 /// Returns the figment derived from the configuration provider set for
1105 /// `self`. To extract a typed config, prefer to use
1106 /// [`AdHoc::config()`](crate::fairing::AdHoc::config()).
1107 ///
1108 /// Note; A [`Figment`] generated from the current `provider` can _always_
1109 /// be retrieved via this method. However, because the provider can be
1110 /// changed at any point prior to ignition, a [`Config`] can only be
1111 /// retrieved in the ignite or orbit phases, or by manually extracting one
1112 /// from a particular figment.
1113 ///
1114 /// # Example
1115 ///
1116 /// ```rust
1117 /// let rocket = rocket::build();
1118 /// let figment = rocket.figment();
1119 /// ```
1120 pub fn figment(&self) -> &Figment {
1121 match self.0.as_ref() {
1122 StateRef::Build(p) => &p.figment,
1123 StateRef::Ignite(p) => &p.figment,
1124 StateRef::Orbit(p) => &p.figment,
1125 }
1126 }
1127
1128 async fn into_ignite(self) -> Result<Rocket<Ignite>, Error> {
1129 match self.0.into_state() {
1130 State::Build(s) => Rocket::from(s).ignite().await,
1131 State::Ignite(s) => Ok(Rocket::from(s)),
1132 State::Orbit(s) => Ok(Rocket::from(s).deorbit()),
1133 }
1134 }
1135
1136 pub(crate) async fn local_launch(self, e: Endpoint) -> Result<Rocket<Orbit>, Error> {
1137 Ok(self.into_ignite().await?._local_launch(e).await)
1138 }
1139
1140 /// Returns a `Future` that transitions this instance of `Rocket` from any
1141 /// phase into the _orbit_ phase. When `await`ed, the future drives the
1142 /// server forward, listening for and dispatching requests to mounted routes
1143 /// and catchers.
1144 ///
1145 /// In addition to all of the processes that occur during
1146 /// [ignition](Rocket::ignite()), a successful launch results in _liftoff_
1147 /// fairings being executed _after_ binding to any respective network
1148 /// interfaces but before serving the first request. Liftoff fairings are
1149 /// run concurrently; resolution of all fairings is `await`ed before
1150 /// resuming request serving.
1151 ///
1152 /// The `Future` resolves as an `Err` if any of the following occur:
1153 ///
1154 /// * there is an error igniting; see [`Rocket::ignite()`].
1155 /// * there is an I/O error starting the server.
1156 /// * an unrecoverable, system-level error occurs while running.
1157 ///
1158 /// The `Future` resolves as an `Ok` if any of the following occur:
1159 ///
1160 /// * graceful shutdown via [`Shutdown::notify()`] completes.
1161 ///
1162 /// The returned value on `Ok(())` is previously running instance.
1163 ///
1164 /// The `Future` does not resolve otherwise.
1165 ///
1166 /// # Error
1167 ///
1168 /// If there is a problem starting the application or the application fails
1169 /// unexpectedly while running, an [`Error`] is returned. Note that a value
1170 /// of type `Error` panics if dropped without first being inspected. See the
1171 /// [`Error`] documentation for more information.
1172 ///
1173 /// # Example
1174 ///
1175 /// ```rust,no_run
1176 /// #[rocket::main]
1177 /// async fn main() {
1178 /// let result = rocket::build().launch().await;
1179 ///
1180 /// // this is reachable only after `Shutdown::notify()` or `Ctrl+C`.
1181 /// println!("Rocket: deorbit.");
1182 /// }
1183 /// ```
1184 pub async fn launch(self) -> Result<Rocket<Ignite>, Error> {
1185 self.launch_with::<DefaultListener>().await
1186 }
1187
1188 pub async fn launch_with<B: Bind>(self) -> Result<Rocket<Ignite>, Error> {
1189 let rocket = self.into_ignite().await?;
1190 let bind_endpoint = B::bind_endpoint(&rocket).ok();
1191 let listener: B = B::bind(&rocket).await
1192 .map_err(|e| ErrorKind::Bind(bind_endpoint, Box::new(e)))?;
1193
1194 let any: Box<dyn Any + Send + Sync> = Box::new(listener);
1195 match any.downcast::<DefaultListener>() {
1196 Ok(listener) => {
1197 let listener = *listener;
1198 crate::util::for_both!(listener, listener => {
1199 crate::util::for_both!(listener, listener => {
1200 rocket._launch(listener).await
1201 })
1202 })
1203 }
1204 Err(any) => {
1205 let listener = *any.downcast::<B>().unwrap();
1206 rocket._launch(listener).await
1207 }
1208 }
1209 }
1210
1211 pub async fn try_launch_on<L, F, E>(self, listener: F) -> Result<Rocket<Ignite>, Error>
1212 where L: Listener + 'static,
1213 F: Future<Output = Result<L, E>>,
1214 E: std::error::Error + Send + 'static
1215 {
1216 let listener = listener.map_err(|e| ErrorKind::Bind(None, Box::new(e))).await?;
1217 self.into_ignite().await?._launch(listener).await
1218 }
1219
1220 pub async fn launch_on<L>(self, listener: L) -> Result<Rocket<Ignite>, Error>
1221 where L: Listener + 'static,
1222 {
1223 self.into_ignite().await?._launch(listener).await
1224 }
1225}
1226
1227#[doc(hidden)]
1228impl<P: Phase> Deref for Rocket<P> {
1229 type Target = P::State;
1230
1231 fn deref(&self) -> &Self::Target {
1232 &self.0
1233 }
1234}
1235
1236#[doc(hidden)]
1237impl<P: Phase> DerefMut for Rocket<P> {
1238 fn deref_mut(&mut self) -> &mut Self::Target {
1239 &mut self.0
1240 }
1241}
1242
1243impl<P: Phase> fmt::Debug for Rocket<P> {
1244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1245 self.0.fmt(f)
1246 }
1247}