Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

CA-75708: Remove the 16MB limit on DB RPC responses.

Check the content length of responses to requests made by the database
RPC client; if the content length is greater than the maximum string
length then read the response into a Bigbuffer instead.

Signed-off-by: John Else <john.else@citrix.com>
  • Loading branch information...
commit 8e7d43dcdf5af9cddcf561075bef20f77a5fa7f3 1 parent 437bd17
@johnelse authored
View
6 ocaml/database/db_interface.ml
@@ -12,6 +12,10 @@
* GNU Lesser General Public License for more details.
*)
+type response =
+ | String of string
+ | Bigbuf of Bigbuffer.t
+
(** A generic RPC interface *)
module type RPC = sig
@@ -19,7 +23,7 @@ module type RPC = sig
val initialise : unit -> unit
(** [rpc request] transmits [request] and receives a response *)
- val rpc : string -> string
+ val rpc : string -> response
end
(** dictionary of regular fields x dictionary of associated set_ref values *)
View
5 ocaml/database/db_rpc_client_v1.ml
@@ -49,7 +49,10 @@ module Make = functor(RPC: Db_interface.RPC) -> struct
let do_remote_call marshall_args unmarshall_resp fn_name args =
let xml = marshall_args args in
let xml = XMLRPC.To.array [XMLRPC.To.string fn_name; XMLRPC.To.string "" (* unused *); xml] in
- let resp = Xml.parse_string (RPC.rpc (Xml.to_string xml)) in
+ let resp = match RPC.rpc (Xml.to_string xml) with
+ | Db_interface.String s -> Xml.parse_string s
+ | Db_interface.Bigbuf b -> Xml.parse_bigbuffer b
+ in
match XMLRPC.From.array (fun x->x) resp with
[status_xml; resp_xml] ->
let status = XMLRPC.From.string status_xml in
View
5 ocaml/database/db_rpc_client_v2.ml
@@ -19,7 +19,10 @@ open Db_exn
module Make = functor(RPC: Db_interface.RPC) -> struct
let initialise = RPC.initialise
- let rpc x = Jsonrpc.of_string (RPC.rpc (Jsonrpc.to_string x))
+ let rpc x =
+ match RPC.rpc (Jsonrpc.to_string x) with
+ | Db_interface.String s -> Jsonrpc.of_string s
+ | Db_interface.Bigbuf b -> raise (Failure "Response too large - cannot convert bigbuffer to json!")
let process (x: Request.t) =
let y : Response.t = Response.t_of_rpc (rpc (Request.rpc_of_t x)) in
View
16 ocaml/database/master_connection.ml
@@ -112,10 +112,10 @@ let restart_on_connection_timeout = ref true
exception Content_length_required
-let do_db_xml_rpc_persistent_with_reopen ~host ~path (req: string) : string =
+let do_db_xml_rpc_persistent_with_reopen ~host ~path (req: string) : Db_interface.response =
let time_call_started = Unix.gettimeofday() in
let write_ok = ref false in
- let result = ref "" in
+ let result = ref (Db_interface.String "") in
let surpress_no_timeout_logs = ref false in
let backoff_delay = ref 2.0 in (* initial delay = 2s *)
let update_backoff_delay () =
@@ -145,8 +145,16 @@ let do_db_xml_rpc_persistent_with_reopen ~host ~path (req: string) : string =
and we'll be out of sync with the next request. *)
let res = match response.Http.Response.content_length with
| None -> raise Content_length_required
- | Some l ->
- with_timestamp (fun ()-> Unixext.really_read_string fd (Int64.to_int l)) in
+ | Some l -> begin
+ if (Int64.to_int l) <= Sys.max_string_length then
+ with_timestamp (fun () -> Db_interface.String (Unixext.really_read_string fd (Int64.to_int l)))
+ else
+ with_timestamp (fun () ->
+ let buf = Bigbuffer.make () in
+ Unixext.really_read_bigbuffer fd buf l;
+ Db_interface.Bigbuf buf)
+ end
+ in
write_ok := true;
result := res (* yippeee! return and exit from while loop *)
) fd
Please sign in to comment.
Something went wrong with that request. Please try again.