Comment passer une variable à actix-web guard () dans Rust?
Sep 06 2020
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
let token = env::var("TOKEN").expect("Set TOKEN");
HttpServer::new(|| {
App::new()
.wrap(middleware::Logger::default())
.service(
web::resource("/")
.guard(guard::Header("TOKEN", &token))
.route(web::post().to(index))
)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
L'erreur est:
error[E0597]: `token` does not live long enough
J'ai vu .data()dans la documentation actix mais c'est pour passer des variables à l'intérieur des fonctions de routes.
UPD:
Si j'ajoute "déplacer":
HttpServer::new(move || {
alors juste les changements d'erreur:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 42:21...
--> src/main.rs:42:21
|
42 | HttpServer::new(move || {
| ^^^^^^^
note: ...so that closure can access `token`
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> src/main.rs:50:58
|
50 | .guard(guard::Header("TOKEN", &token))
| ^^^^^^
error: aborting due to previous error
Réponses
Sergey Sep 06 2020 at 19:41
actix-web crée de nombreux threads et chaque worker (dans chaque thread) doit obtenir une copie d'une variable. Donc en utilisant let token = token.clone();et move.
Après cela, chacune de ces variables entre en fn_guardfonction. Donc encore une fois move.
let token = env::var("TOKEN").expect("You must set TOKEN");
HttpServer::new(move || {
let token = token.clone();
App::new()
.wrap(middleware::Logger::default())
.service(
web::resource("/")
.guard(guard::fn_guard(
move |req| match req.headers().get("TOKEN") {
Some(value) => value == token.as_str(),
None => false,
}))
.route(web::post().to(index))
)
})
.bind("127.0.0.1:8080")?
.run()
.await
Cela marche.
Je ne peux pas le faire fonctionner uniquement avec .guard(guard::Header("TOKEN", &token))