FastCGI implementation in OCaml
FastCGI Test Cases#
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.
Test Case Files#
Management Records (requestId = 0)#
get_values.bin- FCGI_GET_VALUES record requesting capability informationget_values_result.bin- FCGI_GET_VALUES_RESULT record with capability responsesunknown_type.bin- FCGI_UNKNOWN_TYPE record for unrecognized record types
Application Records (requestId > 0)#
BEGIN_REQUEST Records#
begin_request_responder.bin- Begin request for Responder role with KEEP_CONN flagbegin_request_no_keep.bin- Begin request for Responder role without KEEP_CONN flagbegin_request_authorizer.bin- Begin request for Authorizer rolebegin_request_filter.bin- Begin request for Filter role
Stream Records#
params_get.bin- FCGI_PARAMS record with GET request environment variablesparams_post.bin- FCGI_PARAMS record with POST request environment variablesparams_empty.bin- Empty FCGI_PARAMS record (end of params stream)stdin_form_data.bin- FCGI_STDIN record with form datastdin_empty.bin- Empty FCGI_STDIN record (end of stdin stream)stdout_response.bin- FCGI_STDOUT record with HTTP responsestdout_empty.bin- Empty FCGI_STDOUT record (end of stdout stream)stderr_message.bin- FCGI_STDERR record with error messagestderr_empty.bin- Empty FCGI_STDERR record (end of stderr stream)data_filter.bin- FCGI_DATA record with file content (for Filter role)data_empty.bin- Empty FCGI_DATA record (end of data stream)
Control Records#
end_request_success.bin- FCGI_END_REQUEST record with successful completionend_request_error.bin- FCGI_END_REQUEST record with error statusabort_request.bin- FCGI_ABORT_REQUEST record
Complex Scenarios#
multiplexed_requests.bin- Multiple concurrent requests on same connectionlarge_record.bin- Record with maximum content size (65KB)padded_record.bin- Record with padding for 8-byte alignment
Record Format#
All records follow the FastCGI record format:
typedef struct {
unsigned char version; // FCGI_VERSION_1 (1)
unsigned char type; // Record type (1-11)
unsigned char requestIdB1; // Request ID high byte
unsigned char requestIdB0; // Request ID low byte
unsigned char contentLengthB1; // Content length high byte
unsigned char contentLengthB0; // Content length low byte
unsigned char paddingLength; // Padding length
unsigned char reserved; // Reserved (always 0)
// contentData[contentLength]
// paddingData[paddingLength]
} FCGI_Record;
Usage for Parser Testing#
These test cases can be used to verify:
- Header parsing - Correct extraction of version, type, requestId, lengths
- Content parsing - Proper handling of record body data
- Stream handling - Recognition of stream start/end patterns
- Name-value pair parsing - Decoding of FCGI_PARAMS format
- Role-specific parsing - Different record sequences for each role
- Error handling - Response to unknown types, malformed data
- Multiplexing - Handling multiple concurrent request IDs
- Padding - Correct skipping of padding bytes
Typical Protocol Flows#
Simple Responder Request#
begin_request_responder.binparams_get.binparams_empty.binstdin_empty.binstdout_response.binstdout_empty.binend_request_success.bin
POST Request with Form Data#
begin_request_responder.binparams_post.binparams_empty.binstdin_form_data.binstdin_empty.binstdout_response.binstdout_empty.binend_request_success.bin
Authorizer Request#
begin_request_authorizer.binparams_get.binparams_empty.binstdout_response.binstdout_empty.binend_request_success.bin
Filter Request#
begin_request_filter.binparams_get.binparams_empty.binstdin_empty.bindata_filter.bindata_empty.binstdout_response.binstdout_empty.binend_request_success.bin
Binary Format Verification#
You can inspect the binary content using hexdump:
hexdump -C begin_request_responder.bin
The first 8 bytes should always be the FastCGI header, followed by the record content and any padding.