+3
-1
CLAUDE.md
···If in doubt, add more whitespace lines than needed - you can always clean this up later with `dune build @fmt` to get ocamlformat to sort out the whitespace properly.+When adding ocamldoc comments, use the information in the protocol specifications available to also add relevant explanations to the OCamldoc. Do not refer to the specification in the third-person, but directly include enough information in the OCamldoc for a reader to understand the protocol flow directly.IMPORTANT: For all modules, use a nested module structure with a canonical `type t` inside each submodule. This approach ensures consistent type naming and logical grouping of related functionality.···1) we will generate OCaml interface files only, and no module implementations. The purpose here is to write and document the necessary type signatures. Once we generate these, we can check that they work with "dune build @check". Once that succeeds, we will build HTML documentation with "dune build @doc" in order to ensure the interfaces are reasonable.
+4
bin/dune
+79
bin/fcgi_server.ml
···+let method_ = Fastcgi.Record.KV.find_opt "REQUEST_METHOD" params |> Option.value ~default:"GET" in+let script_name = Fastcgi.Record.KV.find_opt "SCRIPT_NAME" params |> Option.value ~default:"" in
+7
config/Caddyfile
+3
-1
dune-project
···
+2
fastcgi.opam
+3
-4
lib/dune
+50
lib/fastcgi.ml
···
+28
lib/fastcgi.mli
···
+305
lib/fastcgi_record.ml
···+else String.sub actual_content 0 max_content_len ^ "..." ^ Printf.sprintf " (%d more bytes)" (len - max_content_len)+"@[<2>{ version = %d;@ record_type = %a;@ request_id = %d;@ content = %S;@ offset = %d;@ length = %d }@]"+Printf.eprintf "[DEBUG] Fastcgi_record.read: Header parsed - version=%d, type=%d, id=%d, content_len=%d, padding=%d\n%!"+Printf.eprintf "[DEBUG] Fastcgi_record.read: Successfully read %d bytes\n%!" (String.length c);+Printf.eprintf "[DEBUG] Fastcgi_record.read: Skipping %d bytes of padding\n%!" padding_length;+let record = { version; record_type; request_id; content; offset = 0; length = String.length content } in
+131
lib/fastcgi_record.mli
···
+279
lib/fastcgi_request.ml
···+"@[<2>{ request_id = %d;@ role = %a;@ keep_conn = %b;@ params = %a;@ stdin = %d bytes;@ data = %s }@]"+Printf.eprintf "[DEBUG] read_stdin_from_flow: Got stream terminator, total stdin=%d bytes\n%!"+Printf.eprintf "[DEBUG] read_request_streams: Got STDIN data, %d bytes\n%!" (String.length stdin_data);+Printf.eprintf "[DEBUG] read_request_streams: Got STDIN data, %d bytes\n%!" (String.length stdin_data);+Printf.eprintf "[DEBUG] read_request_streams: Got DATA stream, %d bytes\n%!" (String.length data);+let record = Fastcgi_record.create ~record:record_type ~request_id ~content ~offset:pos ~length:chunk_len () in
+80
lib/fastcgi_request.mli
···+(** [write_end_request buf_write request_id app_status protocol_status] writes END_REQUEST record. *)+val write_end_request : Eio.Buf_write.t -> Fastcgi_record.request_id -> app_status -> protocol_status -> unit
+13
test/dune
···
+161
test/simple_test.ml
···
+123
test/test_cases/README.md
···+This directory contains binary test case files representing various FastCGI records as defined in the FastCGI specification. These files can be used to test a FastCGI parser implementation.+The first 8 bytes should always be the FastCGI header, followed by the record content and any padding.
test/test_cases/abort_request.bin
This is a binary file and will not be displayed.
test/test_cases/begin_request_filter.bin
This is a binary file and will not be displayed.
test/test_cases/begin_request_no_keep.bin
This is a binary file and will not be displayed.
test/test_cases/begin_request_responder.bin
This is a binary file and will not be displayed.
test/test_cases/data_empty.bin
This is a binary file and will not be displayed.
test/test_cases/data_filter.bin
This is a binary file and will not be displayed.
test/test_cases/end_request_error.bin
This is a binary file and will not be displayed.
test/test_cases/end_request_success.bin
This is a binary file and will not be displayed.
+349
test/test_cases/generate_test_cases.py
···
test/test_cases/get_values.bin
This is a binary file and will not be displayed.
test/test_cases/get_values_result.bin
This is a binary file and will not be displayed.
test/test_cases/large_record.bin
This is a binary file and will not be displayed.
test/test_cases/multiplexed_requests.bin
This is a binary file and will not be displayed.
test/test_cases/padded_record.bin
This is a binary file and will not be displayed.
test/test_cases/params_empty.bin
This is a binary file and will not be displayed.
test/test_cases/params_get.bin
This is a binary file and will not be displayed.
test/test_cases/params_post.bin
This is a binary file and will not be displayed.
test/test_cases/stderr_empty.bin
This is a binary file and will not be displayed.
test/test_cases/stderr_message.bin
This is a binary file and will not be displayed.
test/test_cases/stdin_empty.bin
This is a binary file and will not be displayed.
test/test_cases/stdin_form_data.bin
This is a binary file and will not be displayed.
test/test_cases/stdout_empty.bin
This is a binary file and will not be displayed.
test/test_cases/stdout_response.bin
This is a binary file and will not be displayed.
+24
test/test_cases/test_case_sizes.txt
···
test/test_cases/unknown_type.bin
This is a binary file and will not be displayed.
+130
test/test_cases/validate_test_cases.py
···+version, record_type, request_id, content_length, padding_length, reserved = struct.unpack('>BBHHBB', data[:8])
+438
test/test_cases/validation_results.txt
···
+219
test/validate_all_test_cases.ml
···+Printf.printf "\nā All %d test case files validated successfully!\n%!" (List.length test_cases);