// 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
&ROUTER,
RpcEnvironmentType::PUBLIC,
Arc::new(DummyAuth {}),
- get_index,
+ &get_index,
)?;
let rest_server = RestServer::new(config);
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};
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 {
})
}
- 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(
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);
};
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;
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> {
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()?;
+use std::future::Future;
+use std::pin::Pin;
+
use anyhow::{bail, Error};
use futures::*;
use http::request::Parts;
}
}
-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> {
&proxmox_backup::api2::ROUTER,
RpcEnvironmentType::PRIVILEGED,
default_api_auth(),
- get_index,
+ &get_index,
)?;
let backup_user = pbs_config::backup_user()?;
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::*;
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>();
&proxmox_backup::api2::ROUTER,
RpcEnvironmentType::PUBLIC,
default_api_auth(),
- get_index,
+ &get_index,
)?;
config.add_alias("novnc", "/usr/share/novnc-pve");