2018-06-28 15:55:15 +00:00
|
|
|
#[macro_use] extern crate rocket;
|
2017-04-20 20:43:01 +00:00
|
|
|
|
|
|
|
use std::io::Cursor;
|
2017-05-15 04:46:01 +00:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2021-03-10 05:13:26 +00:00
|
|
|
use std::sync::Arc;
|
2017-04-20 20:43:01 +00:00
|
|
|
|
2021-03-11 06:30:23 +00:00
|
|
|
use rocket::{Rocket, Request, State, Data};
|
2017-05-15 04:46:01 +00:00
|
|
|
use rocket::fairing::{AdHoc, Fairing, Info, Kind};
|
2021-03-11 06:30:23 +00:00
|
|
|
use rocket::http::Method;
|
2017-04-20 20:43:01 +00:00
|
|
|
|
2017-05-17 08:39:36 +00:00
|
|
|
struct Token(i64);
|
|
|
|
|
2017-04-20 20:43:01 +00:00
|
|
|
#[cfg(test)] mod tests;
|
|
|
|
|
2021-03-10 05:13:26 +00:00
|
|
|
#[derive(Default, Clone)]
|
2017-05-15 04:46:01 +00:00
|
|
|
struct Counter {
|
2021-03-10 05:13:26 +00:00
|
|
|
get: Arc<AtomicUsize>,
|
|
|
|
post: Arc<AtomicUsize>,
|
2017-05-15 04:46:01 +00:00
|
|
|
}
|
|
|
|
|
2020-01-31 04:47:57 +00:00
|
|
|
#[rocket::async_trait]
|
2017-05-15 04:46:01 +00:00
|
|
|
impl Fairing for Counter {
|
|
|
|
fn info(&self) -> Info {
|
|
|
|
Info {
|
|
|
|
name: "GET/POST Counter",
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
kind: Kind::Launch | Kind::Request
|
2017-05-15 04:46:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
async fn on_launch(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
|
2021-03-10 05:13:26 +00:00
|
|
|
#[get("/counts")]
|
|
|
|
fn counts(counts: State<'_, Counter>) -> String {
|
|
|
|
let get_count = counts.get.load(Ordering::Relaxed);
|
|
|
|
let post_count = counts.post.load(Ordering::Relaxed);
|
|
|
|
format!("Get: {}\nPost: {}", get_count, post_count)
|
2020-01-31 04:47:57 +00:00
|
|
|
}
|
2017-05-15 04:46:01 +00:00
|
|
|
|
2021-03-10 05:13:26 +00:00
|
|
|
Ok(rocket.manage(self.clone()).mount("/", routes![counts]))
|
2017-05-15 04:46:01 +00:00
|
|
|
}
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
|
|
|
|
async fn on_request(&self, request: &mut Request<'_>, _: &mut Data) {
|
|
|
|
if request.method() == Method::Get {
|
|
|
|
self.get.fetch_add(1, Ordering::Relaxed);
|
|
|
|
} else if request.method() == Method::Post {
|
|
|
|
self.post.fetch_add(1, Ordering::Relaxed);
|
|
|
|
}
|
|
|
|
}
|
2017-05-15 04:46:01 +00:00
|
|
|
}
|
|
|
|
|
2017-04-20 20:43:01 +00:00
|
|
|
#[put("/")]
|
|
|
|
fn hello() -> &'static str {
|
|
|
|
"Hello, world!"
|
|
|
|
}
|
|
|
|
|
2017-05-17 08:39:36 +00:00
|
|
|
#[get("/token")]
|
2019-06-13 02:41:29 +00:00
|
|
|
fn token(token: State<'_, Token>) -> String {
|
2017-05-17 08:39:36 +00:00
|
|
|
format!("{}", token.0)
|
|
|
|
}
|
|
|
|
|
2020-07-22 23:10:02 +00:00
|
|
|
#[launch]
|
2021-04-08 02:01:48 +00:00
|
|
|
fn rocket() -> _ {
|
2017-04-20 20:43:01 +00:00
|
|
|
rocket::ignite()
|
2017-05-17 08:39:36 +00:00
|
|
|
.mount("/", routes![hello, token])
|
2017-05-15 04:46:01 +00:00
|
|
|
.attach(Counter::default())
|
2021-04-08 02:01:48 +00:00
|
|
|
.attach(AdHoc::try_on_launch("Token State", |rocket| async {
|
2017-05-17 08:39:36 +00:00
|
|
|
println!("Adding token managed state...");
|
2020-10-22 10:27:04 +00:00
|
|
|
match rocket.figment().extract_inner("token") {
|
2020-09-03 05:41:31 +00:00
|
|
|
Ok(value) => Ok(rocket.manage(Token(value))),
|
|
|
|
Err(_) => Err(rocket)
|
|
|
|
}
|
2017-05-17 08:39:36 +00:00
|
|
|
}))
|
Remove 'attach' fairings. Add 'liftoff' fairings.
Launch fairings are now fallible and take the place of attach fairings,
but they are only run, as the name implies, at launch time.
This is is a fundamental shift from eager execution of set-up routines,
including the now defunct attach fairings, to lazy execution,
precipitated by the transition to `async`. The previous functionality,
while simple, caused grave issues:
1. A instance of 'Rocket' with async attach fairings requires an async
runtime to be constructed.
2. The instance is accessible in non-async contexts.
3. The async attach fairings have no runtime in which to be run.
Here's an example:
```rust
let rocket = rocket::ignite()
.attach(AttachFairing::from(|rocket| async {
Ok(rocket.manage(load_from_network::<T>().await))
}));
let state = rocket.state::<T>();
```
This had no real meaning previously yet was accepted by running the
attach fairing future in an isolated runtime. In isolation, this causes
no issue, but when attach fairing futures share reactor state with other
futures in Rocket, panics ensue.
The new Rocket application lifecycle is this:
* Build - A Rocket instance is constructed. No fairings are run.
* Ignition - All launch fairings are run.
* Liftoff - If all launch fairings succeeded, the server is started.
New 'liftoff' fairings are run in this third phase.
2021-04-01 19:32:52 +00:00
|
|
|
.attach(AdHoc::on_liftoff("Liftoff Message", |_| Box::pin(async move {
|
|
|
|
println!("We have liftoff!");
|
|
|
|
})))
|
2018-08-14 16:14:06 +00:00
|
|
|
.attach(AdHoc::on_request("PUT Rewriter", |req, _| {
|
2019-12-11 00:34:32 +00:00
|
|
|
Box::pin(async move {
|
|
|
|
println!(" => Incoming request: {}", req);
|
|
|
|
if req.uri().path() == "/" {
|
|
|
|
println!(" => Changing method to `PUT`.");
|
|
|
|
req.set_method(Method::Put);
|
|
|
|
}
|
|
|
|
})
|
2017-05-15 04:46:01 +00:00
|
|
|
}))
|
2018-08-14 16:14:06 +00:00
|
|
|
.attach(AdHoc::on_response("Response Rewriter", |req, res| {
|
2019-08-04 22:36:55 +00:00
|
|
|
Box::pin(async move {
|
|
|
|
if req.uri().path() == "/" {
|
|
|
|
println!(" => Rewriting response body.");
|
2020-06-19 13:01:10 +00:00
|
|
|
res.set_sized_body(None, Cursor::new("Hello, fairings!"));
|
2019-08-04 22:36:55 +00:00
|
|
|
}
|
|
|
|
})
|
2017-05-15 04:46:01 +00:00
|
|
|
}))
|
2017-04-20 20:43:01 +00:00
|
|
|
}
|