]> git.proxmox.com Git - proxmox-backup.git/commitdiff
proxmox-rest-server: make get_index async
authorDietmar Maurer <dietmar@proxmox.com>
Fri, 1 Oct 2021 07:38:10 +0000 (09:38 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 1 Oct 2021 07:38:10 +0000 (09:38 +0200)
proxmox-rest-server/examples/minimal-rest-server.rs
proxmox-rest-server/src/api_config.rs
proxmox-rest-server/src/rest.rs
proxmox-restore-daemon/src/main.rs
src/bin/proxmox-backup-api.rs
src/bin/proxmox-backup-proxy.rs

index 8954ce761807372b0d517abf1b61ae5323bb9d25..fadb99d55501043fc655895e58550d5c2ec7cd5b 100644 (file)
@@ -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<String>,
     _language: Option<String>,
-    _api: &ApiConfig,
+    _api: &'a ApiConfig,
     _parts: http::request::Parts,
-) -> http::Response<hyper::Body> {
-    // build an index page
-    http::Response::builder()
-        .body("hello world".into())
-        .unwrap()
+) -> Pin<Box<dyn Future<Output = http::Response<hyper::Body>> + 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);
 
index f94390a71080f7087f9d4a0ff7e8a6df78e56b76..be7fbc23c1022ed693aba232060520976914d681 100644 (file)
@@ -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<String>, Option<String>, &ApiConfig, Parts) -> Response<Body>;
+pub type GetIndexFn = &'static (dyn for<'a> Fn(Option<String>, Option<String>, &'a ApiConfig, Parts) -> Pin<Box<dyn Future<Output = Response<Body>> + 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<String>,
         language: Option<String>,
         parts: Parts,
     ) -> Response<Body> {
-        (self.get_index_fn)(auth_id, language, self, parts)
+        (self.get_index_fn)(auth_id, language, self, parts).await
     }
 
     pub(crate) fn find_method(
index d56edb1204e4d15aba9ec27679e0f9ff1419c703..5f7ecbaa9f2be26ae3a87747c5158380d4af7bf5 100644 (file)
@@ -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);
index 9cf7f75574771d7835c0d1551c26687ceef81e35..139adebd50c082b4335728c9775d4b7afe7184ee 100644 (file)
@@ -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<String>,
     _language: Option<String>,
-    _api: &ApiConfig,
+    _api: &'a ApiConfig,
     _parts: Parts,
-) -> Response<Body> {
+) -> Pin<Box<dyn Future<Output = http::Response<Body>> + Send + 'a>> {
+    Box::pin(async move {
 
-    let index = "<center><h1>Proxmox Backup Restore Daemon/h1></center>";
+        let index = "<center><h1>Proxmox Backup Restore Daemon/h1></center>";
 
-    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()?;
index 713f7f19504c401996a3745ae5f2beca59f1825b..f0d09ecd30bf3cf894eb31031ffb58e57e8c3e03 100644 (file)
@@ -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<String>,
     _language: Option<String>,
-    _api: &ApiConfig,
+    _api: &'a ApiConfig,
     _parts: Parts,
-) -> Response<Body> {
+) -> Pin<Box<dyn Future<Output = Response<Body>> + Send + 'a>> {
+    Box::pin(async move {
 
-    let index = "<center><h1>Proxmox Backup API Server</h1></center>";
+        let index = "<center><h1>Proxmox Backup API Server</h1></center>";
 
-    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()?;
index 17a100a1b77b74f6d61a94aa5b4ac6fe6adfbe06..4b84e8b2740122083f9bf29f9d46df6c5353321a 100644 (file)
@@ -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<String>,
+    language: Option<String>,
+    api: &'a ApiConfig,
+    parts: Parts,
+) -> Pin<Box<dyn Future<Output = Response<Body>> + Send + 'a>> {
+    Box::pin(get_index_future(auth_id, language, api, parts))
+}
+
+async fn get_index_future(
     auth_id: Option<String>,
     language: Option<String>,
     api: &ApiConfig,
     parts: Parts,
 ) -> Response<Body> {
 
+    // fixme: make all IO async
+
     let (userid, csrf_token) = match auth_id {
         Some(auth_id) => {
             let auth_id = auth_id.parse::<Authid>();
@@ -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");