From 6680878b5c236869c332e297e2756b27138a404a Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Fri, 1 Oct 2021 09:38:10 +0200 Subject: [PATCH] proxmox-rest-server: make get_index async --- .../examples/minimal-rest-server.rs | 18 +++++++------ proxmox-rest-server/src/api_config.rs | 8 +++--- proxmox-rest-server/src/rest.rs | 4 +-- proxmox-restore-daemon/src/main.rs | 24 ++++++++++-------- src/bin/proxmox-backup-api.rs | 25 +++++++++++-------- src/bin/proxmox-backup-proxy.rs | 17 +++++++++++-- 6 files changed, 61 insertions(+), 35 deletions(-) diff --git a/proxmox-rest-server/examples/minimal-rest-server.rs b/proxmox-rest-server/examples/minimal-rest-server.rs index 8954ce76..fadb99d5 100644 --- a/proxmox-rest-server/examples/minimal-rest-server.rs +++ b/proxmox-rest-server/examples/minimal-rest-server.rs @@ -45,16 +45,18 @@ impl ApiAuth for DummyAuth { // this should return the index page of the webserver // iow. what the user browses to -fn get_index( +fn get_index<'a>( _auth_id: Option, _language: Option, - _api: &ApiConfig, + _api: &'a ApiConfig, _parts: http::request::Parts, -) -> http::Response { - // build an index page - http::Response::builder() - .body("hello world".into()) - .unwrap() +) -> Pin> + Send + 'a>> { + Box::pin(async move { + // build an index page + http::Response::builder() + .body("hello world".into()) + .unwrap() + }) } // a few examples on how to do api calls with the Router @@ -191,7 +193,7 @@ async fn run() -> Result<(), Error> { &ROUTER, RpcEnvironmentType::PUBLIC, Arc::new(DummyAuth {}), - get_index, + &get_index, )?; let rest_server = RestServer::new(config); diff --git a/proxmox-rest-server/src/api_config.rs b/proxmox-rest-server/src/api_config.rs index f94390a7..be7fbc23 100644 --- a/proxmox-rest-server/src/api_config.rs +++ b/proxmox-rest-server/src/api_config.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; use std::time::SystemTime; use std::fs::metadata; use std::sync::{Arc, Mutex, RwLock}; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, Error, format_err}; use hyper::{Method, Body, Response}; @@ -16,7 +18,7 @@ use proxmox::tools::fs::{create_path, CreateOptions}; use crate::{ApiAuth, FileLogger, FileLogOptions, CommandSocket}; -pub type GetIndexFn = fn(Option, Option, &ApiConfig, Parts) -> Response; +pub type GetIndexFn = &'static (dyn for<'a> Fn(Option, Option, &'a ApiConfig, Parts) -> Pin> + Send + 'a>> + Send + Sync); /// REST server configuration pub struct ApiConfig { @@ -68,13 +70,13 @@ impl ApiConfig { }) } - pub(crate) fn get_index( + pub(crate) async fn get_index( &self, auth_id: Option, language: Option, parts: Parts, ) -> Response { - (self.get_index_fn)(auth_id, language, self, parts) + (self.get_index_fn)(auth_id, language, self, parts).await } pub(crate) fn find_method( diff --git a/proxmox-rest-server/src/rest.rs b/proxmox-rest-server/src/rest.rs index d56edb12..5f7ecbaa 100644 --- a/proxmox-rest-server/src/rest.rs +++ b/proxmox-rest-server/src/rest.rs @@ -732,14 +732,14 @@ async fn handle_request( let language = extract_lang_header(&parts.headers); match auth.check_auth(&parts.headers, &method).await { Ok((auth_id, _user_info)) => { - return Ok(api.get_index(Some(auth_id), language, parts)); + return Ok(api.get_index(Some(auth_id), language, parts).await); } Err(AuthError::Generic(_)) => { tokio::time::sleep_until(Instant::from_std(delay_unauth_time)).await; } Err(AuthError::NoData) => {} } - return Ok(api.get_index(None, language, parts)); + return Ok(api.get_index(None, language, parts).await); } else { let filename = api.find_alias(&components); let compression = extract_compression_method(&parts.headers); diff --git a/proxmox-restore-daemon/src/main.rs b/proxmox-restore-daemon/src/main.rs index 9cf7f755..139adebd 100644 --- a/proxmox-restore-daemon/src/main.rs +++ b/proxmox-restore-daemon/src/main.rs @@ -7,6 +7,8 @@ use std::os::unix::{ }; use std::path::Path; use std::sync::{Arc, Mutex}; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; use lazy_static::lazy_static; @@ -91,20 +93,22 @@ fn setup_system_env() -> Result<(), Error> { Ok(()) } -fn get_index( +fn get_index<'a>( _auth_id: Option, _language: Option, - _api: &ApiConfig, + _api: &'a ApiConfig, _parts: Parts, -) -> Response { +) -> Pin> + Send + 'a>> { + Box::pin(async move { - let index = "

Proxmox Backup Restore Daemon/h1>

"; + let index = "

Proxmox Backup Restore Daemon/h1>

"; - Response::builder() - .status(StatusCode::OK) - .header(header::CONTENT_TYPE, "text/html") - .body(index.into()) - .unwrap() + Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/html") + .body(index.into()) + .unwrap() + }) } async fn run() -> Result<(), Error> { @@ -113,7 +117,7 @@ async fn run() -> Result<(), Error> { let auth_config = Arc::new( auth::ticket_auth().map_err(|err| format_err!("reading ticket file failed: {}", err))?, ); - let config = ApiConfig::new("", &ROUTER, RpcEnvironmentType::PUBLIC, auth_config, get_index)?; + let config = ApiConfig::new("", &ROUTER, RpcEnvironmentType::PUBLIC, auth_config, &get_index)?; let rest_server = RestServer::new(config); let vsock_fd = get_vsock_fd()?; diff --git a/src/bin/proxmox-backup-api.rs b/src/bin/proxmox-backup-api.rs index 713f7f19..f0d09ecd 100644 --- a/src/bin/proxmox-backup-api.rs +++ b/src/bin/proxmox-backup-api.rs @@ -1,3 +1,6 @@ +use std::future::Future; +use std::pin::Pin; + use anyhow::{bail, Error}; use futures::*; use http::request::Parts; @@ -24,20 +27,22 @@ fn main() { } } -fn get_index( +fn get_index<'a>( _auth_id: Option, _language: Option, - _api: &ApiConfig, + _api: &'a ApiConfig, _parts: Parts, -) -> Response { +) -> Pin> + Send + 'a>> { + Box::pin(async move { - let index = "

Proxmox Backup API Server

"; + let index = "

Proxmox Backup API Server

"; - Response::builder() - .status(StatusCode::OK) - .header(header::CONTENT_TYPE, "text/html") - .body(index.into()) - .unwrap() + Response::builder() + .status(StatusCode::OK) + .header(header::CONTENT_TYPE, "text/html") + .body(index.into()) + .unwrap() + }) } async fn run() -> Result<(), Error> { @@ -76,7 +81,7 @@ async fn run() -> Result<(), Error> { &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PRIVILEGED, default_api_auth(), - get_index, + &get_index, )?; let backup_user = pbs_config::backup_user()?; diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index 17a100a1..4b84e8b2 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -1,6 +1,8 @@ use std::sync::{Mutex, Arc}; use std::path::{Path, PathBuf}; use std::os::unix::io::AsRawFd; +use std::future::Future; +use std::pin::Pin; use anyhow::{bail, format_err, Error}; use futures::*; @@ -76,13 +78,24 @@ fn main() -> Result<(), Error> { pbs_runtime::main(run()) } -fn get_index( +fn get_index<'a>( + auth_id: Option, + language: Option, + api: &'a ApiConfig, + parts: Parts, +) -> Pin> + Send + 'a>> { + Box::pin(get_index_future(auth_id, language, api, parts)) +} + +async fn get_index_future( auth_id: Option, language: Option, api: &ApiConfig, parts: Parts, ) -> Response { + // fixme: make all IO async + let (userid, csrf_token) = match auth_id { Some(auth_id) => { let auth_id = auth_id.parse::(); @@ -169,7 +182,7 @@ async fn run() -> Result<(), Error> { &proxmox_backup::api2::ROUTER, RpcEnvironmentType::PUBLIC, default_api_auth(), - get_index, + &get_index, )?; config.add_alias("novnc", "/usr/share/novnc-pve");