Skip to content

Commit 27f3847

Browse files
author
Konstantina Chremmou
committed
CA-261166: The jsonrpc version of the response should match the one of the request. The structure of the error output for v2 should comply with the specs.
Signed-off-by: Konstantina Chremmou <[email protected]>
1 parent 010ec52 commit 27f3847

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

ocaml/xapi/api_server.ml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,14 @@ let is_himn_req req =
123123
| None -> false)
124124
| None -> false
125125

126+
127+
let json_of_error_object ?(data=None) code message =
128+
let data_json = match data with Some d -> ["data", d] | None -> [] in
129+
Rpc.Dict ([ "code", Rpc.Int code; "message", Rpc.String message; ] @ data_json)
130+
131+
126132
(* This bit is called directly by the fake_rpc callback *)
127-
let callback1 is_json req fd body call =
133+
let callback1 ?(json_rpc_version=Jsonrpc.V1) is_json req fd body call =
128134
(* We now have the body string, the xml and the call name, and can also tell *)
129135
(* if we're a master or slave and whether the call came in on the unix domain socket or the tcp socket *)
130136
(* If we're a slave, and the call is from the unix domain socket or from the HIMN, and the call *isn't* *)
@@ -144,8 +150,14 @@ let callback1 is_json req fd body call =
144150
else
145151
let response = Server.dispatch_call req fd call in
146152
let translated =
147-
if is_json && response.Rpc.success && call.Rpc.name <> "system.listMethods" then
148-
{response with Rpc.contents = Rpc.rpc_of_string (Jsonrpc.to_string response.Rpc.contents)}
153+
if is_json && json_rpc_version = Jsonrpc.V2 && not response.Rpc.success && call.Rpc.name <> "system.listMethods" then
154+
begin
155+
let message, data = match response.Rpc.contents with
156+
| Rpc.Enum ((Rpc.String s)::tl) -> s, (Rpc.Enum tl)
157+
| _ -> "", response.Rpc.contents
158+
in
159+
{response with Rpc.contents = json_of_error_object ~data:(Some data) 0L message}
160+
end
149161
else
150162
response in
151163
translated
@@ -196,11 +208,11 @@ let jsoncallback req bio _ =
196208
let fd = Buf_io.fd_of bio in (* fd only used for writing *)
197209
let body = Http_svr.read_body ~limit:Db_globs.http_limit_max_rpc_size req bio in
198210
try
199-
let rpc = Jsonrpc.call_of_string body in
200-
let response = Jsonrpc.a_of_response
211+
let json_rpc_version, id, rpc = Jsonrpc.version_id_and_call_of_string body in
212+
let response = Jsonrpc.a_of_response ~id ~version:json_rpc_version
201213
~empty:Bigbuffer.make
202214
~append:(fun buf s -> Bigbuffer.append_substring buf s 0 (String.length s))
203-
(callback1 false req fd (Some body) rpc) in
215+
(callback1 ~json_rpc_version true req fd (Some body) rpc) in
204216
Http_svr.response_fct req ~hdrs:[ Http.Hdr.content_type, "application/json";
205217
"Access-Control-Allow-Origin", "*";
206218
"Access-Control-Allow-Headers", "X-Requested-With"] fd (Bigbuffer.length response)

0 commit comments

Comments
 (0)