]>
Commit | Line | Data |
---|---|---|
f7d4e4b5 | 1 | use anyhow::{Error}; |
1571873d DM |
2 | use serde_json::{json, Value}; |
3 | ||
c578fcd9 DM |
4 | use hyper::{Body, Response, StatusCode}; |
5 | use hyper::header; | |
6 | ||
a2479cfa WB |
7 | use proxmox::api::{HttpError, RpcEnvironment}; |
8 | ||
44c00c0d DM |
9 | /// Extension to set error message for server side logging |
10 | pub struct ErrorMessageExtension(pub String); | |
11 | ||
1571873d DM |
12 | pub struct OutputFormatter { |
13 | ||
dd5495d6 | 14 | pub format_data: fn(data: Value, rpcenv: &dyn RpcEnvironment) -> Response<Body>, |
6049b71f DM |
15 | |
16 | pub format_error: fn(err: Error) -> Response<Body>, | |
1571873d DM |
17 | } |
18 | ||
0f253593 | 19 | static JSON_CONTENT_TYPE: &str = "application/json;charset=UTF-8"; |
6049b71f | 20 | |
78b51915 DM |
21 | pub fn json_response(result: Result<Value, Error>) -> Response<Body> { |
22 | match result { | |
23 | Ok(data) => json_data_response(data), | |
24 | Err(err) => json_error_response(err), | |
25 | } | |
26 | } | |
6049b71f | 27 | |
78b51915 | 28 | pub fn json_data_response(data: Value) -> Response<Body> { |
6049b71f | 29 | |
78b51915 | 30 | let json_str = data.to_string(); |
6049b71f DM |
31 | |
32 | let raw = json_str.into_bytes(); | |
1571873d | 33 | |
6049b71f DM |
34 | let mut response = Response::new(raw.into()); |
35 | response.headers_mut().insert( | |
36 | header::CONTENT_TYPE, | |
0f253593 | 37 | header::HeaderValue::from_static(JSON_CONTENT_TYPE)); |
1571873d | 38 | |
6049b71f DM |
39 | response |
40 | } | |
c578fcd9 | 41 | |
6b508dd5 DM |
42 | fn add_result_attributes(result: &mut Value, rpcenv: &dyn RpcEnvironment) |
43 | { | |
e8d1da6a DM |
44 | let attributes = match rpcenv.result_attrib().as_object() { |
45 | Some(attr) => attr, | |
46 | None => return, | |
47 | }; | |
6b508dd5 | 48 | |
e8d1da6a DM |
49 | for (key, value) in attributes { |
50 | result[key] = value.clone(); | |
c578fcd9 | 51 | } |
6b508dd5 DM |
52 | } |
53 | ||
54 | fn json_format_data(data: Value, rpcenv: &dyn RpcEnvironment) -> Response<Body> { | |
55 | ||
56 | let mut result = json!({ | |
57 | "data": data | |
58 | }); | |
59 | ||
60 | add_result_attributes(&mut result, rpcenv); | |
6049b71f | 61 | |
78b51915 | 62 | json_data_response(result) |
6049b71f DM |
63 | } |
64 | ||
78b51915 | 65 | pub fn json_error_response(err: Error) -> Response<Body> { |
6049b71f | 66 | |
8225aa2f DM |
67 | let mut response = if let Some(apierr) = err.downcast_ref::<HttpError>() { |
68 | let mut resp = Response::new(Body::from(apierr.message.clone())); | |
69 | *resp.status_mut() = apierr.code; | |
70 | resp | |
71 | } else { | |
72 | let mut resp = Response::new(Body::from(err.to_string())); | |
73 | *resp.status_mut() = StatusCode::BAD_REQUEST; | |
74 | resp | |
75 | }; | |
76 | ||
6049b71f DM |
77 | response.headers_mut().insert( |
78 | header::CONTENT_TYPE, | |
0f253593 | 79 | header::HeaderValue::from_static(JSON_CONTENT_TYPE)); |
6049b71f | 80 | |
44c00c0d DM |
81 | response.extensions_mut().insert(ErrorMessageExtension(err.to_string())); |
82 | ||
6049b71f | 83 | response |
1571873d DM |
84 | } |
85 | ||
86 | pub static JSON_FORMATTER: OutputFormatter = OutputFormatter { | |
d55037e4 | 87 | format_data: json_format_data, |
78b51915 | 88 | format_error: json_error_response, |
1571873d DM |
89 | }; |
90 | ||
dd5495d6 | 91 | fn extjs_format_data(data: Value, rpcenv: &dyn RpcEnvironment) -> Response<Body> { |
1571873d | 92 | |
6049b71f DM |
93 | let mut result = json!({ |
94 | "data": data, | |
95 | "success": true | |
96 | }); | |
1571873d | 97 | |
6b508dd5 | 98 | add_result_attributes(&mut result, rpcenv); |
c578fcd9 | 99 | |
78b51915 | 100 | json_data_response(result) |
6049b71f | 101 | } |
1571873d | 102 | |
6049b71f | 103 | fn extjs_format_error(err: Error) -> Response<Body> { |
1571873d | 104 | |
6049b71f | 105 | let mut errors = vec![]; |
5bb33981 DM |
106 | |
107 | let message = err.to_string(); | |
108 | errors.push(&message); | |
1571873d | 109 | |
6049b71f | 110 | let result = json!({ |
5bb33981 | 111 | "message": message, |
6049b71f DM |
112 | "errors": errors, |
113 | "success": false | |
114 | }); | |
1571873d | 115 | |
78b51915 | 116 | let mut response = json_data_response(result); |
44c00c0d DM |
117 | |
118 | response.extensions_mut().insert(ErrorMessageExtension(message)); | |
119 | ||
120 | response | |
1571873d DM |
121 | } |
122 | ||
123 | pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter { | |
d55037e4 | 124 | format_data: extjs_format_data, |
6049b71f | 125 | format_error: extjs_format_error, |
1571873d | 126 | }; |