]> git.proxmox.com Git - proxmox-backup.git/blame - src/server/formatter.rs
src/server/rest.rs: improve logs for unauthorized request
[proxmox-backup.git] / src / server / formatter.rs
CommitLineData
1571873d
DM
1use failure::*;
2use serde_json::{json, Value};
3
8225aa2f 4use crate::api_schema::router::{HttpError, RpcEnvironment};
6049b71f 5
c578fcd9
DM
6use hyper::{Body, Response, StatusCode};
7use hyper::header;
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
6049b71f
DM
14 pub format_result: fn(data: Value, rpcenv: &RpcEnvironment) -> Response<Body>,
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
DM
20
21
22fn json_response(result: Value) -> Response<Body> {
23
24 let json_str = result.to_string();
25
26 let raw = json_str.into_bytes();
1571873d 27
6049b71f
DM
28 let mut response = Response::new(raw.into());
29 response.headers_mut().insert(
30 header::CONTENT_TYPE,
0f253593 31 header::HeaderValue::from_static(JSON_CONTENT_TYPE));
1571873d 32
6049b71f
DM
33 response
34}
c578fcd9 35
6049b71f 36fn json_format_result(data: Value, rpcenv: &RpcEnvironment) -> Response<Body> {
c578fcd9 37
6049b71f
DM
38 let mut result = json!({
39 "data": data
40 });
c578fcd9 41
6049b71f
DM
42 if let Some(total) = rpcenv.get_result_attrib("total").and_then(|v| v.as_u64()) {
43 result["total"] = Value::from(total);
44 }
c578fcd9 45
6049b71f
DM
46 if let Some(changes) = rpcenv.get_result_attrib("changes") {
47 result["changes"] = changes.clone();
c578fcd9 48 }
6049b71f
DM
49
50 json_response(result)
51}
52
53fn json_format_error(err: Error) -> Response<Body> {
54
8225aa2f
DM
55 let mut response = if let Some(apierr) = err.downcast_ref::<HttpError>() {
56 let mut resp = Response::new(Body::from(apierr.message.clone()));
57 *resp.status_mut() = apierr.code;
58 resp
59 } else {
60 let mut resp = Response::new(Body::from(err.to_string()));
61 *resp.status_mut() = StatusCode::BAD_REQUEST;
62 resp
63 };
64
6049b71f
DM
65 response.headers_mut().insert(
66 header::CONTENT_TYPE,
0f253593 67 header::HeaderValue::from_static(JSON_CONTENT_TYPE));
6049b71f 68
44c00c0d
DM
69 response.extensions_mut().insert(ErrorMessageExtension(err.to_string()));
70
6049b71f 71 response
1571873d
DM
72}
73
74pub static JSON_FORMATTER: OutputFormatter = OutputFormatter {
75 format_result: json_format_result,
6049b71f 76 format_error: json_format_error,
1571873d
DM
77};
78
6049b71f 79fn extjs_format_result(data: Value, rpcenv: &RpcEnvironment) -> Response<Body> {
1571873d 80
6049b71f
DM
81 let mut result = json!({
82 "data": data,
83 "success": true
84 });
1571873d 85
6049b71f
DM
86 if let Some(total) = rpcenv.get_result_attrib("total").and_then(|v| v.as_u64()) {
87 result["total"] = Value::from(total);
88 }
c578fcd9 89
6049b71f
DM
90 if let Some(changes) = rpcenv.get_result_attrib("changes") {
91 result["changes"] = changes.clone();
92 }
c578fcd9 93
c578fcd9 94
6049b71f
DM
95 json_response(result)
96}
1571873d 97
6049b71f 98fn extjs_format_error(err: Error) -> Response<Body> {
1571873d 99
6049b71f 100 let mut errors = vec![];
5bb33981
DM
101
102 let message = err.to_string();
103 errors.push(&message);
1571873d 104
6049b71f 105 let result = json!({
5bb33981 106 "message": message,
6049b71f
DM
107 "errors": errors,
108 "success": false
109 });
1571873d 110
44c00c0d
DM
111 let mut response = json_response(result);
112
113 response.extensions_mut().insert(ErrorMessageExtension(message));
114
115 response
1571873d
DM
116}
117
118pub static EXTJS_FORMATTER: OutputFormatter = OutputFormatter {
119 format_result: extjs_format_result,
6049b71f 120 format_error: extjs_format_error,
1571873d 121};