mirror of
https://git.proxmox.com/git/proxmox
synced 2025-05-28 05:05:31 +00:00
api-test: comments/cleanup
Signed-off-by: Wolfgang Bumiller <w.bumiller@errno.eu>
This commit is contained in:
parent
bb2639bf40
commit
6705d13424
@ -13,76 +13,9 @@ use tokio::io::AsyncReadExt;
|
||||
|
||||
use proxmox::api::{api, router};
|
||||
|
||||
async fn run_request(request: Request<Body>) -> Result<http::Response<Body>, hyper::Error> {
|
||||
match route_request(request).await {
|
||||
Ok(r) => Ok(r),
|
||||
Err(err) => Ok(Response::builder()
|
||||
.status(400)
|
||||
.body(Body::from(format!("ERROR: {}", err)))
|
||||
.expect("building an error response...")),
|
||||
}
|
||||
}
|
||||
|
||||
async fn route_request(request: Request<Body>) -> Result<http::Response<Body>, Error> {
|
||||
let path = request.uri().path();
|
||||
|
||||
let (target, params) = ROUTER
|
||||
.lookup(path)
|
||||
.ok_or_else(|| format_err!("missing path: {}", path))?;
|
||||
|
||||
target
|
||||
.get
|
||||
.as_ref()
|
||||
.ok_or_else(|| format_err!("no GET method for: {}", path))?
|
||||
.call(params.unwrap_or(Value::Null))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn main_do(www_dir: String) {
|
||||
// Construct our SocketAddr to listen on...
|
||||
let addr = ([0, 0, 0, 0], 3000).into();
|
||||
|
||||
// And a MakeService to handle each connection...
|
||||
let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(run_request)) });
|
||||
|
||||
// Then bind and serve...
|
||||
let server = Server::bind(&addr).serve(service);
|
||||
|
||||
println!("Serving {} under http://localhost:3000/www/", www_dir);
|
||||
|
||||
if let Err(e) = server.await {
|
||||
eprintln!("server error: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// We expect a path, where to find our files we expose via the www/ dir:
|
||||
let mut args = std::env::args();
|
||||
|
||||
// real code should have better error handling
|
||||
let _program_name = args.next();
|
||||
let www_dir = args.next().expect("expected a www/ subdirectory");
|
||||
set_www_dir(www_dir.to_string());
|
||||
|
||||
// show our api info:
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&ROUTER.api_dump()).unwrap()
|
||||
);
|
||||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(main_do(www_dir));
|
||||
}
|
||||
|
||||
#[api({
|
||||
description: "Hello API call",
|
||||
})]
|
||||
async fn hello() -> Result<Response<Body>, Error> {
|
||||
Ok(http::Response::builder()
|
||||
.status(200)
|
||||
.header("content-type", "text/html")
|
||||
.body(Body::from("Hello"))?)
|
||||
}
|
||||
//
|
||||
// Configuration:
|
||||
//
|
||||
|
||||
static mut WWW_DIR: Option<String> = None;
|
||||
|
||||
@ -103,6 +36,30 @@ pub fn set_www_dir(dir: String) {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// API methods
|
||||
//
|
||||
|
||||
router! {
|
||||
pub static ROUTER: Router<Body> = {
|
||||
GET: hello,
|
||||
/www/{path}*: { GET: get_www },
|
||||
/api/1: {
|
||||
// fill with more stuff
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[api({
|
||||
description: "Hello API call",
|
||||
})]
|
||||
async fn hello() -> Result<Response<Body>, Error> {
|
||||
Ok(http::Response::builder()
|
||||
.status(200)
|
||||
.header("content-type", "text/html")
|
||||
.body(Body::from("Hello"))?)
|
||||
}
|
||||
|
||||
#[api({
|
||||
description: "Get a file from the www/ subdirectory.",
|
||||
parameters: {
|
||||
@ -114,6 +71,7 @@ async fn get_www(path: String) -> Result<Response<Body>, Error> {
|
||||
bail!("illegal path");
|
||||
}
|
||||
|
||||
// FIXME: Add support for an ApiError type for 404s etc. to reduce error handling code size:
|
||||
let mut file = match tokio::fs::File::open(format!("{}/{}", www_dir(), path)).await {
|
||||
Ok(file) => file,
|
||||
Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
|
||||
@ -145,11 +103,77 @@ async fn get_www(path: String) -> Result<Response<Body>, Error> {
|
||||
Ok(response.body(Body::from(data))?)
|
||||
}
|
||||
|
||||
router! {
|
||||
pub static ROUTER: Router<Body> = {
|
||||
GET: hello,
|
||||
/www/{path}*: { GET: get_www },
|
||||
/api/1: {
|
||||
}
|
||||
//
|
||||
// Hyper glue
|
||||
//
|
||||
|
||||
async fn route_request(request: Request<Body>) -> Result<http::Response<Body>, Error> {
|
||||
let path = request.uri().path();
|
||||
|
||||
let (target, params) = ROUTER
|
||||
.lookup(path)
|
||||
.ok_or_else(|| format_err!("missing path: {}", path))?;
|
||||
|
||||
use hyper::Method;
|
||||
let method = match *request.method() {
|
||||
Method::GET => target.get.as_ref(),
|
||||
Method::PUT => target.put.as_ref(),
|
||||
Method::POST => target.post.as_ref(),
|
||||
Method::DELETE => target.delete.as_ref(),
|
||||
_ => bail!("unexpected method type"),
|
||||
};
|
||||
|
||||
method
|
||||
.ok_or_else(|| format_err!("no GET method for: {}", path))?
|
||||
.call(params.unwrap_or(Value::Null))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn service_func(request: Request<Body>) -> Result<http::Response<Body>, hyper::Error> {
|
||||
match route_request(request).await {
|
||||
Ok(r) => Ok(r),
|
||||
Err(err) => Ok(Response::builder()
|
||||
.status(400)
|
||||
.body(Body::from(format!("ERROR: {}", err)))
|
||||
.expect("building an error response...")),
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Main entry point
|
||||
//
|
||||
async fn main_do(www_dir: String) {
|
||||
// Construct our SocketAddr to listen on...
|
||||
let addr = ([0, 0, 0, 0], 3000).into();
|
||||
|
||||
// And a MakeService to handle each connection...
|
||||
let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(service_func)) });
|
||||
|
||||
// Then bind and serve...
|
||||
let server = Server::bind(&addr).serve(service);
|
||||
|
||||
println!("Serving {} under http://localhost:3000/www/", www_dir);
|
||||
|
||||
if let Err(e) = server.await {
|
||||
eprintln!("server error: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// We expect a path, where to find our files we expose via the www/ dir:
|
||||
let mut args = std::env::args();
|
||||
|
||||
// real code should have better error handling
|
||||
let _program_name = args.next();
|
||||
let www_dir = args.next().expect("expected a www/ subdirectory");
|
||||
set_www_dir(www_dir.to_string());
|
||||
|
||||
// show our api info:
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&ROUTER.api_dump()).unwrap()
|
||||
);
|
||||
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(main_do(www_dir));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user