mirror of
https://git.proxmox.com/git/proxmox
synced 2025-07-09 19:57:39 +00:00
api-test: add a json-body multi-parameter test method
Signed-off-by: Wolfgang Bumiller <w.bumiller@errno.eu>
This commit is contained in:
parent
82f8df963e
commit
8b77b3d08c
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -15,6 +15,7 @@ dependencies = [
|
|||||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"endian_trait 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"endian_trait 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.13.0-a.0 (git+https://github.com/hyperium/hyper)",
|
"hyper 0.13.0-a.0 (git+https://github.com/hyperium/hyper)",
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -11,6 +11,7 @@ authors = [
|
|||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
endian_trait = { version = "0.6", features = [ "arrays" ] }
|
endian_trait = { version = "0.6", features = [ "arrays" ] }
|
||||||
failure = "0.1"
|
failure = "0.1"
|
||||||
|
futures-preview = "0.3.0-alpha"
|
||||||
http = "0.1"
|
http = "0.1"
|
||||||
hyper = { version = "0.13.0-a.0", git = "https://github.com/hyperium/hyper" }
|
hyper = { version = "0.13.0-a.0", git = "https://github.com/hyperium/hyper" }
|
||||||
lazy_static = "1.3"
|
lazy_static = "1.3"
|
||||||
|
@ -45,7 +45,7 @@ router! {
|
|||||||
GET: hello,
|
GET: hello,
|
||||||
/www/{path}*: { GET: get_www },
|
/www/{path}*: { GET: get_www },
|
||||||
/api/1: {
|
/api/1: {
|
||||||
// fill with more stuff
|
/greet: { GET: greet_person_with },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -103,19 +103,39 @@ async fn get_www(path: String) -> Result<Response<Body>, Error> {
|
|||||||
Ok(response.body(Body::from(data))?)
|
Ok(response.body(Body::from(data))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[api({
|
||||||
|
description: "Create a greeting message with various parameters...",
|
||||||
|
parameters: {
|
||||||
|
person: "The person to greet",
|
||||||
|
message: "The message to give",
|
||||||
|
ps: "An optional PS message",
|
||||||
|
},
|
||||||
|
})]
|
||||||
|
async fn greet_person_with(
|
||||||
|
person: String,
|
||||||
|
message: String,
|
||||||
|
ps: Option<String>,
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
Ok(match ps {
|
||||||
|
Some(ps) => format!("{}, {}.\n{}", person, message, ps),
|
||||||
|
None => format!("{}, {}.", person, message),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Hyper glue
|
// Hyper glue
|
||||||
//
|
//
|
||||||
|
|
||||||
async fn route_request(request: Request<Body>) -> Result<http::Response<Body>, Error> {
|
async fn route_request(request: Request<Body>) -> Result<http::Response<Body>, Error> {
|
||||||
let path = request.uri().path();
|
let (parts, body) = request.into_parts();
|
||||||
|
let path = parts.uri.path();
|
||||||
|
|
||||||
let (target, params) = ROUTER
|
let (target, mut params) = ROUTER
|
||||||
.lookup(path)
|
.lookup(path)
|
||||||
.ok_or_else(|| format_err!("missing path: {}", path))?;
|
.ok_or_else(|| format_err!("missing path: {}", path))?;
|
||||||
|
|
||||||
use hyper::Method;
|
use hyper::Method;
|
||||||
let method = match *request.method() {
|
let method = match parts.method {
|
||||||
Method::GET => target.get.as_ref(),
|
Method::GET => target.get.as_ref(),
|
||||||
Method::PUT => target.put.as_ref(),
|
Method::PUT => target.put.as_ref(),
|
||||||
Method::POST => target.post.as_ref(),
|
Method::POST => target.post.as_ref(),
|
||||||
@ -123,9 +143,33 @@ async fn route_request(request: Request<Body>) -> Result<http::Response<Body>, E
|
|||||||
_ => bail!("unexpected method type"),
|
_ => bail!("unexpected method type"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(ty) = parts.headers.get(http::header::CONTENT_TYPE) {
|
||||||
|
if ty.to_str()? == "application/json" {
|
||||||
|
use futures::stream::TryStreamExt;
|
||||||
|
let json = serde_json::from_str(std::str::from_utf8(
|
||||||
|
body
|
||||||
|
.try_concat()
|
||||||
|
.await?
|
||||||
|
.as_ref()
|
||||||
|
)?)?;
|
||||||
|
match json {
|
||||||
|
Value::Object(map) => for (k, v) in map {
|
||||||
|
let existed = params
|
||||||
|
.get_or_insert_with(serde_json::Map::new)
|
||||||
|
.insert(k, v)
|
||||||
|
.is_some();
|
||||||
|
if existed {
|
||||||
|
bail!("tried to override path-based parameter!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => bail!("expected a json object"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
method
|
method
|
||||||
.ok_or_else(|| format_err!("no GET method for: {}", path))?
|
.ok_or_else(|| format_err!("no GET method for: {}", path))?
|
||||||
.call(params.unwrap_or(Value::Null))
|
.call(params.map(Value::Object).unwrap_or(Value::Null))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user