Skip to content

Commit 42fb801

Browse files
authored
Merge pull request #5832 from last-genius/private/asultanov/query-fix
CA-395626: Fix (server status report generation report)
2 parents fbcc033 + 0f45257 commit 42fb801

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

ocaml/libs/http-lib/http_svr.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,13 @@ let request_of_bio_exn ~proxy_seen ~read_timeout ~total_timeout ~max_length bio
359359
proxy |> Option.fold ~none:[] ~some:(fun p -> [("STUNNEL_PROXY", p)])
360360
in
361361
let open Http.Request in
362-
(* Below transformation only keeps one value per key, whereas
363-
a fully compliant implementation following Uri's interface
364-
would operate on list of values for each key instead *)
365362
let kvlist_flatten ls =
366-
List.map (function k, v :: _ -> (k, v) | k, [] -> (k, "")) ls
363+
(* Uri.query splits the value string into several if they are separated
364+
with commas. Like this: "?k=v1,v2,v3" -> [("k", ["v1";"v2";"v3"])]
365+
This function concatenates these back. It will not concatenate values
366+
entered for duplicate keys, as these will be separate tuples:
367+
"?k=v1,v2,v3&k=v4" -> [("k", ["v1"; "v2"; "v3"]); ("k", ["v4"])] *)
368+
List.map (fun (k, vs) -> (k, Astring.String.concat ~sep:"," vs)) ls
367369
in
368370
let request =
369371
Astring.String.cuts ~sep:"\n" headers

ocaml/libs/http-lib/test_client.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,25 @@ let one ~use_fastpath ~use_framing keep_alive s =
4343
failwith "Need a content length"
4444
)
4545

46+
let query ~use_fastpath ~use_framing keep_alive s =
47+
let query_string = "v1,v2,v3,<>`" in
48+
Http_client.rpc ~use_fastpath s
49+
(Http.Request.make ~frame:use_framing ~version:"1.1" ~keep_alive ~user_agent
50+
~query:[("k1", query_string)]
51+
Http.Get "/query"
52+
)
53+
(fun response s ->
54+
match response.Http.Response.content_length with
55+
| Some l ->
56+
let s = Unixext.really_read_string s (Int64.to_int l) in
57+
if s <> query_string then
58+
failwith "Incorrectly parsed query string"
59+
else
60+
()
61+
| None ->
62+
failwith "Need a content length"
63+
)
64+
4665
module Normal_population = struct
4766
(** Stats on a normally-distributed population *)
4867
type t = {sigma_x: float; sigma_xx: float; n: int}
@@ -122,6 +141,16 @@ let _ =
122141
)
123142
in
124143
Printf.printf "%s RPCs/sec\n%!" (Normal_population.to_string nonpersistent) ;
144+
Printf.printf "1 thread non-persistent connections (query): " ;
145+
let nonpersistent_query =
146+
sample 1 (fun () ->
147+
per_nsec 1. (fun () ->
148+
transport !ip !port (query ~use_fastpath ~use_framing false)
149+
)
150+
)
151+
in
152+
Printf.printf "%s RPCs/sec\n%!"
153+
(Normal_population.to_string nonpersistent_query) ;
125154
Printf.printf "10 threads non-persistent connections: " ;
126155
let thread_nonpersistent =
127156
sample 1 (fun () ->

ocaml/libs/http-lib/test_server.ml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ let _ =
6464
Unixext.really_write_string s r
6565
)
6666
) ;
67+
Server.add_handler server Http.Get "/query"
68+
(FdIO
69+
(fun request s _ ->
70+
match request.Http.Request.query with
71+
| (_, v) :: _ ->
72+
Unixext.really_write_string s
73+
(Http.Response.to_wire_string
74+
(Http.Response.make ~body:v "200" "OK")
75+
)
76+
| _ ->
77+
Unixext.really_write_string s
78+
(Http.Response.to_wire_string
79+
(Http.Response.make "404" "Query string missing")
80+
)
81+
)
82+
) ;
6783
let ip = "0.0.0.0" in
6884
let inet_addr = Unix.inet_addr_of_string ip in
6985
let addr = Unix.ADDR_INET (inet_addr, !port) in

0 commit comments

Comments
 (0)