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}