router: make hyper/http optional

but enable it by default.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2022-08-03 14:44:53 +02:00
parent f92c8f92cc
commit 66ace63618
5 changed files with 24 additions and 4 deletions

View File

@ -11,8 +11,8 @@ exclude = [ "debian" ]
[dependencies]
anyhow = "1.0"
env_logger = { version = "0.9", optional = true }
http = "0.2"
hyper = { version = "0.14", features = [ "full" ] }
http = { version = "0.2", optional = true }
hyper = { version = "0.14", features = [ "full" ], optional = true }
nix = "0.24.1"
percent-encoding = "2.1"
serde_json = "1.0"
@ -29,6 +29,7 @@ proxmox-schema = { path = "../proxmox-schema", version = "1.1" }
proxmox-async = { path = "../proxmox-async", version = "0.4.1" }
[features]
default = [ "cli" ]
default = [ "cli", "server" ]
cli = [ "dep:env_logger", "dep:libc", "dep:rustyline", "dep:tokio" ]
server = [ "dep:http", "dep:hyper" ]
test-harness = [ "proxmox-schema/test-harness" ]

View File

@ -68,6 +68,7 @@ async fn handle_simple_command_future(
ApiHandler::StreamingAsync(handler) => (handler)(params, cli_cmd.info, &mut rpcenv)
.await
.and_then(|r| r.to_value().map_err(Error::from)),
#[cfg(feature = "server")]
ApiHandler::AsyncHttp(_) => {
let err_msg = "CliHandler does not support ApiHandler::AsyncHttp - internal error";
print_simple_usage_error(prefix, cli_cmd, err_msg);
@ -119,6 +120,7 @@ fn handle_simple_command(
print_simple_usage_error(prefix, cli_cmd, err_msg);
return Err(format_err!("{}", err_msg));
}
#[cfg(feature = "server")]
ApiHandler::AsyncHttp(_) => {
let err_msg = "CliHandler does not support ApiHandler::AsyncHttp - internal error";
print_simple_usage_error(prefix, cli_cmd, err_msg);

View File

@ -7,7 +7,9 @@ use anyhow::Error;
use proxmox_schema::format::*;
use proxmox_schema::ObjectSchemaType;
use crate::{ApiHandler, ApiMethod};
#[cfg(feature = "server")]
use crate::ApiHandler;
use crate::ApiMethod;
fn dump_method_definition(method: &str, path: &str, def: Option<&ApiMethod>) -> Option<String> {
let style = ParameterDisplayStyle::Config;
@ -19,8 +21,12 @@ fn dump_method_definition(method: &str, path: &str, def: Option<&ApiMethod>) ->
let return_descr = dump_api_return_schema(&api_method.returns, style);
#[cfg(feature = "server")]
let mut method = method;
#[cfg(not(feature = "server"))]
let method = method;
#[cfg(feature = "server")]
if let ApiHandler::AsyncHttp(_) = api_method.handler {
method = if method == "POST" { "UPLOAD" } else { method };
method = if method == "GET" { "DOWNLOAD" } else { method };

View File

@ -7,6 +7,7 @@ pub mod cli;
// this is public so the `http_err!` macro can access `http::StatusCode` through it
#[doc(hidden)]
#[cfg(feature = "server")]
pub mod error;
mod permission;
@ -15,6 +16,7 @@ mod rpc_environment;
mod serializable_return;
#[doc(inline)]
#[cfg(feature = "server")]
pub use error::HttpError;
pub use permission::*;

View File

@ -4,8 +4,11 @@ use std::future::Future;
use std::pin::Pin;
use anyhow::Error;
#[cfg(feature = "server")]
use http::request::Parts;
#[cfg(feature = "server")]
use http::{Method, Response};
#[cfg(feature = "server")]
use hyper::Body;
use percent_encoding::percent_decode_str;
use serde_json::Value;
@ -176,6 +179,7 @@ pub type StreamingApiFuture<'a> = Pin<
/// &ObjectSchema::new("Hello World Example (low level)", &[])
/// );
/// ```
#[cfg(feature = "server")]
pub type ApiAsyncHttpHandlerFn = &'static (dyn Fn(
Parts,
Body,
@ -188,15 +192,18 @@ pub type ApiAsyncHttpHandlerFn = &'static (dyn Fn(
+ 'static);
/// The output of an asynchronous API handler is a future yielding a `Response`.
#[cfg(feature = "server")]
pub type ApiResponseFuture =
Pin<Box<dyn Future<Output = Result<Response<Body>, anyhow::Error>> + Send>>;
/// Enum for different types of API handler functions.
#[non_exhaustive]
pub enum ApiHandler {
Sync(ApiHandlerFn),
StreamingSync(StreamingApiHandlerFn),
Async(ApiAsyncHandlerFn),
StreamingAsync(StreamingApiAsyncHandlerFn),
#[cfg(feature = "server")]
AsyncHttp(ApiAsyncHttpHandlerFn),
}
@ -220,6 +227,7 @@ impl PartialEq for ApiHandler {
(ApiHandler::StreamingAsync(l), ApiHandler::StreamingAsync(r)) => {
core::mem::transmute::<_, usize>(l) == core::mem::transmute::<_, usize>(r)
}
#[cfg(feature = "server")]
(ApiHandler::AsyncHttp(l), ApiHandler::AsyncHttp(r)) => {
core::mem::transmute::<_, usize>(l) == core::mem::transmute::<_, usize>(r)
}
@ -431,6 +439,7 @@ impl Router {
/// - `components`: Path, split into individual components.
/// - `method`: The HTTP method.
/// - `uri_param`: Mutable hash map to store parameter from `MatchAll` router.
#[cfg(feature = "server")]
pub fn find_method(
&self,
components: &[&str],