···
+
(** Core FastCGI types and constants.
+
This module defines the fundamental types used throughout the
+
FastCGI protocol implementation.
+
FastCGI is an open extension to CGI that provides high performance for
+
all Internet applications without the penalties of Web server APIs.
+
Unlike traditional CGI programs that are started for each request,
+
FastCGI applications are long-lived processes that can handle multiple
+
requests over persistent connections. *)
+
(** FastCGI protocol version.
+
The current protocol uses version 1. Future versions of the
+
protocol may increment this value. Applications should check the version
+
field in incoming records and reject unsupported versions.
+
Version 1 is represented by the value [1]. *)
+
(** FastCGI record types.
+
All data transmitted over a FastCGI connection is packaged in records.
+
Each record has a type that determines how the record's content should
+
be interpreted. The protocol defines both management records (for
+
protocol-level communication) and application records (for request
+
Management records contain information that is not specific to any web
+
server request, such as capability queries and unknown type responses.
+
Application records contain information about a particular request,
+
identified by a non-zero request ID. *)
+
| Begin_request (** Starts a new request. Sent by the web server to begin
+
processing. Contains the role and connection flags. *)
+
| Abort_request (** Aborts an existing request. Sent by the web server
+
when an HTTP client closes its connection while the
+
request is still being processed. *)
+
| End_request (** Completes a request. Sent by the application to
+
terminate processing, either normally or due to
+
| Params (** Parameter name-value pairs. Used to transmit CGI-style
+
environment variables from the web server to the
+
application. Sent as a stream. *)
+
| Stdin (** Standard input data. Contains the request body data
+
that would normally be available on stdin in CGI.
+
| Stdout (** Standard output data. Response data from the application
+
to the web server. This becomes the HTTP response.
+
| Stderr (** Standard error data. Error messages from the application.
+
Used for logging and debugging. Sent as a stream. *)
+
| Data (** Additional data stream. Used only in the Filter role
+
to transmit file data that needs to be filtered.
+
| Get_values (** Management record to query application variables.
+
Allows the web server to discover application
+
capabilities like max connections and multiplexing. *)
+
| Get_values_result (** Management record response to Get_values. Contains
+
the requested variable values. *)
+
| Unknown_type (** Management record for unknown type handling. Sent by
+
the application when it receives a record type it
+
(** FastCGI application roles.
+
A FastCGI application can play one of several well-defined roles.
+
The role determines what information the application receives and
+
what it's expected to produce.
+
A FastCGI application plays one of several well-defined roles. The most
+
familiar is the Responder role, in which the application receives all
+
the information associated with an HTTP request and generates an HTTP
+
| Responder (** The most common role, equivalent to traditional CGI.
+
The application receives all information associated with
+
an HTTP request and generates an HTTP response. This
+
includes environment variables, request headers, and
+
| Authorizer (** Performs access control decisions. The application
+
receives HTTP request information and generates an
+
authorized/unauthorized decision. In case of authorization,
+
it can associate additional variables with the request.
+
For unauthorized requests, it provides a complete HTTP
+
| Filter (** Processes data streams with filtering. The application
+
receives HTTP request information plus an additional
+
data stream from a file stored on the web server, and
+
generates a "filtered" version of the data as an HTTP
+
response. Both the file and the filter can be access
+
(** Request ID for multiplexing multiple requests over a single connection.
+
FastCGI supports multiplexing, allowing multiple concurrent requests
+
to be processed over a single transport connection. Each request is
+
identified by a unique request ID within the scope of that connection.
+
The Web server re-uses FastCGI request IDs; the application keeps track
+
of the current state of each request ID on a given transport connection.
+
Request IDs should be small integers to allow efficient tracking using
+
arrays rather than hash tables.
+
The value [0] is reserved for management records and is called the
+
(** Application-level status code.
+
When an application completes a request, it provides an application
+
status code similar to the exit status of a traditional CGI program.
+
A value of [0] indicates success, while non-zero values indicate
+
various error conditions.
+
The application sets the appStatus component to the status code that
+
the CGI program would have returned via the exit system call. *)
+
(** Protocol-level status codes.
+
In addition to application status, each request completion includes
+
a protocol-level status that indicates whether the request was
+
processed normally or rejected for protocol-related reasons.
+
These status codes allow the web server to understand why a request
+
was not processed and take appropriate action. *)
+
| Request_complete (** Normal end of request. The application successfully
+
processed the request and the appStatus field
+
indicates the application-level result. *)
+
| Cant_mpx_conn (** Rejecting a new request because the application
+
cannot multiplex connections. This happens when
+
a web server sends concurrent requests over one
+
connection to an application that processes only
+
one request at a time per connection. *)
+
| Overloaded (** Rejecting a new request because the application
+
is overloaded. This occurs when the application
+
runs out of some resource, such as database
+
connections or memory. *)
+
| Unknown_role (** Rejecting a new request because the requested
+
role is unknown to the application. This happens
+
when the web server specifies a role that the
+
application doesn't implement. *)
+
(** Connection flags for controlling connection behavior.
+
These flags are sent in Begin_request records to control how the
+
connection should be managed after the request completes. *)
+
type connection_flags = {
+
keep_conn : bool; (** Keep connection open after request completion.
+
If false, the application closes the connection after
+
responding to this request. If true, the application
+
does not close the connection after responding to this
+
request; the Web server retains responsibility for the
+
This flag enables connection reuse for better performance,
+
especially important for high-traffic applications. *)
+
(** {1 Record Types} *)
+
(** FastCGI record header.
+
Every FastCGI record begins with an 8-byte header that identifies
+
the record type, request ID, and content length. This fixed-length
+
prefix allows efficient parsing and proper demultiplexing of records.
+
A FastCGI record consists of a fixed-length prefix followed by a
+
variable number of content and padding bytes.
+
The header format is platform-independent and uses network byte order
+
for multi-byte integers. *)
+
version : int; (** Protocol version. Must be [1] for this specification.
+
Future versions may increment this value. *)
+
record_type : record_type; (** Type of this record, determining how to interpret
+
request_id : request_id; (** Request ID this record belongs to. Value [0] is
+
reserved for management records. *)
+
content_length : int; (** Number of bytes in the content data. Must be
+
between [0] and [65535]. *)
+
padding_length : int; (** Number of padding bytes following content.
+
Must be between [0] and [255]. Used for alignment. *)
+
(** Begin request record body.
+
This record marks the start of a new request and specifies the role
+
the application should play and connection management flags.
+
The Web server sends a FCGI_BEGIN_REQUEST record to start a request.
+
The record body contains the role and flags that control request
+
type begin_request_body = {
+
role : role; (** The role the web server expects the application
+
to play for this request. *)
+
flags : connection_flags; (** Flags controlling connection behavior after
+
(** End request record body.
+
This record marks the completion of a request and provides both
+
application-level and protocol-level status information.
+
The application sends a FCGI_END_REQUEST record to terminate a request,
+
either because the application has processed the request or because the
+
application has rejected the request. *)
+
type end_request_body = {
+
app_status : app_status; (** Application-level status code, similar to
+
a CGI program's exit status. *)
+
protocol_status : protocol_status; (** Protocol-level status indicating normal
+
completion or rejection reason. *)
+
(** Complete FastCGI record.
+
A complete record consists of the header, content data, and optional
+
padding. The content interpretation depends on the record type.
+
Records support padding to allow senders to keep data aligned for more
+
efficient processing. Experience with the X window system protocols shows
+
the performance benefit of such alignment. *)
+
header : record_header; (** Fixed 8-byte header with record metadata. *)
+
content : bytes; (** Variable-length content data. Length must match
+
header.content_length. *)
+
padding : bytes option; (** Optional padding data for alignment. Length must
+
match header.padding_length if present. *)
+
(** Name-value pair for parameters.
+
FastCGI uses a compact binary encoding for transmitting name-value pairs
+
such as CGI environment variables. This encoding supports both short
+
and long names/values efficiently.
+
FastCGI transmits a name-value pair as the length of the name, followed
+
by the length of the value, followed by the name, followed by the value.
+
Lengths of 127 bytes and less can be encoded in one byte, while longer
+
lengths are always encoded in four bytes. *)
+
type name_value_pair = {
+
name : string; (** Parameter name. For CGI compatibility, these are typically
+
uppercase environment variable names like "REQUEST_METHOD". *)
+
value : string; (** Parameter value. The value does not include a terminating
+
null byte in the FastCGI encoding. *)
+
(** {1 Request/Response Model} *)
+
(** Request context containing all information for a FastCGI request.
+
This high-level type aggregates all the information needed to process
+
a FastCGI request. It combines the protocol-level details (request ID,
+
role, flags) with the application data (parameters and input streams).
+
The request follows a two-level processing model: First, the protocol
+
multiplexes a single transport connection between several independent
+
FastCGI requests. Second, within each request the protocol provides
+
several independent data streams in each direction. *)
+
request_id : request_id; (** Unique identifier for this request within
+
the connection scope. Used for multiplexing. *)
+
role : role; (** The role this application should play for
+
this request (Responder, Authorizer, or Filter). *)
+
flags : connection_flags; (** Connection management flags from the web server. *)
+
params : (string * string) list; (** CGI-style environment variables transmitted
+
via FCGI_PARAMS records. These provide request
+
context like HTTP headers, server info, etc. *)
+
stdin : 'a Eio.Flow.source; (** Standard input stream, containing request body
+
data (equivalent to CGI stdin). For HTTP POST
+
requests, this contains the form data or payload. *)
+
data : 'a Eio.Flow.source option; (** Additional data stream, used only in Filter
+
role. Contains file data that needs to be
+
filtered. [None] for Responder and Authorizer. *)
+
(** Response builder for constructing FastCGI responses.
+
This type provides the output streams for sending response data back
+
to the web server. Following CGI conventions, it separates normal
+
output from error output.
+
Both stdout and stderr data pass over a single transport connection from
+
the application to the Web server, rather than requiring separate pipes
+
stdout : 'a Eio.Flow.sink; (** Standard output stream for response data.
+
In Responder role, this contains the HTTP
+
response including headers and body. *)
+
stderr : 'a Eio.Flow.sink; (** Standard error stream for logging and debugging.
+
All role protocols use the FCGI_STDERR stream
+
just the way stderr is used in conventional
+
applications programming: to report application-level
+
errors in an intelligible way. *)
+
(** Complete response with status.
+
When an application finishes processing a request, it must provide
+
both application-level and protocol-level status information. This
+
allows the web server to understand the outcome and take appropriate
+
This corresponds to the FCGI_END_REQUEST record sent by the application. *)
+
type response_result = {
+
app_status : app_status; (** Application exit status, equivalent to what
+
a CGI program would return via exit(). *)
+
protocol_status : protocol_status; (** Protocol-level completion status, indicating
+
normal completion or various rejection reasons. *)
+
(** {1 Protocol Constants} *)
+
(** Protocol version constant.
+
This constant represents FCGI_VERSION_1. This value should be used in
+
the version field of all record headers. *)
+
(** Standard file descriptor for FastCGI listening socket.
+
The Web server leaves a single file descriptor, FCGI_LISTENSOCK_FILENO,
+
open when the application begins execution. This descriptor refers to a
+
listening socket created by the Web server.
+
The value equals STDIN_FILENO (0). Applications can distinguish between
+
CGI and FastCGI invocation by calling getpeername() on this descriptor. *)
+
val listensock_fileno : int
+
(** {2 Record Type Constants}
+
These integer constants correspond to the record_type variants and are
+
used in the binary protocol encoding. These are the values transmitted
+
in the type field of record headers. *)
+
(** Value [1]. Starts a new request. *)
+
val fcgi_begin_request : int
+
(** Value [2]. Aborts an existing request. *)
+
val fcgi_abort_request : int
+
(** Value [3]. Completes a request. *)
+
val fcgi_end_request : int
+
(** Value [4]. Parameter name-value pairs. *)
+
(** Value [5]. Standard input data. *)
+
(** Value [6]. Standard output data. *)
+
(** Value [7]. Standard error data. *)
+
(** Value [8]. Additional data stream (Filter). *)
+
(** Value [9]. Query application variables. *)
+
val fcgi_get_values : int
+
(** Value [10]. Response to Get_values. *)
+
val fcgi_get_values_result : int
+
(** Value [11]. Unknown record type response. *)
+
val fcgi_unknown_type : int
+
These integer constants correspond to the role variants and are used
+
in Begin_request record bodies. These identify the role the web server
+
expects the application to play. *)
+
(** Value [1]. Handle HTTP requests and generate responses. *)
+
val fcgi_responder : int
+
(** Value [2]. Perform authorization decisions. *)
+
val fcgi_authorizer : int
+
(** Value [3]. Process data streams with filtering. *)
+
These constants are used in the flags field of Begin_request records
+
to control connection behavior. *)
+
(** Value [1]. Keep connection open after request.
+
If zero, the application closes the connection after
+
responding to this request. If not zero, the application
+
does not close the connection after responding to this
+
val fcgi_keep_conn : int
+
(** {2 Protocol Limits}
+
These constants define the maximum sizes for various protocol elements,
+
ensuring compatibility and preventing buffer overflows. *)
+
(** Value [65535]. Maximum bytes in record content.
+
Between 0 and 65535 bytes of data, interpreted
+
according to the record type. *)
+
val max_content_length : int
+
(** Value [255]. Maximum bytes in record padding.
+
Between 0 and 255 bytes of data, which are ignored. *)
+
val max_padding_length : int
+
(** Value [8]. Fixed size of record headers.
+
Number of bytes in a FCGI_Header. Future versions
+
of the protocol will not reduce this number. *)
+
val header_length : int
+
(** {2 Management Record Variables}
+
These string constants identify the standard management variables that
+
can be queried using FCGI_GET_VALUES records. They allow the web server
+
to discover application capabilities.
+
The initial set provides information to help the server perform application
+
and connection management. *)
+
(** Variable name "FCGI_MAX_CONNS". The maximum number
+
of concurrent transport connections this application
+
will accept, e.g. "1" or "10". *)
+
val fcgi_max_conns : string
+
(** Variable name "FCGI_MAX_REQS". The maximum number
+
of concurrent requests this application will accept,
+
val fcgi_max_reqs : string
+
(** Variable name "FCGI_MPXS_CONNS". "0" if this
+
application does not multiplex connections (i.e.
+
handle concurrent requests over each connection),
+
val fcgi_mpxs_conns : string