]> git.proxmox.com Git - proxmox-backup.git/blame - src/server/formatter.rs
sync: verify size and checksum of pulled archives
[proxmox-backup.git] / src / server / formatter.rs
CommitLineData
f7d4e4b5 1use anyhow::{Error};
1571873d
DM
2use serde_json::{json, Value};
3
c578fcd9
DM
4use hyper::{Body, Response, StatusCode};
5use hyper::header;
6
a2479cfa
WB
7use proxmox::api::{HttpError, RpcEnvironment};
8
44c00c0d
DM
9/// Extension to set error message for server side logging
10pub struct ErrorMessageExtension(pub String);
11
1571873d
DM
12pub 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 19static JSON_CONTENT_TYPE: &str = "application/json;charset=UTF-8";
6049b71f 20
78b51915
DM
21pub 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 28pub 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
42fn 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
54fn 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 65pub 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
86pub static JSON_FORMATTER: OutputFormatter = OutputFormatter {
d55037e4 87 format_data: json_format_data,
78b51915 88 format_error: json_error_response,
1571873d
DM
89};
90
dd5495d6 91fn 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 103fn 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
123pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter {
d55037e4 124 format_data: extjs_format_data,
6049b71f 125 format_error: extjs_format_error,
1571873d 126};