···
+
let hex_dump ?(max_bytes=256) content =
+
let len = String.length content in
+
let display_len = min len max_bytes in
+
let bytes_per_line = 16 in
+
let lines_to_show = (display_len - 1) / bytes_per_line + 1 in
+
for i = 0 to lines_to_show - 1 do
+
let start = i * bytes_per_line in
+
let end_ = min (start + bytes_per_line) display_len in
+
Printf.printf " %04x: " start;
+
for j = start to end_ - 1 do
+
Printf.printf "%02x " (Char.code content.[j]);
+
if j = start + 7 then Printf.printf " "
+
(* Pad remaining space *)
+
for _ = end_ to start + bytes_per_line - 1 do
+
if end_ <= start + 7 then Printf.printf " "
+
(* Print ASCII representation *)
+
for j = start to end_ - 1 do
+
if c >= ' ' && c <= '~' then
+
if len > max_bytes then
+
Printf.printf " ... (%d more bytes truncated)\n%!" (len - max_bytes)
("abort_request.bin", Abort_request, 1);
("begin_request_authorizer.bin", Begin_request, 2);
···
let test_binary_file ~fs filename expected_type expected_request_id =
+
Printf.printf "Testing %s...\n" filename;
+
let (raw_content, parsed) =
Eio.Path.with_open_in (fs, "test_cases/" ^ filename) @@ fun flow ->
+
let buf = Buffer.create 1024 in
+
Eio.Flow.copy flow (Eio.Flow.buffer_sink buf);
+
let raw_content = Buffer.contents buf in
+
let buf_read = Eio.Buf_read.of_string raw_content in
+
let parsed = Record.read buf_read in
+
Printf.printf "\nRaw file contents (%d bytes):\n" (String.length raw_content);
+
Printf.printf "\nParsed record:\n";
+
Format.printf "%a\n" (fun ppf -> Record.pp ppf) parsed;
+
(* If this is a Params record, also show the decoded key-value pairs *)
+
if parsed.record_type = Params && String.length parsed.content > 0 then (
+
let params = Record.KV.decode parsed.content in
+
Printf.printf "\nDecoded parameters:\n";
+
Format.printf "%a\n" Record.KV.pp params
assert (parsed.version = 1);
assert (parsed.record_type = expected_type);
assert (parsed.request_id = expected_request_id);
+
Printf.printf "✓ %s passed\n\n%!" filename
let test_params_decoding ~fs =
+
Printf.printf "Testing params record content decoding...\n";
Eio.Path.with_open_in (fs, "test_cases/params_get.bin") @@ fun flow ->
···
+
Printf.printf "\nParsed params record:\n";
+
Format.printf "%a\n" (fun ppf -> Record.pp ppf) parsed;
(* Decode the params content *)
let params = Record.KV.decode parsed.content in
+
Printf.printf "\nDecoded parameters:\n";
+
Format.printf "%a\n" Record.KV.pp params;
(* Check some expected environment variables *)
assert (Record.KV.find "REQUEST_METHOD" params = "GET");
assert (Record.KV.find "SERVER_NAME" params = "localhost");
assert (Record.KV.find "SERVER_PORT" params = "80");
+
Printf.printf "✓ params decoding passed\n\n%!"
let test_large_record ~fs =
+
Printf.printf "Testing large record...\n";
Eio.Path.with_open_in (fs, "test_cases/large_record.bin") @@ fun flow ->
···
+
Printf.printf "\nParsed large record:\n";
+
Format.printf "%a\n" (fun ppf -> Record.pp ppf) parsed;
assert (parsed.version = 1);
assert (parsed.record_type = Stdout);
assert (parsed.request_id = 1);
assert (String.length parsed.content = 65000);
+
Printf.printf "✓ large record test passed\n\n%!"
let test_padded_record ~fs =
+
Printf.printf "Testing padded record...\n";
Eio.Path.with_open_in (fs, "test_cases/padded_record.bin") @@ fun flow ->
let buf_read = Eio.Buf_read.of_flow flow ~max_size:1000000 in
+
Printf.printf "\nParsed padded record:\n";
+
Format.printf "%a\n" (fun ppf -> Record.pp ppf) parsed;
assert (parsed.version = 1);
assert (parsed.record_type = Stdout);
assert (parsed.request_id = 1);
assert (parsed.content = "Hello");
+
Printf.printf "✓ padded record test passed\n\n%!"
let test_multiplexed_records ~fs =
+
Printf.printf "Testing multiplexed records...\n";
Eio.Path.with_open_in (fs, "test_cases/multiplexed_requests.bin") @@ fun flow ->
···
let records = List.rev records in
+
Printf.printf "\nParsed %d multiplexed records:\n" (List.length records);
+
List.iteri (fun i record ->
+
Printf.printf "\nRecord %d:\n" (i + 1);
+
Format.printf "%a\n" (fun ppf -> Record.pp ppf) record
(* Should have multiple records with different request IDs *)
assert (List.length records > 5);
···
assert (List.mem 1 request_ids);
assert (List.mem 2 request_ids);
+
Printf.printf "✓ multiplexed records test passed\n\n%!"
Printf.printf "Validating all FastCGI test case files...\n\n%!";