From 0ffbccce5e98d1919b410811d8c253fafcbd23a4 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 27 Feb 2019 12:12:00 +0100 Subject: [PATCH] rc/server/rest.rs: allow to pass parameters as application/json --- src/client/http_client.rs | 22 ++++++++++++++++++++++ src/server/rest.rs | 26 +++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/client/http_client.rs b/src/client/http_client.rs index d4c30f85..2ca7af91 100644 --- a/src/client/http_client.rs +++ b/src/client/http_client.rs @@ -136,11 +136,33 @@ impl HttpClient { .header("User-Agent", "proxmox-backup-client/1.0") .header("Cookie", format!("PBSAuthCookie={}", enc_ticket)) .header("CSRFPreventionToken", token) + .header(hyper::header::CONTENT_TYPE, "application/x-www-form-urlencoded") .body(Body::empty())?; Self::run_request(request) } + pub fn post_json(&mut self, path: &str, data: Value) -> Result { + + let path = path.trim_matches('/'); + let url: Uri = format!("https://{}:8007/{}", self.server, path).parse()?; + + let (ticket, token) = self.login()?; + + let enc_ticket = percent_encode(ticket.as_bytes(), DEFAULT_ENCODE_SET).to_string(); + + let request = Request::builder() + .method("POST") + .uri(url) + .header("User-Agent", "proxmox-backup-client/1.0") + .header("Cookie", format!("PBSAuthCookie={}", enc_ticket)) + .header("CSRFPreventionToken", token) + .header(hyper::header::CONTENT_TYPE, "application/json") + .body(Body::from(data.to_string()))?; + + Self::run_request(request) + } + fn login(&mut self) -> Result<(String, String), Error> { if let Some(ref ticket) = self.ticket { diff --git a/src/server/rest.rs b/src/server/rest.rs index e92406c5..b5ad9cd0 100644 --- a/src/server/rest.rs +++ b/src/server/rest.rs @@ -117,6 +117,18 @@ fn get_request_parameters_async( uri_param: HashMap, ) -> Box + Send> { + let mut is_json = false; + + if let Some(value) = parts.headers.get(header::CONTENT_TYPE) { + if value == "application/x-www-form-urlencoded" { + is_json = false; + } else if value == "application/json" { + is_json = true; + } else { + return Box::new(future::err(http_err!(BAD_REQUEST, format!("unsupported content type")))); + } + } + let resp = req_body .map_err(|err| http_err!(BAD_REQUEST, format!("Promlems reading request body: {}", err))) .fold(Vec::new(), |mut acc, chunk| { @@ -130,6 +142,18 @@ fn get_request_parameters_async( let utf8 = std::str::from_utf8(&body)?; + let obj_schema = &info.parameters; + + if is_json { + let mut params: Value = serde_json::from_str(utf8)?; + for (k, v) in uri_param { + if let Some((_optional, prop_schema)) = obj_schema.properties.get::(&k) { + params[&k] = parse_simple_value(&v, prop_schema)?; + } + } + return Ok(params); + } + let mut param_list: Vec<(String, String)> = vec![]; if utf8.len() > 0 { @@ -150,7 +174,7 @@ fn get_request_parameters_async( param_list.push((k.clone(), v.clone())); } - let params = parse_parameter_strings(¶m_list, &info.parameters, true)?; + let params = parse_parameter_strings(¶m_list, obj_schema, true)?; Ok(params) });